我可以在RecyclerView中使用带有GridView的光标适配器吗?

时间:2017-02-22 03:02:58

标签: java android android-layout

我正在构建一个带有说明链接的图片应用。带有Cursor适配器的GridView RecyclerView是否适合使用Movie数据库作为电影缩略图和描述数据的来源。

1 个答案:

答案 0 :(得分:0)

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

Recycler view with cursor adapter

首先,CursorAdapter不适用于RecyclerView。你试图破解那些永远无法正常工作的东西。您无法调用它的方法并期望它能够正常运行。查看来源。

首先是第一件事。我们想要使用游标..让我们分开这个责任并创建RecyclerViewCursorAdapter。对于RecyclerView来说,它是CursorAdapter。这个细节与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();
        }
    };
}