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
Android gridview keep item selected
提问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 GridView
that 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
, ToggleButton
and so on or you can add the Checkable
support 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 onClickListener
is 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 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.
请注意,该方法onCreateDrawableState
更新了视觉样式。您不必这样做,例如您可以直接在 setChange 方法中更改背景。
Then use the CheckableRelativeLayout
as 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.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:
当您不需要在其他地方重用该代码时,这是 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 gridview
must 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);
});