Android gridview keep item selected

后端 未结 6 1424
失恋的感觉
失恋的感觉 2020-11-29 06:18

I have a GridView with multiple items, but the items must be kept selected once the the onClickListener is called.How can i achive this?

I\'v already tried v.s

相关标签:
6条回答
  • 2020-11-29 06:38
    **You can add tag and check for tag**
    
    
     gv.setOnItemClickListener((adapterView, view, i, l) -> {
    
                    int f = gv.getCheckedItemPosition();
    
                    if(view.getTag()=="selected")
                    {
                        view.setTag("notselected");
                        String clickedText = gv.getItemAtPosition(i).toString();
                        filterKeywords.remove(clickedText);
                        view.setBackgroundColor(Color.WHITE);
                    }
                    else
                    {
                        view.setTag("selected");
                        String clickedText = gv.getItemAtPosition(i).toString();
                        filterKeywords.add(clickedText);
                        view.setBackgroundColor(Color.GREEN);
    
                    }
    
                    System.out.println("KEYWORDS"+filterKeywords);
    
    
                });
    
    0 讨论(0)
  • 2020-11-29 06:41

    the views in the gridview must be CheckBoxs, in this way you can check and uncheck them .

    0 讨论(0)
  • 2020-11-29 06:42

    The concept that you want to achieve is possible, but not like the way you are working now.

    The best and easiest solution would be to keep track of the states of the clicked items and give them the correct layout inside the adapter. I have set up a little example:

    Activity

    public class StackOverFlowActivity extends Activity {
        GridView gridView;
        MyCustomAdapter myAdapter;
        ArrayList<GridObject> myObjects;
    
        static final String[] numbers = new String[] { "A", "B", "C", "D", "E",
                "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
                "S", "T", "U", "V", "W", "X", "Y", "Z" };
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            myObjects = new ArrayList<GridObject>();
            for (String s : numbers) {
                myObjects.add(new GridObject(s, 0));
            }
    
            gridView = (GridView) findViewById(R.id.gridView1);
    
            myAdapter = new MyCustomAdapter(this);
    
            gridView.setAdapter(myAdapter);
            gridView.setOnItemClickListener(new OnItemClickListener() {
    
                @Override
                public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
                    myObjects.get(position).setState(1);
                    myAdapter.notifyDataSetChanged();
                }
            });
        }
    
        static class ViewHolder {
            TextView text;
        }
    
        private class MyCustomAdapter extends BaseAdapter  {
    
            private LayoutInflater mInflater;
    
            public MyCustomAdapter(Context context) {
                mInflater = LayoutInflater.from(context);
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                GridObject object = myObjects.get(position);
                ViewHolder holder;
    
                if (convertView == null) {
                    convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
                    holder = new ViewHolder();
                    holder.text = (TextView) convertView.findViewById(R.id.text);
                    convertView.setTag(holder);
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }
    
                holder.text.setText(object.getName());
    
                if (object.getState() == 1) {
                    holder.text.setBackgroundColor(Color.GREEN);
                } else {
                    holder.text.setBackgroundColor(Color.BLUE);
                }
                return convertView;
            }
    
            @Override
            public int getCount() {
                return myObjects.size();
            }
    
            @Override
            public Object getItem(int position) {
                return position;
            }
    
            @Override
            public long getItemId(int position) {
                return position;
            }
        }
    }
    

    GridObject

    public class GridObject {
    
        private String name;
        private int state;
    
        public GridObject(String name, int state) {
            super();
            this.name = name;
            this.state = state;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getState() {
            return state;
        }
    
        public void setState(int state) {
            this.state = state;
        }   
    }
    

    Main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <GridView
            android:id="@+id/gridView1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:columnWidth="50dp"
            android:gravity="center"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth" >
        </GridView>
    
    </LinearLayout>
    

    list_item_icon_text

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <TextView
            android:id="@+id/text"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    
    </LinearLayout>
    
    0 讨论(0)
  • 2020-11-29 06:52

    I think a better approach is to tell the GridView that you wish to support selecting (checking) the items:

    gridView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE);
    

    and then make sure that items in GridView implement Checkable interface. That means that the items can be either Checkbox, ToggleButton and so on or you can add the Checkable support yourself - for example make RelativeLayout checkable. (See the example below.)

    In contrast to the other answer most of the work is taken care of by the GridView itself - no onClickListener is needed. Instead of storing the state yourself, just call gridView.getCheckedItemIds() or similar method.


    To make RelativeLayout (or anything) checkable make a subclass of it:

    public class CheckableRelativeLayout extends RelativeLayout implements Checkable {
        private boolean checked = false;
        private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
    
        public CheckableRelativeLayout(Context context) {
            super(context);
        }
    
        public CheckableRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CheckableRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected int[] onCreateDrawableState(int extraSpace) {
             final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
             if (isChecked())
                 mergeDrawableStates(drawableState, CHECKED_STATE_SET);
             return drawableState;
        }
    
        @Override
        public boolean isChecked() {
            return checked;
        }
    
        @Override
        public void setChecked(boolean _checked) {
            checked = _checked;
            refreshDrawableState();
        }
    
        @Override
        public void toggle() {
            setChecked(!checked);
        }
    
    }
    

    Notice that the method onCreateDrawableState updates the visual style. You don't have to do it this way, you can for example directly change the background in the setChange method.

    Then use the CheckableRelativeLayout as the top view for items in the GridView:

    <foo.bar.CheckableRelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:background="@drawable/my_awesome_background"
        ... more stuff
        >
            ...  content of the relative layout
    </com.test.CheckableRelativeLayout>
    

    And define how the background changes when the item is checked in res/drawable/my_awesome_background.xml:

    <selector xmlns:android="http://schemas.android.com/apk/res/android" > 
         <item android:state_checked="true" >
            <!-- This applies when the item is checked. -->
             <shape android:shape="rectangle"  >
                 <solid android:color="#A8DFF4" />
             </shape>
         </item>
    
        <item>
            <!-- This applies when the item is not checked. -->
            <shape android:shape="rectangle"  >
                 <solid android:color="#EFEFEF" />
             </shape>
         </item>
    </selector>
    
    0 讨论(0)
  • 2020-11-29 06:52

    I know the answer is a little bit old. But i think it's the easiest one of all. In your Adapter Class, add a variable containing the selected Item Position. Set transperency to all Images excluding the selected one in GetView method. In your click handler in main method, safe the selected ItemPosition. Notify the adapter that he has changed.

    In your Adapter Class, add a variable containing the selected Item Position.

    public class GridImageAdapter extends BaseAdapter {
           public int selectedImage = 0;
    

    Set transperency to all Images excluding the selected one in Adapter GetView method.

    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        int[] images = { R.drawable.walk, R.drawable.run, R.drawable.jump }
    
        ImageView imageView = new ImageView(mContext);
        if (position < imgMapper.length) {
    
            imageView.setImageResource(images[position]);
    
            if (position != selectedImage) {
                imageView.setImageAlpha(50);
            }
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
        };
    
        return imageView;
    }
    

    In your click handler in main method, safe the selected ItemPosition. Notify the adapter that he has changed

       myGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                GridImageAdapter myAdapter = (GridImageAdapter) myGridView.getAdapter();
                myAdapter.selectedImage = position;
                myAdapter.notifyDataSetChanged();
            }
        });
    
    0 讨论(0)
  • 2020-11-29 06:55

    Here's a terser version of Strix's answer (which I think is better than the accepted answer) when you don't need to reuse that code elsewhere. Instead of creating a new class and implementing Checked, you can just create an anonymous class inside your Adapter.getView method, overriding onCreateDrawableState as in Strix's answer, but replace isChecked() there with ((AbsListView)parent).isItemChecked(position). Here's the full code from my adapter that draws a border around checked thumbnails in a gallery:

    public class ImageAdapter extends BaseAdapter {
        private final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
        public int getCount() {return images.size();}
        public Object getItem(int position) {return images.get(position);}
        public long getItemId(int position) {return position;}
    
        public View getView(final int position, final View convertView, final ViewGroup parent) {
            final ImageView imageView = new ImageView(getApplicationContext()) {
                @Override public int[] onCreateDrawableState(int extraSpace) {
                    final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
                    if (((AbsListView)parent).isItemChecked(position)) {
                        mergeDrawableStates(drawableState, CHECKED_STATE_SET);
                    }
                    return drawableState;
                }
            };
            imageView.setBackground(getResources().getDrawable(R.drawable.my_awesome_background));
            imageView.setScaleType(ImageView.ScaleType.CENTER);
            final byte[] buffer = images.get(position);
            final Bitmap bmp = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
            imageView.setImageBitmap(bmp);
            return imageView;
        }
    }
    
    0 讨论(0)
提交回复
热议问题