我有一个带适配器的gridview,当点击了一个imageview时,它还有一个复选框外观。但出了点问题。如果选中图像并滚动到底部,则还会检查其中一个图像。如果再次向上滚动,则会检查与您单击开始的图像不同的图像(在大多数情况下)。 这里是我的适配器的代码。关注的代码是getView方法:
public class ImageAdapter extends BaseAdapter {
private Context context;
private ArrayList<String> files;
private Bitmap mPlaceHolderBitmap;
private File directory;
private int thumbSize;
private GridImageListener gridImageListener;
private LayoutInflater inflater;
private View rootView;
private final int MAX_PICTURE_LIMIT = 5;
private int picturesChosenCount = 0;
public ImageAdapter(Context context, ArrayList<String> files, File directory, int thumbSize, GridImageListener gridImageListener, LayoutInflater inflater, View rootView) {
super();
this.context = context;
this.files = files;
this.directory = directory;
this.thumbSize = thumbSize;
this.gridImageListener = gridImageListener;
this.inflater = inflater;
this.rootView = rootView;
mPlaceHolderBitmap = drawableToBitmap(context.getResources().getDrawable(R.drawable.logo));
}
public Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
@Override
public int getCount() {
return files.size();
}
@Override
public Object getItem(int position) {
return files.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup container) {
final ViewHolder holder;
if (convertView == null) { // if it's not recycled, initialize some attributes
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.component_imageview_checkable, null);
holder.imageview = (ImageView) convertView.findViewById(R.id.checkableImageView);
holder.imageview.getLayoutParams().height = thumbSize;
holder.imageview.getLayoutParams().width = thumbSize;
holder.imageCheckBox = (RelativeLayout) convertView.findViewById(R.id.image_check_view);
loadBitmap(files.get(position), holder.imageview);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.imageCheckBox.setId(position);
holder.imageview.setId(position);
holder.imageview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder.imageCheckBox.getVisibility() == View.VISIBLE) {
holder.imageCheckBox.setVisibility(View.INVISIBLE);
picturesChosenCount--;
} else {
if (picturesChosenCount < 5) {
holder.imageCheckBox.setVisibility(View.VISIBLE);
picturesChosenCount++;
} else {
Toast.makeText(context, "Max number of pictures has been reached", Toast.LENGTH_SHORT).show();
}
}
gridImageListener.onClickImage(files.get(position));
}
});
holder.id = position;
return convertView;
}
public void loadBitmap(String path, ImageView imageView) {
if (cancelPotentialWork(path, imageView)) {
final BitmapWorkerTask task = new BitmapWorkerTask(imageView, context, path, directory, thumbSize);
final AsyncDrawable asyncDrawable =
new AsyncDrawable(context.getResources(), mPlaceHolderBitmap, task);
imageView.setImageDrawable(asyncDrawable);
task.execute(path);
}
}
public static boolean cancelPotentialWork(String path, ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
if (bitmapWorkerTask != null) {
final String bitmapData = bitmapWorkerTask.path;
// If bitmapData is not yet set or it differs from the new data
if (bitmapData.equals("0") || !bitmapData.equals(path)) {
// Cancel previous task
bitmapWorkerTask.cancel(true);
} else {
// The same work is already in progress
return false;
}
}
// No task associated with the ImageView, or an existing task was cancelled
return true;
}
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference =
new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
}
class ViewHolder {
int id;
ImageView imageview;
RelativeLayout imageCheckBox;
}
我知道它与gridview中的视图回收有关,但我不知道如何避免/修复它。 每个imageview都单独加载到asynctask中,并在滚动到它时重新加载。如果您需要查看它,代码就在这里:http://pastebin.com/2BcBW7PN
最后,这是我的每个图像项目的xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/checkableImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<RelativeLayout
android:id="@+id/image_check_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/checkableImageView"
android:layout_alignTop="@+id/checkableImageView"
android:layout_alignRight="@+id/checkableImageView"
android:layout_alignBottom="@+id/checkableImageView"
android:visibility="invisible">
<com.ivankocijan.magicviews.views.MagicTextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/white"
android:background="@drawable/blue_border"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<com.ivankocijan.magicviews.views.MagicTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/icon_check"
android:textColor="@color/white"
android:textSize="@dimen/txtsize_standard_smaller_icon"
android:padding="4dp"
app:typeFace="@string/icon_font"
android:background="@color/standard_blue"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</RelativeLayout>
我真的希望有人能看到错误。我已经阅读了所有可以找到的教程,但它们似乎没有任何区别。 任何帮助将不胜感激。
答案 0 :(得分:0)
您可以使用:例如:Android – Select multiple photos from Gallery
或者:
实体-CustomGallery.class
public class CustomGallery {
public String sdcardPath;
public boolean isSeleted = false;
}
Adapter -GalleryAdapterCustom.class
private Context mContext;
private LayoutInflater infalter;
private ArrayList<CustomGallery> data = new ArrayList<CustomGallery>();
ImageLoader imageLoader;
private boolean isActionMultiplePick;
public GalleryAdapterCustom(Context c, ImageLoader imageLoader) {
infalter = (LayoutInflater) c
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContext = c;
this.imageLoader = imageLoader;
// clearCache();
}
@Override
public int getCount() {
return data.size();
}
@Override
public CustomGallery getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public void setMultiplePick(boolean isMultiplePick) {
this.isActionMultiplePick = isMultiplePick;
}
public void selectAll(boolean selection) {
for (int i = 0; i < data.size(); i++) {
data.get(i).isSeleted = selection;
}
notifyDataSetChanged();
}
public boolean isAllSelected() {
boolean isAllSelected = true;
for (int i = 0; i < data.size(); i++) {
if (!data.get(i).isSeleted) {
isAllSelected = false;
break;
}
}
return isAllSelected;
}
public boolean isAnySelected() {
boolean isAnySelected = false;
for (int i = 0; i < data.size(); i++) {
if (data.get(i).isSeleted) {
isAnySelected = true;
break;
}
}
return isAnySelected;
}
public ArrayList<CustomGallery> getSelected() {
ArrayList<CustomGallery> dataT = new ArrayList<CustomGallery>();
for (int i = 0; i < data.size(); i++) {
if (data.get(i).isSeleted) {
dataT.add(data.get(i));
}
}
return dataT;
}
public void addAll(ArrayList<CustomGallery> files) {
try {
this.data.clear();
this.data.addAll(files);
} catch (Exception e) {
e.printStackTrace();
}
notifyDataSetChanged();
}
public void changeSelection(View v, int position) {
if (data.get(position).isSeleted) {
data.get(position).isSeleted = false;
} else {
data.get(position).isSeleted = true;
}
ArrayList<CustomGallery> dataT = new ArrayList<CustomGallery>();
for (int i = 0; i < data.size(); i++) {
if (data.get(i).isSeleted) {
dataT.add(data.get(i));
}
}
if (dataT.size() > NewPostActivity.max_image) {
Toast.makeText(mContext, "Bạn chỉ được đăng tối đa 20 ảnh / 1 tin",
Toast.LENGTH_SHORT).show();
data.get(position).isSeleted = false;
}
((ViewHolder) v.getTag()).imgQueueMultiSelected.setSelected(data
.get(position).isSeleted);
// }
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = infalter.inflate(R.layout.gallery_item, null);
holder = new ViewHolder();
holder.imgQueue = (ImageView) convertView
.findViewById(R.id.imgQueue);
holder.imgQueueMultiSelected = (ImageView) convertView
.findViewById(R.id.imgQueueMultiSelected);
if (isActionMultiplePick) {
holder.imgQueueMultiSelected.setVisibility(View.VISIBLE);
} else {
holder.imgQueueMultiSelected.setVisibility(View.GONE);
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.imgQueue.setTag(position);
try {
imageLoader.displayImage("file://" + data.get(position).sdcardPath,
holder.imgQueue, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
holder.imgQueue
.setImageResource(R.drawable.default_icon2);
super.onLoadingStarted(imageUri, view);
}
});
if (isActionMultiplePick) {
holder.imgQueueMultiSelected
.setSelected(data.get(position).isSeleted);
}
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
public class ViewHolder {
ImageView imgQueue;
ImageView imgQueueMultiSelected;
}
public void clearCache() {
imageLoader.clearDiscCache();
imageLoader.clearMemoryCache();
}
public void clear() {
data.clear();
notifyDataSetChanged();
}
}
Activity- CustomGalleryActivity.class
public class CustomGalleryActivity extends Activity {
GridView gridGallery;
Handler handler;
GalleryAdapterCustom adapter;
String count_image;
RelativeLayout layout_select, layout_cancel;
ImageView imgNoMedia;
Button btnGalleryOk;
public static final int REQUEST_CODE_Gallery = 1111;
public static final int REQUEST_CODE_Gallery_OK = 2222;
String action;
private ImageLoader imageLoader;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.gallery);
action = getIntent().getStringExtra("action");
if (action == null) {
finish();
}
initImageLoader();
init();
}
private void initImageLoader() {
try {
String CACHE_DIR = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/.temp_tmp";
new File(CACHE_DIR).mkdirs();
File cacheDir = StorageUtils.getOwnCacheDirectory(getBaseContext(),
CACHE_DIR);
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheOnDisc(true).imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565).build();
ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(
getBaseContext())
.defaultDisplayImageOptions(defaultOptions)
.discCache(new UnlimitedDiscCache(cacheDir))
.memoryCache(new WeakMemoryCache());
ImageLoaderConfiguration config = builder.build();
imageLoader = ImageLoader.getInstance();
imageLoader.init(config);
} catch (Exception e) {
}
}
private void init() {
handler = new Handler();
gridGallery = (GridView) findViewById(R.id.gridGallery);
gridGallery.setFastScrollEnabled(true);
adapter = new GalleryAdapterCustom(getApplicationContext(), imageLoader);
PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader,
true, true);
gridGallery.setOnScrollListener(listener);
if (action.equalsIgnoreCase(Action.ACTION_MULTIPLE_PICK)) {
findViewById(R.id.layout_select).setVisibility(View.VISIBLE);
gridGallery.setOnItemClickListener(mItemMulClickListener);
adapter.setMultiplePick(true);
} else if (action.equalsIgnoreCase(Action.ACTION_PICK)) {
findViewById(R.id.layout_select).setVisibility(View.GONE);
gridGallery.setOnItemClickListener(mItemSingleClickListener);
adapter.setMultiplePick(false);
}
gridGallery.setAdapter(adapter);
imgNoMedia = (ImageView) findViewById(R.id.imgNoMedia);
layout_cancel = (RelativeLayout) findViewById(R.id.layout_cancel);
layout_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
layout_select = (RelativeLayout) findViewById(R.id.layout_select);
layout_select.setOnClickListener(mOkClickListener);
new Thread() {
@Override
public void run() {
Looper.prepare();
handler.post(new Runnable() {
@Override
public void run() {
adapter.addAll(getGalleryPhotos());
checkImageStatus();
}
});
Looper.loop();
};
}.start();
}
private void checkImageStatus() {
if (adapter.isEmpty()) {
imgNoMedia.setVisibility(View.VISIBLE);
} else {
imgNoMedia.setVisibility(View.GONE);
}
}
View.OnClickListener mOkClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
ArrayList<CustomGallery> selected = adapter.getSelected();
String[] allPath = new String[selected.size()];
for (int i = 0; i < allPath.length; i++) {
allPath[i] = selected.get(i).sdcardPath;
}
if (allPath.length == 0) {
Toast.makeText(CustomGalleryActivity.this, "Vui lòng chọn ảnh",
Toast.LENGTH_SHORT).show();
} else {
Intent data = new Intent().putExtra("all_path", allPath);
setResult(REQUEST_CODE_Gallery_OK, data);
finish();
}
}
};
AdapterView.OnItemClickListener mItemMulClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
adapter.changeSelection(v, position);
}
};
AdapterView.OnItemClickListener mItemSingleClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
CustomGallery item = adapter.getItem(position);
Intent data = new Intent().putExtra("single_path", item.sdcardPath);
setResult(REQUEST_CODE_Gallery_OK, data);
finish();
}
};
private ArrayList<CustomGallery> getGalleryPhotos() {
ArrayList<CustomGallery> galleryList = new ArrayList<CustomGallery>();
try {
final String[] columns = { MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID };
final String orderBy = MediaStore.Images.Media._ID;
Cursor imagecursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
null, null, orderBy);
if (imagecursor != null && imagecursor.getCount() > 0) {
while (imagecursor.moveToNext()) {
CustomGallery item = new CustomGallery();
int dataColumnIndex = imagecursor
.getColumnIndex(MediaStore.Images.Media.DATA);
item.sdcardPath = imagecursor.getString(dataColumnIndex);
galleryList.add(item);
}
}
} catch (Exception e) {
e.printStackTrace();
}
// show newest photo at beginning of the list
Collections.reverse(galleryList);
return galleryList;
}
使用。
Intent i = new Intent(NewPostActivity.this,
CustomGalleryActivity.class);
i.putExtra("action", Action.ACTION_MULTIPLE_PICK);
startActivityForResult(i, REQUEST_CODE_Gallery);