繁体   English   中英

我可以在 RecyclerView 中将 Cursor Adapter 与 GridView 一起使用吗

[英]Can I use Cursor Adapter with a GridView in a RecyclerView

我正在构建一个带有描述链接的图片应用程序。 带有 Cursor 适配器的GridView RecyclerView是否适合执行此操作,因为使用电影数据库作为电影缩略图和描述数据的来源。

请在下面的链接中找到游标适配器的实现我也在链接下面放了代码,它可能对你有帮助。

带游标适配器的回收器视图

首先,CursorAdapter 不是为与 RecyclerView 一起使用而设计的。 您正在尝试破解那里的某些永远无法正常工作的东西。 你不能只是调用它的方法并期望它正常运行。 见源码。

所以首先要做的事情。 我们想使用一个游标......让我们分离这个职责并创建 RecyclerViewCursorAdapter。 这就是它所说的,一个 CursorAdapter,用于 RecyclerView。 其细节与 CursorAdapter 的工作原理几乎相同。 查看它的来源,看看什么是相同的,什么不是。

接下来,我们现在有您的原始类 RVAdapter 来实现抽象 RecyclerViewCursorAdapter,它需要我们实现 onCreateViewHolder 和我们的新 onBindViewHolder,它为我们提供了一个 Cursor 参数来绑定。 这些视图的细节和你原来的一样,只是稍微整理了一下。

RVAdapter.java

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import java.util.Random;


public class RVAdapter extends RecyclerViewCursorAdapter<RVAdapter.ProductViewHolder>
{
    private static final String TAG = RVAdapter.class.getSimpleName();
    private final Context mContext;
    private final Random mRandom;


    public RVAdapter(Context context, String locationSetting)
    {
        super(null);
        mContext = context;
        mRandom  = new Random(System.currentTimeMillis());

        // Sort order:  Ascending, by date.
        String sortOrder = ProductContract.ProductEntry.COLUMN_DATE + " ASC";
        Uri productForLocationUri = ProductContract.ProductEntry
            .buildProductLocationWithStartDate(locationSetting, System.currentTimeMillis());

        // Students: Uncomment the next lines to display what what you stored in the bulkInsert
        Cursor cursor = mContext.getContentResolver()
            .query(productForLocationUri, null, null, null, sortOrder);

        swapCursor(cursor);
    }

    @Override
    public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item, parent, false);
        return new ProductViewHolder(view);
    }

    @Override
    protected void onBindViewHolder(ProductViewHolder holder, Cursor cursor)
    {
        String imagePath = cursor.getString(ShopFragment.COL_PRODUCT_IMAGE);
        String price = cursor.getString(ShopFragment.COL_PRODUCT_PRICE);

        holder.productPrice.setText("US $" + price);

        int height = mRandom.nextInt(50) + 500;

        //Download image using picasso library
        Picasso.with(mContext)
            .load(imagePath)
            .resize(500, height)
            .error(R.drawable.placeholder)
            .placeholder(R.drawable.placeholder)
            .into(holder.productPhoto);
    }


    public static class ProductViewHolder extends RecyclerView.ViewHolder
    {
        CardView cv;
        TextView productPrice;
        ImageView productPhoto;

        ProductViewHolder(View itemView)
        {
            super(itemView);
            cv = (CardView) itemView.findViewById(R.id.cv);
            productPrice = (TextView) itemView.findViewById(R.id.product_price);
            productPhoto = (ImageView) itemView.findViewById(R.id.product_photo);
        }
    }
}

RecyclerViewCursorAdapter.java

import android.database.Cursor;
import android.database.DataSetObserver;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;


/**
 * RecyclerView CursorAdapter
 * <p>
 * Created by Simon on 28/02/2016.
 */
public abstract class RecyclerViewCursorAdapter<VH extends RecyclerView.ViewHolder> extends
    RecyclerView.Adapter<VH>
{
    private Cursor mCursor;
    private boolean mDataValid;
    private int mRowIDColumn;


    public RecyclerViewCursorAdapter(Cursor cursor)
    {
        setHasStableIds(true);
        swapCursor(cursor);
    }

    public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);

    protected abstract void onBindViewHolder(VH holder, Cursor cursor);

    @Override
    public void onBindViewHolder(VH holder, int position)
    {
        if(!mDataValid){
            throw new IllegalStateException("this should only be called when the cursor is valid");
        }
        if(!mCursor.moveToPosition(position)){
            throw new IllegalStateException("couldn't move cursor to position " + position);
        }
        onBindViewHolder(holder, mCursor);
    }

    @Override
    public long getItemId(int position)
    {
        if(mDataValid && mCursor != null && mCursor.moveToPosition(position)){
            return mCursor.getLong(mRowIDColumn);
        }
        return RecyclerView.NO_ID;
    }

    @Override
    public int getItemCount()
    {
        if(mDataValid && mCursor != null){
            return mCursor.getCount();
        }
        else{
            return 0;
        }
    }

    protected Cursor getCursor()
    {
        return mCursor;
    }

    public void changeCursor(Cursor cursor)
    {
        Cursor old = swapCursor(cursor);
        if(old != null){
            old.close();
        }
    }

    public Cursor swapCursor(Cursor newCursor)
    {
        if(newCursor == mCursor){
            return null;
        }
        Cursor oldCursor = mCursor;
        if(oldCursor != null){
            if(mDataSetObserver != null){
                oldCursor.unregisterDataSetObserver(mDataSetObserver);
            }
        }
        mCursor = newCursor;
        if(newCursor != null){
            if(mDataSetObserver != null){
                newCursor.registerDataSetObserver(mDataSetObserver);
            }
            mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
            mDataValid = true;
            notifyDataSetChanged();
        }
        else{
            mRowIDColumn = -1;
            mDataValid = false;
            notifyDataSetChanged();
        }
        return oldCursor;
    }


    private DataSetObserver mDataSetObserver = new DataSetObserver()
    {
        @Override
        public void onChanged()
        {
            mDataValid = true;
            notifyDataSetChanged();
        }

        @Override
        public void onInvalidated()
        {
            mDataValid = false;
            notifyDataSetChanged();
        }
    };
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM