我想要创建的是一个水平滚动图库.我有一个RecyclerView(支持22.0.0).我遇到的问题是,当我滚动到最后然后向后滚动时,通常会丢失一个图像,有时会丢失两个图像.奇怪的是,当我不停地来回扫动时,可能会丢失不同的图像.这是项目的布局:
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="160dp">
- <ImageView
- android:id="@+id/product_variation_image"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="centerCrop"
- android:layout_gravity="center"/>
这是Adaper:
- public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {
- private String[] mDataset;
- public static class ViewHolder extends RecyclerView.ViewHolder {
- public ImageView mImageView;
- public ViewHolder(View v) {
- super(v);
- mImageView = (ImageView) v.findViewById(R.id.product_variation_image);
- }
- }
- public TestAdapter(String[] myDataset) {
- mDataset = myDataset;
- }
- @Override
- public TestAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
- // create a new view
- View v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.variaton_list_item,parent,false);
- ViewHolder vh = new ViewHolder(v);
- return vh;
- }
- @Override
- public void onBindViewHolder(ViewHolder holder,int position) {
- holder.mImageView.setImageDrawable(null);
- String url = mDataset[position];
- Log.i("TEST","position = " + position);
- ((MainActivity)MainActivity.getInstance()).imageDownloader.download(url,holder.mImageView);
- }
- @Override
- public int getItemCount() {
- return mDataset.length;
- }
下载方法从URL获取图像,或者如果已经缓存,则从内存中获取图像.这适用于所有其他布局,例如ListView或GridView.这是我在片段中设置它的代码:
- final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
- layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
- mRecyclerView.setLayoutManager(layoutManager);
这是在onCreateView方法中.当我获取网址时,我填充它们并使用以下方法设置适配器:
- myDataset[i] = imageURL; // for each image
- mAdapter = new TestAdapter(myDataset);
- mRecyclerView.setAdapter(mAdapter);
有趣的是适配器中onBindViewHolder方法中的行,我记录位置.我发现没有显示图像的单元格是没有调用此方法.就像它出于某种原因跳过那个细胞一样.更奇怪的是,如果我按住一个单元格并继续从左向右滑动,如果一个单元格离开屏幕然后又重新进入,那么它的图像就会再次被调用onBindViewHolder方法.
解决方法
我认为不重要的一个类是造成这个问题的一个类.我不确定是什么原因,但它存在于我用于从BitmapFun示例获得的回收的自定义ImageView类中.
- public class RecyclingImageView extends ImageView {
- public RecyclingImageView(Context context) {
- super(context);
- }
- public RecyclingImageView(Context context,AttributeSet attrs) {
- super(context,attrs);
- }
- /**
- * @see android.widget.ImageView#onAttachedToWindow()
- */
- @Override
- protected void onAttachedToWindow() {}
- /**
- * @see android.widget.ImageView#onDetachedFromWindow()
- */
- @Override
- protected void onDetachedFromWindow() {
- // This has been detached from Window,so clear the drawable
- setImageDrawable(null);
- super.onDetachedFromWindow();
- }
- /**
- * @see android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)
- */
- @Override
- public void setImageDrawable(Drawable drawable) {
- // Keep hold of prevIoUs Drawable
- final Drawable prevIoUsDrawable = getDrawable();
- // Call super to set new Drawable
- super.setImageDrawable(drawable);
- // Notify new Drawable that it is being displayed
- notifyDrawable(drawable,true);
- // Notify old Drawable so it is no longer being displayed
- notifyDrawable(prevIoUsDrawable,false);
- }
- /**
- * Notifies the drawable that it's displayed state has changed.
- *
- * @param drawable
- * @param isDisplayed
- */
- private static void notifyDrawable(Drawable drawable,final boolean isDisplayed) {
- if (drawable instanceof RecyclingBitmapDrawable) {
- // The drawable is a CountingBitmapDrawable,so notify it
- ((RecyclingBitmapDrawable) drawable).setIsDisplayed(isDisplayed);
- } else if (drawable instanceof LayerDrawable) {
- // The drawable is a LayerDrawable,so recurse on each layer
- LayerDrawable layerDrawable = (LayerDrawable) drawable;
- for (int i = 0,z = layerDrawable.getNumberOfLayers(); i < z; i++) {
- notifyDrawable(layerDrawable.getDrawable(i),isDisplayed);
- }
- }
- }
- }
当我用普通的ImageView替换它时,我不再遇到问题.