RecyclerView适配器未返回正确的光标位置

时间:2017-03-07 00:50:01

标签: android

我一直在试图弄清楚如何使用来自数据库的可点击图像来使用RecyclerView Adapter。当点击图像时,我的应用程序总是崩溃,出现错误“android.database.CursorIndexOutOfBoundsException:索引4请求,大小为4”。当我向db添加更多项时,错误中的索引也会递增。请任何帮助将不胜感激。请参阅下面的代码段。 `public class SelectItemRecycleViewAdapter扩展了RecyclerView.Adapter {

private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;

PreferenceActivity.Header header;
Context context;
Cursor cursor;
RecyclerView.ViewHolder holder;

public SelectItemRecycleViewAdapter(Context mContext, Cursor mCursor, PreferenceActivity.Header header) {
    context = mContext;
    cursor = mCursor;
    this.header = header;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.selection, parent, false);

    if(viewType == TYPE_HEADER)

    {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.add_item, parent, false);
        return  new VHHeader(v);
    }
    else if(viewType == TYPE_ITEM)
    {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.display_items, parent, false);
        return  new VHItem(v);
    }
    throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}

public Cursor swapCursor(Cursor mCursor) {
    if (cursor == mCursor) {
        return null;
    }
    Cursor oldCursor = cursor;
    this.cursor = mCursor;
    if (mCursor != null) {
        this.notifyDataSetChanged();
    }
    return oldCursor;
}


@Override
public void onBindViewHolder(RecyclerView.ViewHolder mHolder, int position) {

    holder = mHolder;

    if(holder instanceof VHHeader)
    {

        VHHeader VHheader = (VHHeader)holder;

        VHheader.mAdd.setText( "ADD");
        VHheader.mItem.setText( "ITEM");

    }
    else if(holder instanceof VHItem)
    {
        VHItem VHitem = (VHItem)holder;
        int iPosition = position - 1;
        cursor.moveToPosition(iPosition);

        String iString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_IMAGE));

        try {

            byte[] bytarray = decode(String.valueOf(iString), Base64.DEFAULT);
            Bitmap bmimage = BitmapFactory.decodeByteArray(bytarray, 0,
                    bytarray.length);

            VHitem.mDisplayImage.setImageBitmap(bmimage);


        } catch (Exception e){


        }

        String nString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_NAME));
        VHitem.mDisplayName.setText(nString);

        String pString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_PRICE));
        VHitem.mDisplayPrice.setText(pString);

        String bString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_BRAND));

        if (bString.equals("")){

            VHitem.mDisplayBrandView.setVisibility(View.GONE);
        }

        VHitem.mDisplayBrand.setText(bString);


        String aString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_ATTRIBUTE));

        if (aString.equals("")){

            VHitem.mDisplayAttributeView.setVisibility(View.GONE);
        } else {

            VHitem.mDisplayAttribute.setText(aString);

        }

        String qString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_QUANTITY));

        if (qString.equals("")){

            VHitem.mDisplayQuantityView.setVisibility(View.GONE);

        } else {

            VHitem.mDisplayQuantity.setText( "Quantity - " + qString);

        }

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int itemPosition = holder.getAdapterPosition();

                if(holder.getAdapterPosition() != RecyclerView.NO_POSITION){
                    cursor.move(itemPosition);
                }


                String bString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_BRAND));
                String nString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_NAME));
                String aString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_ATTRIBUTE));
                String pString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_PRICE));

                bString = bString + " ";
                aString = " " + aString;

                String description = bString + nString + aString;
                String [] array = {description, pString};
                mCallback.addArray(array);
            }
        });

    }

}

//    need to override this method
@Override
public int getItemViewType(int position) {
    if(isPositionHeader(position))
        return TYPE_HEADER;
    return TYPE_ITEM;
}

private boolean isPositionHeader(int position)
{
    return position == 0;
}

@Override
public int getItemCount() {
    return (cursor == null) ? 0 : cursor.getCount() + 1;
}

class VHHeader extends RecyclerView.ViewHolder{

    TextView mAdd;
    TextView mItem;

    public VHHeader(View itemView) {
        super(itemView);
        this.mAdd = (TextView) itemView.findViewById(R.id.add);
        this.mItem = (TextView) itemView.findViewById(R.id.item);

    }
}

class VHItem extends RecyclerView.ViewHolder{

    ImageView mDisplayImage;
    TextView mDisplayBrand;
    TextView mDisplayName;
    TextView mDisplayAttribute;
    TextView mDisplayQuantity;
    TextView mDisplayPrice;

    View mDisplayImageView;
    View mDisplayBrandView;
    View mDisplayNameView;
    View mDisplayAttributeView;
    View mDisplayQuantityView;
    View mDisplayPriceView;
    View v;

    public VHItem(View itemView) {
        super(itemView);
        this.mDisplayImage = (ImageView) itemView.findViewById(R.id.displayImage);
        this.mDisplayBrand = (TextView) itemView.findViewById(R.id.displayBrand);
        this.mDisplayName = (TextView) itemView.findViewById(R.id.displayName);
        this.mDisplayAttribute = (TextView) itemView.findViewById(R.id.displayAttribute);
        this.mDisplayQuantity = (TextView) itemView.findViewById(R.id.displayQuantity);
        this.mDisplayPrice = (TextView) itemView.findViewById(R.id.displayPrice);

        this.mDisplayImageView = itemView.findViewById(R.id.displayImageView);
        this.mDisplayBrandView = itemView.findViewById(R.id.displayBrandView);
        this.mDisplayNameView = itemView.findViewById(R.id.displayNameView);
        this.mDisplayAttributeView = itemView.findViewById(R.id.displayAttributeView);
        this.mDisplayQuantityView = itemView.findViewById(R.id.displayQuantityView);
        this.mDisplayPriceView = itemView.findViewById(R.id.displayPriceView);
    }
}

public interface Callback{
    void addArray(String[] a);
}

private Callback mCallback;

public void setListener(Callback callBack){
    mCallback=callBack;

`

3 个答案:

答案 0 :(得分:0)

错误在下面的代码中,它总是返回加1索引,因为你写了bool WriteData(char *buffer, unsigned int nbChar);

cursor.getCount()+1

用以下代码替换代码:

@Override
public int getItemCount() {
    return (cursor == null) ? 0 : cursor.getCount() + 1;
}

答案 1 :(得分:0)

@Override
public int getItemCount() {
return (cursor.getCount());
}

答案 2 :(得分:0)

经过多天的奋斗,我终于找到了解决问题的方法。见下面的代码。非常感谢@Caspain和@Asif。

public class SelectItemRecycleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;

private final View.OnClickListener mOnClickListener = new MyOnClickListener();

RecyclerView recyclerView;

PreferenceActivity.Header header;
Context context;
Cursor cursor;

public SelectItemRecycleViewAdapter(Context mContext, Cursor mCursor, PreferenceActivity.Header header) {
    context = mContext;
    cursor = mCursor;
    this.header = header;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.selection, parent, false);
    recyclerView = (RecyclerView) view.findViewById(R.id.grid);

    if(viewType == TYPE_HEADER)

    {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.add_item, parent, false);
        return  new VHHeader(v);
    }
    else if(viewType == TYPE_ITEM)
    {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.display_items, parent, false);
        return  new VHItem(v);
    }
    throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}

public Cursor swapCursor(Cursor mCursor) {
    if (cursor == mCursor) {
        return null;
    }
    Cursor oldCursor = cursor;
    this.cursor = mCursor;
    if (mCursor != null) {
        this.notifyDataSetChanged();
    }
    return oldCursor;
}


