我一直在试图弄清楚如何使用来自数据库的可点击图像来使用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;
`
答案 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);
}
}
}