I am using gallery as below
<Gallery android:nextFocusUp="#+id/zoom_out"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/icon_gallery_plate" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:spacing="10dip"
android:background="#drawable/browse_slider_bar"
android:unselectedAlpha="0.5" android:layout_alignBottom="#+id/layoutZoom"
/>
Problem is as i defined nextFocusup zoom out when i press up key while on the gallery it don't focus to zoom out.
found solution add nextfocusup id in adatper's getview method.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
/* calculationg position */
ImageView i = new ImageView(mContext);
i.setScaleType(ImageView.ScaleType.FIT_CENTER);
BrowseMapCategoryRow catRow = getItem(position);
/* Replacing with selected image */
i.setImageResource(catRow.getImageSource());
i.setNextFocusUpId(R.id.zoom_out); // setting manullay
return i;
}
In "nextFocusUp" you should put an id that already exists, the + adds a new id: so when you create the widget that will gain the focus, you should eliminate the +, so the id would be android:id="#id/zoom_out"
Related
Right now I'm working on a launcher app, in which I've made a GridView which fetches all installed apps from the device. But there are only app icons and no app names. And I wanted to put app name below it so I tried to put TextView below my app icon ImageView, but my app crashes. Any ideas how should I fix it? Here's my code: Thank you very much!
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i;
if (convertView == null) {
i = new ImageView(Apps.this);
i.setScaleType(ImageView.ScaleType.FIT_CENTER);
i.setLayoutParams(new GridView.LayoutParams(93, 93));
i.setPadding(15, 15, 15, 15);
} else {
i = (ImageView) convertView;
}
ResolveInfo info = mApps.get(position);
i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
return i;
}
Instead of building a view that contain TextView and ImageView, use CompoundDrawable. You only have to implement one TextView and set it's DrawableTop with the required icon. This will do the job.
From the XML file
<TextView
android:id="#+id/my_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableTop="#drawable/my_icon"
android:gravity="center"
/>
Or you can do it programmatically using the following:
myTextView.setCompoundDrawablesWithIntrinsicBounds(null, topDrawable, null, null);
Simply use a TextView as the image container, by using a compound drawable: http://developer.android.com/reference/android/widget/TextView.html#setCompoundDrawablesWithIntrinsicBounds(int,%20int,%20int,%20int)
So, you'll set 1 View to replace 2 ones, with UI simplification and performance improvements, as side-effects.
A little example:
public View getView(int position, View convertView, ViewGroup parent) {
TextView t;
if (convertView == null) {
t = new TextView(Apps.this);
t.setLayoutParams(new GridView.LayoutParams(93, 93));
t.setPadding(15, 15, 15, 15);
ResolveInfo info = mApps.get(position);
Drawable drw = info.activityInfo.loadIcon(getPackageManager());
t.setCompoundDrawablesWithIntrinsicBounds(null, drw, null, null);
//t.setText("Some Text");
t.setText(info.activityInfo.loadLabel(getPackageManager()).toString());
} else {
t = (TextView) convertView;
}
return t;
}
[EDIT]
Once you return the View (t, the TextView), you can get the drawable by using getCompoundDrawables(): http://developer.android.com/reference/android/widget/TextView.html#getCompoundDrawables()
I have a GridView that is populated by all apps installed on the device. The user can select certain apps here. I want the selected apps to be opaque and non-selected to be partially transparent. I did this with the following:
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout linearLayout = new LinearLayout(mContext);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setGravity(Gravity.CENTER_HORIZONTAL);
LinearLayout.LayoutParams layoutParamsText = new LinearLayout.LayoutParams(150, 90);
ImageView imageView = new ImageView(mContext);
TextView appLabel = new TextView(mContext);
final OurAppInfo info = (OurAppInfo) getItem(position);
if(!installedApplications.contains(info)){
AlphaAnimation alpha = new AlphaAnimation(0.4F, 0.4F);
alpha.setDuration(0);
alpha.setFillAfter(true);
linearLayout.startAnimation(alpha);
}
String appName = info.label;
if (appName.length() > 25) {
appName = appName.substring(0, 25);
appName = appName + "...";
}
appLabel.setText(appName);
appLabel.setTextColor(Color.BLACK);
appLabel.setGravity(Gravity.CENTER_HORIZONTAL);
appLabel.setTypeface(null, Typeface.BOLD);
imageView.setImageDrawable(info.drawableAppIcon);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(110, 110));
appLabel.setTextSize(15);
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (installedApplications.contains(info)){
installedApplications.remove(info);
receiveUpdate(installedApplications, false, false);
} else {
installedApplications.add(info);
Collections.sort(installedApplications);
receiveUpdate(installedApplications, false, false);
}
}
});
appLabel.setLayoutParams(layoutParamsText);
linearLayout.addView(imageView);
linearLayout.addView(appLabel);
return linearLayout;
}
This is part of the GridAdapter extends BaseAdapter. The code works as expected, when I tap on an app it is either removed from or added to the list and according to transparency is set. However, whenever I tap on an element in the GridView, the view is reset and I am brought to the top of the scrollable GridView. Obviously, this isn't a problem for a small number of apps, but if you're selecting apps near the XYZ letters, every time you select one you are brought back to ABC. How can I prevent this from happening?
It looks like you're refreshing the adapter whenever you make changes that makes the grid go back to initial position. You could try saving and restoring the position before making any changes to the adapter.
//Before refreshing the adapter you get both X and Y position
int xPos = grid.getScrollX();
int yPos = grid.getScrollY();
Then you update your adapter.
After the adapter is recreated you restore the grid position:
grid.scrollTo(xPos, yPos);
You could also use (everytime possible) the method notifyDataSetChanged() instead of creating a new adapter.
Hope it helps.
Check all child views for automatic height or width.
I guess gridview calculates size of this views whenever you change data.
This was solution in my case.
In my case changed this:
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
To this:
<ImageView
android:id="#+id/image"
android:layout_width="100dp"
android:layout_height="100dp" />
I have created horizontal gallery view using this Tutorial
But when gallery is created it starts from half of the screen, below screen shot
I want that when gallery view starts it should start from left of screen not center.
Thanks
Better way to escape, mark the focus from second item.
Try to use in xml--
android:gravity="left"
in your getView function you can set the image that should be centered. So you can set the last image as below
imageView.setImageResource(mImageIds[position]);
Something I did
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView.setImageResource(mImageIds[position]);
imageView.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setBackgroundResource(mGalleryItemBackground);
return imageView;
}
i followed the ApiDemo to create a gallery.
but i don't need the background of each item , so i marked these code:
public ImageAdapter(Context c) {
mContext = c;
// See res/values/attrs.xml for the <declare-styleable> that defines
// Gallery1.
**// TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
// mGalleryItemBackground = a.getResourceId(
// R.styleable.Gallery1_android_galleryItemBackground, 0);
// a.recycle();**
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(48, 48));
// The preferred Gallery item background
**// i.setBackgroundResource(mGalleryItemBackground);**
return i;
}
then , i met a problem :
the default first selected item( also the first item) is bright ,
but after a start to drag , and the selected item be changed , all items looked dark.....
i don't know how to set the alpha back , let the item looks bright.......could someone help me?
Try set the cacheColorHint of your ListView. IE with
<listView android:cacheColorHint="#android:color/transparent" ...
EDIT:
Do not comment out these lines, but set the android:background in the Gallery1_android_galleryItemBackground Style to #android:color/transparent or another color you want.
When I use the Gallery widget, how do I get the images to say scale up & glow on being selected and scaled down & un-glow on being unselected?
All tutorials I've seen have this effect but I'm not able to see it...
Is there some kind of an animation that I have to attach to the Gallery?
Hope this is helpful. I manage to "simulate" the shrink/grow solution with the Gallery widget. Since they removed the getScale(), things get a little bit complicated. I think that this it's not the best solution at all, but at least I can live with it.
What I have found is that Gallery manages the focus EXTREMELY BAD. So, the first approach was to add a focus change listener on the ImageView displayed, but no luck there. Focus is a MESS there... in terms that, the selected image it's not the currently focused view. I have sent a mail to android-developers mailing list about some error on API doc (regarding the focusSearch()method and some focus contants).
Here's my solution to this problem:
Build an animation resource to 'grow' the image:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1.0"
android:toXScale="1.10"
android:fromYScale="1.0"
android:toYScale="1.10"
android:duration="300"
android:pivotX="50%"
android:pivotY="50%"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fillAfter="false"/>
If you don't get what that means then you should proceed to read this
That will be our 'grow' effect, and you will need to save it in: res/anim/grow.xml or whatever name it suites you (but always in res/anim dir).
You can follow the resource guide from here to create a Gallery view. The ImageAdapter builds an ImageView every time that the Gallery object calls getView(). One workaround you could implement is adding a line to the getView() method that identifies a View with a position, this way:
...
i.setId(position);
...
With that line added to the getView() method of the ImageAdpater object, you can then unequivocally identify that view within a listener, for instance:
g.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected (AdapterView<?> parent, View v, int position, long id) {
Animation grow = AnimationUtils.loadAnimation(YourActivity.this, R.anim.grow);
View sideView = parent.findViewById(position - 1);
if (sideView != null)
((ImageView)sideView).setLayoutParams(new Gallery.LayoutParams(150, 100));
sideView = parent.findViewById(position + 1);
if (sideView != null)
((ImageView)sideView).setLayoutParams(new Gallery.LayoutParams(150, 100));
v.startAnimation(grow);
v.setLayoutParams(new Gallery.LayoutParams(170, 150));
}
public void onNothingSelected (AdapterView<?> parent) {
System.out.println("NOTHING SELECTED");
}
});
NOTE: You may notice that all the values from animation and from layout parameters has been choosen by me at hand. This is because i'm not going to clean code for you. And, this is just a workaround the BAD focus issue with this widget or the android view system. If focus were OK, then, all you need to do is set a focus change listener that makes the gros/shrink when it got focus/unfocused.
I hope this may help you to find a way around for your problem,
Regards,
New EDIT: This is the listener I have set, I also added the line i.clearAnimation() in the getView() method:
private class SelectListener implements AdapterView.OnItemSelectedListener {
private Animation grow;
private int last;
public SelectListener() {
grow = AnimationUtils.loadAnimation(RouteGallery.this, R.anim.grow);
last = 0;
}
public void onItemSelected (AdapterView<?> parent, View v, int position, long id) {
View sideView = parent.findViewById(last);
if (sideView != null && last != position)
sideView.clearAnimation();
v.startAnimation(grow);
last = position;
}
public void onNothingSelected (AdapterView<?> parent) {
}
}
You need to use an ImageSwitcher. The ImageSwitcher has methods for setting the in and out animations (when image is selected and deselected, or selected and replaced).
The following link has a good tutorial on how to use it in conjunction with the Gallery.
I implemented a similar animation like this:
final Animation shrink = AnimationUtils.loadAnimation(activity, R.anim.shrink);
shrink.setFillAfter(true);
gallery.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// This iterates through the views which are currently displayed on screen.
for (int k=0; k<gallery.getChildCount(); k++){
// Do whatever else you want, here.
// This is how you get a particular element of a view
ImageView background = (ImageView) gallery.getChildAt(k).findViewById(R.id.menu_item_background);
//clear animation
gallery.getChildAt(k).clearAnimation();
}
// Scale the selected one
view.startAnimation(shrink);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {}
});