@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {


    if(holder instanceof VHHeader)
    {

        VHHeader VHheader = (VHHeader)holder;

        VHheader.mAdd.setText( "ADD");
        VHheader.mItem.setText( "ITEM");

    }
    else if(holder instanceof VHItem)
    {
        VHItem VHitem = (VHItem)holder;
        cursor.moveToPosition(position - 1);

        holder.itemView.setOnClickListener(mOnClickListener);

        String iString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_IMAGE));

        try {

            byte[] bytarray = decode(String.valueOf(iString), Base64.DEFAULT);
            Bitmap bmimage = BitmapFactory.decodeByteArray(bytarray, 0,
                    bytarray.length);

            VHitem.mDisplayImage.setImageBitmap(bmimage);


        } catch (Exception e){


        }

        String nString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_NAME));
        VHitem.mDisplayName.setText(nString);

        String pString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_PRICE));
        VHitem.mDisplayPrice.setText(pString);

        String bString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_BRAND));

        if (bString.equals("")){

            VHitem.mDisplayBrandView.setVisibility(View.GONE);
        }

        VHitem.mDisplayBrand.setText(bString);

        String aString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_ATTRIBUTE));

        if (aString.equals("")){

            VHitem.mDisplayAttributeView.setVisibility(View.GONE);
        } else {

            VHitem.mDisplayAttribute.setText(aString);

        }

        String qString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_QUANTITY));

        if (qString.equals("")){

            VHitem.mDisplayQuantityView.setVisibility(View.GONE);

        } else {

            VHitem.mDisplayQuantity.setText( "Quantity - " + qString);

        }

    }

}

//    need to override this method
@Override
public int getItemViewType(int position) {
    if(isPositionHeader(position))
        return TYPE_HEADER;
    return TYPE_ITEM;
}

private boolean isPositionHeader(int position)
{
    return position == 0;
}

@Override
public int getItemCount() {
    return (cursor == null) ? 0 : cursor.getCount() + 1;
}

class VHHeader extends RecyclerView.ViewHolder{

    TextView mAdd;
    TextView mItem;

    public VHHeader(View itemView) {
        super(itemView);
        this.mAdd = (TextView) itemView.findViewById(R.id.add);
        this.mItem = (TextView) itemView.findViewById(R.id.item);

    }
}

class VHItem extends RecyclerView.ViewHolder{

    ImageView mDisplayImage;
    TextView mDisplayBrand;
    TextView mDisplayName;
    TextView mDisplayAttribute;
    TextView mDisplayQuantity;
    TextView mDisplayPrice;

    View mDisplayImageView;
    View mDisplayBrandView;
    View mDisplayNameView;
    View mDisplayAttributeView;
    View mDisplayQuantityView;
    View mDisplayPriceView;
    View v;

    public VHItem(View itemView) {
        super(itemView);
        this.mDisplayImage = (ImageView) itemView.findViewById(R.id.displayImage);
        this.mDisplayBrand = (TextView) itemView.findViewById(R.id.displayBrand);
        this.mDisplayName = (TextView) itemView.findViewById(R.id.displayName);
        this.mDisplayAttribute = (TextView) itemView.findViewById(R.id.displayAttribute);
        this.mDisplayQuantity = (TextView) itemView.findViewById(R.id.displayQuantity);
        this.mDisplayPrice = (TextView) itemView.findViewById(R.id.displayPrice);

        this.mDisplayImageView = itemView.findViewById(R.id.displayImageView);
        this.mDisplayBrandView = itemView.findViewById(R.id.displayBrandView);
        this.mDisplayNameView = itemView.findViewById(R.id.displayNameView);
        this.mDisplayAttributeView = itemView.findViewById(R.id.displayAttributeView);
        this.mDisplayQuantityView = itemView.findViewById(R.id.displayQuantityView);
        this.mDisplayPriceView = itemView.findViewById(R.id.displayPriceView);
    }
}

public interface Callback{
    void addArray(String[] a);
}

private Callback mCallback;

public void setListener(Callback callBack){
    mCallback=callBack;
}

private class MyOnClickListener implements View.OnClickListener {

    @Override
    public void onClick(final View v) {

        int itemPosition = recyclerView.getChildLayoutPosition(v) - 1;
        cursor.moveToPosition(itemPosition);

        String bString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_BRAND));
        String nString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_NAME));
        String aString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_ATTRIBUTE));
        String pString = cursor.getString(cursor.getColumnIndex(FlexpayContract.StockEntry.COLUMN_ITEM_PRICE));


        bString = bString + " ";
        aString = " " + aString;

        String description = bString + nString + aString;
        String [] array = {description, pString};
        mCallback.addArray(array);
    }
}

}

相关问题