在GridView中选择多个项目 [英] Select multiple items in GridView
问题描述
我正在开发一个类似画廊的活动。一切运行良好,但有一个关键功能缺失,我找不到一个体面的答案或解释。我需要的是让用户能够通过长时间点击选择多个项目。
这是所需的结果:
您可以清楚地看到所选图片和ActionBar中的选项。
我的设置是这样的:
<1>在我的XML中有一个 GridView :
< GridView xmlns:android =http://schemas.android.com/apk/res/android
android: id =@ + id / gridview
android:layout_width =fill_parent
android:layout_height =fill_parent
android:columnWidth =90dp$ b $ android:numColumns = auto_fit
android:verticalSpacing =5dp
android:horizontalSpacing =5dp
android:stretchMode =columnWidth
android:gravity =center/>
2.它附加到一个类,它扩展了 BaseAdapter 并加载使用毕加索的图像:
public class GalleryAdapter extends BaseAdapter {
Context mContext;
列表< String> mDataset;
public GalleryAdapter(Context context,List< String> dataset){
mContext = context;
mDataset =数据集;
}
@Override
public int getCount(){
return mDataset.size();
}
@Override
public Object getItem(int position){
return mDataset.get(position);
}
@Override
public long getItemId(int position){
return 0;
}
@Override
public View getView(int position,View convertView,ViewGroup parent){
ImageView imageView;
if(convertView == null){
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200,200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8,8,8,8);
} else {
imageView =(ImageView)convertView;
}
// TODO:REMOVE INTEGER.VALUEOFF。这是为MOCK
Picasso.with(mContext).load(Integer.valueOf(mDataset.get(position)))。fit()。
return imageView;
}
}
<3>附加到活动:
//获取图片路径
列表< String> data = getImagesPath(this);
列表< String> sortedData = new ArrayList<>();
for(String file:data){
sortedData.add(0,file);
}
GalleryAdapter adapter = new GalleryAdapter(this,sortedData);
mGallery.setAdapter(adapter);
我尝试让GridView中的项目实现 Checkable :
从现在开始:
public class CheckableItem extends LinearLayout implements Checkable {
private boolean mIsChecked = false;
private static final int [] CHECKED_STATE_SET = {android.R.attr.state_checked};
public CheckableItem(Context context){
super(context);
$ b @Override
protected int [] onCreateDrawableState(int extraSpace){
int [] drawableState = super.onCreateDrawableState(extraSpace + 1);
if(isChecked())
mergeDrawableStates(drawableState,CHECKED_STATE_SET);
返回drawableState;
}
@Override
public void setChecked(boolean checked){
mIsChecked = checked;
refreshDrawableState();
}
@Override
public boolean isChecked(){
return mIsChecked;
}
@Override
public void toggle(){
setChecked(!isChecked());
refreshDrawableState();
}
然后加载它在我的XML中,并在Activity中将 新增 MultiChoiceModeListener : .setChoiceMode(GridView.CHOICE_MODE_MULTIPLE)
添加到我的 GridView 中。
class MultiChoiceListener implements GridView.MultiChoiceModeListener {
@Override $ b $ public void onItemCheckedStateChanged(ActionMode mode,int position,long id,boolean checked){
int selectCount = mGallery.getCheckedItemCount();
switch(selectCount){
case 1:
mode.setSubtitle(One item selected);
休息;
默认值:
mode.setSubtitle(+ selectCount +items selected);
休息;
$ @ $ $ $ b $ public boolean onCreateActionMode(ActionMode mode,Menu menu) {
mode.setTitle(选择项目);
mode.setSubtitle(One item selected);
返回true;
@Override
public boolean onPrepareActionMode(ActionMode mode,Menu menu){
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode,MenuItem item){
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode){
$ b $}
}
然后将它添加到我的gridView .setMultiChoiceModeListener(newMultiChoiceListener());
但仍然没有结果。
一种在 GridView 中实现此项选择行为的方法?我想使用原生的Android API,没有第三方库。 我认为Checkable和我看到的其余部分在你的代码中有点矫枉过正......当我想要实现类似的东西时,我只是在GridView / ListView中显示的对象的类中添加另一个字段,该对象存储对象的选中状态。例如:
class Image {
Bitmap bm;
boolean isChecked = false;
public Image(Bitmap bm){
this.bm = bm;
}
public boolean isChecked(){
return isChecked;
}
public void toggleChecked(){
isChecked =!isChecked;
}
}
并将一个ArrayList提供给适配器。在适配器的getView方法中,我做了这样的事情;
@Override
public View getView(int position,View convertView,ViewGroup parent){
if(images.get(position).isChecked()){
//显示覆盖视图,显示选中的项目
}
else {
//隐藏覆盖视图
}
}
终于在ListView的onItemClickListener
listView.setOnItemClickListener(new OnItemClickListener(){
$ b $ @Override
public void onItemClick ();
images.get(position).toggleChecked();
listView.getAdapter()。notifyDataSetChanged();
}
});
I am developing a gallery-like Activity. Everything runs fine but there is a key functionality which is missing and I couldn't find a decent answer or explanation. What I need is to give the user the ability to select multiple items by long clicking on them.
Here is the desired result:
You can clearly see the selected pics and the options in the ActionBar.
My setup is this:
1.I have a GridView in my XML:
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="5dp"
android:horizontalSpacing="5dp"
android:stretchMode="columnWidth"
android:gravity="center"/>
2.It is attached to a class, which extends BaseAdapter and loads images using Picasso:
public class GalleryAdapter extends BaseAdapter {
Context mContext;
List<String> mDataset;
public GalleryAdapter(Context context, List<String> dataset) {
mContext = context;
mDataset = dataset;
}
@Override
public int getCount() {
return mDataset.size();
}
@Override
public Object getItem(int position) {
return mDataset.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if(convertView == null){
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200,200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8,8,8,8);
} else {
imageView = (ImageView) convertView;
}
//TODO: REMOVE INTEGER.VALUEOFF. IT'S MADE FOR MOCK
Picasso.with(mContext).load(Integer.valueOf(mDataset.get(position))).fit().into(imageView);
return imageView;
}
}
3.It is attached to the Activity:
//Get images paths
List<String> data = getImagesPath(this);
List<String> sortedData = new ArrayList<>();
for(String file : data){
sortedData.add(0, file);
}
GalleryAdapter adapter = new GalleryAdapter(this, sortedData);
mGallery.setAdapter(adapter);
From now on the struggle begins:
I tried making my item in the GridView to implement Checkable:
public class CheckableItem extends LinearLayout implements Checkable{ private boolean mIsChecked = false; private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked }; public CheckableItem(Context context) { super(context); } @Override protected int[] onCreateDrawableState(int extraSpace) { int[] drawableState = super.onCreateDrawableState(extraSpace + 1); if (isChecked()) mergeDrawableStates(drawableState, CHECKED_STATE_SET); return drawableState; } @Override public void setChecked(boolean checked) { mIsChecked = checked; refreshDrawableState(); } @Override public boolean isChecked() { return mIsChecked; } @Override public void toggle() { setChecked(!isChecked()); refreshDrawableState(); }
Then I load it in my XML and added .setChoiceMode(GridView.CHOICE_MODE_MULTIPLE)
to my GridView in the Activity. Nothing Happened.
Added MultiChoiceModeListener:
class MultiChoiceListener implements GridView.MultiChoiceModeListener{ @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { int selectCount = mGallery.getCheckedItemCount(); switch (selectCount) { case 1: mode.setSubtitle("One item selected"); break; default: mode.setSubtitle("" + selectCount + " items selected"); break; } }
@Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mode.setTitle("Select Items"); mode.setSubtitle("One item selected"); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; } @Override public void onDestroyActionMode(ActionMode mode) { }
}
Then added it to my gridView .setMultiChoiceModeListener(newMultiChoiceListener());
but still no results.
Can someone propose a way to achieve this item selecting behavior in GridView? I'd like to use the native Android API, no 3rd party libraries.
I think Checkable and the rest that I see in your code is a bit of an overkill...When I want to implement something like that I just add another field in the class of the object that is shown in the GridView/ListView which stores the checked state of the object. example:
class Image {
Bitmap bm;
boolean isChecked=false;
public Image(Bitmap bm){
this.bm=bm;
}
public boolean isChecked(){
return isChecked;
}
public void toggleChecked(){
isChecked = !isChecked;
}
}
and feed an ArrayList to the adapter. an in the getView method of the adapter I do something like this;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(images.get(position).isChecked()){
//show the overlay view that suggests the item is selected
}
else{
//hide the overlay view
}
}
finally in the onItemClickListener of the ListView
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
images.get(position).toggleChecked();
listView.getAdapter().notifyDataSetChanged();
}
});
这篇关于在GridView中选择多个项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!