Android gridview 保持项目被选中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11326089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:58:59  来源:igfitidea点击:

Android gridview keep item selected

androidgridviewview

提问by Dorin Rusu

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?

我有一个包含多个项目的 GridView,但是一旦 onClickListener 被调用,这些项目必须保持选中状态。我怎样才能做到这一点?

I'v already tried v.setSelected(true)but it doesnt seem to work.

我已经尝试过了,v.setSelected(true)但似乎不起作用。

gridview.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                int position, long id) {
            // Toast.makeText(Project.this, "Red" + position,
            // Toast.LENGTH_SHORT).show(); //position = al catelea element
            v.setPressed(true);
            if (bp == 2) {
                if (position == 0) {
                Square.setSex(R.drawable.girl_body2v);
                Square2.setHair(R.drawable.girl_hair_01v);
                SquareAccesories.setAcc(R.drawable.girl_accessories_01v);
                SquareEyes.setEyes(R.drawable.eyes_1v);
                SquareLips.setLips(R.drawable.lip_1v);
                Square3.setDress(R.drawable.girl_tops_01v);
                SquareShoes.setShoes(R.drawable.girl_shoes_01v);
                SquarePants.setPants(R.drawable.girl_bottom_01v);
                setS(2);

This is a small part of the code for the onClickListener because i have lots of cases.

这是 onClickListener 代码的一小部分,因为我有很多案例。

回答by Strix

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

我认为更好的方法是告诉GridView您希望支持选择(检查)项目:

gridView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE);

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

然后确保GridView中的项目实现Checkable接口。这意味着项目可以是Checkbox,ToggleButton等等,或者您可以Checkable自己添加支持 - 例如使 RelativeLayout 可检查。(请参阅下面的示例。)

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

与其他答案相比,大部分工作都由 GridView 本身负责 -onClickListener不需要。而不是自己存储状态,只需调用gridView.getCheckedItemIds()或类似的方法。



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

要使RelativeLayout(或任何)可检查,请创建它的子类:

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 onCreateDrawableStateupdates the visual style. You don't have to do it this way, you can for example directly change the background in the setChange method.

请注意,该方法onCreateDrawableState更新了视觉样式。您不必这样做,例如您可以直接在 setChange 方法中更改背景。

Then use the CheckableRelativeLayoutas the top view for items in the GridView:

然后将CheckableRelativeLayout用作 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:

并定义签入项目时背景如何变化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>

回答by DroidBender

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

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>

回答by Dax Fohl

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.getViewmethod, overriding onCreateDrawableStateas 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:

当您不需要在其他地方重用该代码时,这是 Strix 答案的更简洁版本(我认为它比接受的答案更好)。Checked您可以在方法中创建一个匿名类,而不是创建一个新类并实现,而是像 Strix 的答案一样Adapter.getView覆盖onCreateDrawableState,但将其替换isChecked()((AbsListView)parent).isItemChecked(position). 这是我的适配器的完整代码,它在画廊中选中的缩略图周围绘制边框:

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;
    }
}

回答by maniac

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.

我知道答案有点旧。但我认为这是最简单的一种。在您的适配器类中,添加一个包含所选项目位置的变量。在 GetView 方法中将透明度设置为除所选图像之外的所有图像。在 main 方法中的单击处理程序中,保护选定的 ItemPosition。通知适配器他已更改。

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.

在 Adapter GetView 方法中将透明度设置为除所选图像之外的所有图像。

@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

在 main 方法中的单击处理程序中,保护选定的 ItemPosition。通知适配器他已经改变了

   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();
        }
    });

回答by Mohammad Ersan

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

中的视图gridview必须是CheckBoxs,通过这种方式您可以选中和取消选中它们。

回答by qwerty421

**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);


            });