2017-03-07 273 views
-2

我一直在试图找出如何使RecyclerView适配器工作,从数据库可点击图片。当图像被点击时,我的应用总是崩溃,出现“android.database.CursorIndexOutOfBoundsException:索引4请求,大小为4”的错误。当我向数据库添加更多项目时,错误中的索引也会增加。请任何帮助,将不胜感激。请参阅下面的代码片段。 `公共类SelectItemRecycleViewAdapter扩展RecyclerView.Adapter {RecyclerView适配器没有返回正确的光标位置

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; 

`

回答

0

错误是在下面的代码,它总是返回加1个指数,因为你写cursor.getCount()+1

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

替换代码:

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

谢谢你们。我已经尝试了两种解决方案而没有改进。 – Akpome

+0

谢谢,@Caspain,我试过 public int getItemCount(){ return(cursor.getCount()); } 没有改进。 – Akpome

+0

谢谢@Asif。我试过public int getItemCount(){ return(cursor == null)? 0:cursor.getCount(); }也没有imrpovement。 – Akpome

0
@Override 
public int getItemCount() { 
return (cursor.getCount()); 
} 
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); 
    } 
} 

}