2

My layout has a GridView. Similar to Google’s API demo, each grid has an image. Also, I customized a “Drawable image” which used to highlight the currently selected item. When touch the grid’s image, the “Drawable image” can be show. Unfortunately, it will disappear when I not touch the grid.

I hope the GridView will keep to highlight the selected item. Even the user is scrolling the screen.

From here, I found some similar post.

1) Keep image in GridView selected

2) Android gridview keep item selected

But I can’t understand their method and they are not using customized image. Can anyone give me some help? Please.

Following is my code:

    gridAdapter  adapter =  new   gridAdapter  (this, images);
    gv = (GridView) findViewById (R.id.gridView1);
    gv.setAdapter(adapter);
    gv.setSelector(R.drawable.circle);
    gv.setDrawSelectorOnTop(true);

Following is my updated code:

public class GridViewBasic extends Activity {
    Integer[] imageIDs = {
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher,
            R.drawable.ic_launcher    };
    GridView gridView;
    public int lastPos;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
            gridView = (GridView) findViewById(R.id.gridView1);
            gridView.setAdapter(new ImageAdapter(this));
            gridView.setSelected(true);
            gridView.setSelector(R.drawable.circle);
            gridView.setDrawSelectorOnTop(true);
            gridView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

            gridView.setOnItemClickListener(new OnItemClickListener() {
                public void onItemClick(AdapterView<?> parent,  View v, int position, long id) {   
                    lastPos = position;
                    gridView.setSelection((int)(gridView.getAdapter()).getItemId(lastPos));
                    System.out.println ("getItemId ="+(gridView.getAdapter()).getItemId(lastPos));

                }
            });        
        }

        public class ImageAdapter extends BaseAdapter 
        {
            private Context context;

            public ImageAdapter(Context c)  {
                context = c;
            }

            //---returns the number of images---
            public int getCount() {
                return imageIDs.length;
            }

            //---returns the ID of an item--- 
            public Object getItem(int position) {
                return position;
            }

            public long getItemId(int position) {
                return position;
            }

            //---returns an ImageView view---
            public View getView(int position, View convertView, ViewGroup parent) {
                ImageView imageView;

                if (convertView == null) {
                    imageView = new ImageView(context);
                    imageView.setLayoutParams(new GridView.LayoutParams(185, 185));
                    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                    imageView.setPadding(5, 5, 5, 5);
                } else {
                    imageView = (ImageView) convertView;
                }
                imageView.setImageResource(imageIDs[position]);

                return imageView;
            }
        }    


}
Community
  • 1
  • 1
John
  • 323
  • 2
  • 4
  • 13
  • post some code... you have to call setSelection(view, true) for it to stay highlighted :) – Shark Oct 16 '12 at 12:28
  • @Shark Could you tell me where is the setSelection(view, true)? Because at the GridView, I found a similar method but the paramster is not the same. – John Oct 16 '12 at 12:47
  • gridView.setSelection(gridView.getPositionForView(viewThatShouldBeSelected)); had to edit a few times since i just looked up the proper signature. – Shark Oct 16 '12 at 12:50
  • @Shark: I had try it, but I don't know why it will disappear too. At the "onItemClick", I had to saved the last position. So, I added gv.setSelection(lastPos); and gv.setSelected(true); is it correct? thanks. – John Oct 16 '12 at 13:10
  • Why are you calling adapter.getItemId() ? – Shark Oct 18 '12 at 10:21
  • @Shark you means incorrect? Because that is the most similar to your recommand (gridView.getAdapter()).getPosition(viewThatYouWant) or (gridView.getAdapter()).getItemAt(lastPos).requestFocus(). Otherwise I can't found any method same above opinions. – John Oct 18 '12 at 11:39
  • What was wrong with gridView.setSelection(gridView.getPositionForView(clickedView)) ? – Shark Oct 18 '12 at 13:00
  • After testing , the Hightlight haven't keeping too. I found that the "gridView.getPositionForView(v)" is same with my lastPos value. ("v" is coming from onItemClick) – John Oct 18 '12 at 13:32

4 Answers4

2

Ok now it needs a whole new answer...

here's the thing: setSelected() will set the calling view as selected, thus subsequently giving focus....

calling

 GridView gv; gv.setSelected(true);

will select the GridView gv, not the View in gridview's adapter which you want.

So you need to call gv.setSelection(pos) to select a specific child.

the pos you are saving might not be the real position but rather the position from 'visible' offset. that's why you have to call

(gridView.getAdapter()).getPosition(viewThatYouWant);

or

(gridView.getAdapter()).getItemAt(lastPos).requestFocus();

Do note that you should look into HOW A VIEW HANDLES IT'S FOCUS VS CHILD FOCUS the method is called

setDescendantFocusability

so naturally you would want

GridView gv; gv.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
sandrstar
  • 12,503
  • 8
  • 58
  • 65
