ImageViews自定义复选框随机重复

时间:2015-12-23 00:32:45

标签: android gridview imageview

我有一个带适配器的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>

我真的希望有人能看到错误。我已经阅读了所有可以找到的教程,但它们似乎没有任何区别。 任何帮助将不胜感激。

1 个答案:

答案 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);