Shark
  • 6,513
  • 3
  • 28
  • 50
  • Thank you for your teaching. Unfortunately, I am not success too. I feel so blue! – John Oct 16 '12 at 14:14
  • So whats the problem? what errors are you getting? What is your expected behaviour and what behaviour are you getting? Did you put logs in your onItemSelected() callback to print the currently selected item? Find out whats wrong and update your question if you want a better answer :) or you know, help us help you find out whats wrong. – Shark Oct 16 '12 at 14:17
  • Becasue it haven't throw any error so I don't know how to do. Also, I don't know the code placed correctly or not. 1) "gv.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);" placed behind the gv.setAdapter(adapter) 2) In " onItemClick(AdapterView> parent, View v, int position, long id)", I saved the position and View. 3) About the "gridView.getAdapter()", I placed in Adapter's getView. But it has error red line under the code. So I edited to " if (tempView == convertView) gv.setSelection(gv.getAdapter().getItemViewType(position));" . But it can't keep the highlight too. – John Oct 16 '12 at 14:46
  • I also placed the " if (tempView == convertView) gv.setSelection(gv.getAdapter().getItemViewType(position));" in " onItemClick(AdapterView> parent, View v, int position, long id)" , the highlight can't keep in too. – John Oct 16 '12 at 23:33
  • you shouldn't getItemViewType... GridView will autobox your adapter, use the variable reference to it and try that way if you cannot call the proper method this way. remember, you need to pass a position to the setSelection() call. – Shark Oct 17 '12 at 09:50
  • Could you tell me where is the setSelection() placed location? onItemClick or Adapter's getView? Thanks! – John Oct 17 '12 at 11:47
  • onItemClick. You want the item to be selected when clicked on, not when it's added to the gridview. – Shark Oct 17 '12 at 13:20
  • I simpified my code and updated on above. At this code, it can't keep the highlight too. Is it possible to customized the Adapter or other things for this purpose? Could you mind to share your idea? Thanks. – John Oct 18 '12 at 01:26
  • Setting `GridView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS)` was most useful for me. – n.collins Feb 19 '14 at 09:49
0
public class StaffSelectionAdapter extends BaseAdapter {

private Context context;

private final String[] staffMemberList;
private int previousPosition = -1;
private static boolean isFirstTime;
boolean[] isChecked;
private TextView textView = null;
public long staffId;
private LayoutInflater inflater;


public StaffSelectionAdapter(Context context, String[] staffMemberList) {
    this.context = context;
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.staffMemberList = staffMemberList;

    isFirstTime = true;
    isChecked = new boolean[staffMemberList.length];
    for (int i = 0; i < staffMemberList.length; i++) {
        isChecked[i] = false;
    }
}

public View getView(final int position, View convertView, ViewGroup parent) {

    if (convertView == null) {
        convertView = inflater.inflate(R.layout.row_for_staff_selection, null);
    }
    textView = (TextView) convertView.findViewById(R.id.row_for_staff_selection_grid_item_label);
    textView.setText(staffMemberList[position]);

    if (isChecked[position]) {
        SpannableString content = new SpannableString(staffMemberList[position]);
        content.setSpan(new UnderlineSpan(), 0, staffMemberList[position].length(), 0);
        textView.setText(content);
    } else {
        textView.setBackgroundColor(context.getResources().getColor(R.drawable.dialog_bg));
    }

    convertView.setTag(position);
    convertView.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            if (!isChecked[position]) {
                staffId = 

                isChecked[position] = true;
                if (!isFirstTime) {
                    isChecked[previousPosition] = false;
                } else {
                    isFirstTime = false;
                }
                textView.setBackgroundColor(context.getResources().getColor(R.drawable.dialog_bg));
            }
            previousPosition = (Integer) v.getTag();
            notifyDataSetChanged();
        }
    });
    return convertView;
}

public int getCount() 
    {
    return staffMemberList.length;
}

public Object getItem(int position) 
    {
    return staffMemberList[position];
}

public long getItemId(int position) {
    return 0;
}

public long getStaffId() {
    return staffId;
}

public void setStaffId(long staffId) {
    this.staffId = staffId;
}

}
Shark
  • 6,513
  • 3
  • 28
  • 50
Ketan Mehta
  • 272
  • 1
  • 12
0

Set onItemClickListener on gridview .You can then get position of view onItemClick . pass the selected postion to adapter and within adapter inside getView method check if(position == selected_position) . if true set background of your choice .

public ColorGridAdapter(Context context,ArrayList<String> colorArray,int position) {
                super(context, resource,colorArray);            
                this.context = context;
                this.colors = colorArray;
                this.selected_position = position;  // position of your selected item

            }

    public View getView(final int position, View convertView, ViewGroup parent){
                View v = convertView;
                if (v == null) {

    LayoutInflater inflater = (LayoutInflater)  getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        v = inflater.inflate(R.layout.color_pelatte, null);
                        ColorView = (View)v.findViewById(R.id.color_view);          
                    }

                ColorView.setBackgroundColor(Color.parseColor(colors.get(position)));
                if(position == selected_position){
                    v.setBackground(context.getResources().getDrawable(R.drawable.edittext_background));
                }
Abhilasha
  • 11
  • 3
0

This is how I achieved this

 <GridView
    android:id="@+id/gv_calender"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:numColumns="7"
    android:listSelector="@color/colorAccent"
    android:stretchMode="columnWidth"></GridView>

and in Adapter add one line extra

  GridView gvCalender = (GridView)findViewById(R.id.gv_calender);
  CalendarAdapter adapter = new CalendarAdapter(getActivity(), lsCalender);
    gvCalender.setDrawSelectorOnTop(false);
    gvCalender.setAdapter(adapter);

That's It you are done
Key lines are

android:listSelector="@color/colorAccent"
AND
gvCalender.setDrawSelectorOnTop(false);

Lokesh Tiwari
  • 10,496
  • 3
  • 36
  • 45