gpt4 book ai didi

Android Recyclerview Onclicklistener 不适用于 Cursor

转载 作者:行者123 更新时间:2023-11-29 01:19:52 30 4
gpt4 key购买 nike

我正在开发一个包含 RecyclerviewCursorloader 的项目,当用户点击 recyclerview 中的项目时,它应该从中获取数据item 并开始新的 Activity。但是它给了我一个异常(exception)尝试在空对象引用上调用接口(interface)方法“boolean android.database.Cursor.moveToPosition(int)”

我的适配器:

public class Mainrow_Adapter extends CursorRecyclerViewAdapter<Mainrow_Adapter.ViewHolder>
{
Context context;
Cursor cursor;
public Mainrow_Adapter(Context context, Cursor cursor)
{
super(context, cursor);
this.cursor = cursor;
this.context = context;
}
@Override
public Mainrow_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.mainrow_layout,parent,false);
ViewHolder viewHolder = new ViewHolder(view,context,cursor);
return viewHolder;
}
@Override
public void onBindViewHolder(Mainrow_Adapter.ViewHolder viewHolder, final Cursor cursor)
{
PersonDetails personDetails = PersonDetails.from(cursor);
AddLog addLog = new AddLog();
viewHolder.mName.setText(personDetails.getName());
NumberFormat currency = addLog.changeamount();
viewHolder.mAmount.setText(currency.format(personDetails.getAmount()));
}

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
TextView mName,mAmount;

Context context;
Cursor cursor;
public ViewHolder(View itemView,Context context,Cursor cursor) {
super(itemView);
this.context = context;
this.cursor = cursor;
itemView.setOnClickListener(this);
mName = (TextView)itemView.findViewById(R.id.mainrowname);
mAmount = (TextView)itemView.findViewById(R.id.mainrowAmount);
}

@Override
public void onClick(View view) {
int position = this.getAdapterPosition();
cursor.moveToPosition(position);
String name = cursor.getString(1);String mobile = cursor.getString(2);
String city = cursor.getString(3);String amount = cursor.getString(5);
Intent intent = new Intent(context,ViewLog.class);
intent.putExtra("Name",name);intent.putExtra("Mobile",mobile);
intent.putExtra("City",city);intent.putExtra("Amount",amount);
context.startActivity(intent);
Toast.makeText(context,String.valueOf(position), Toast.LENGTH_SHORT).show();
}
}
}

光标适配器:

    public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {

private Context mContext;

private Cursor mCursor;

private boolean mDataValid;

private int mRowIdColumn;

private DataSetObserver mDataSetObserver;

public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
mContext = context;
mCursor = cursor;
mDataValid = cursor != null;
mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
mDataSetObserver = new NotifyingDataSetObserver();
if (mCursor != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
}

public Cursor getCursor() {
return mCursor;
}

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

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

@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(true);
}

public abstract void onBindViewHolder(VH viewHolder, Cursor cursor);

@Override
public void onBindViewHolder(VH viewHolder, 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(viewHolder, mCursor);
}

/**
* Change the underlying cursor to a new cursor. If there is an existing cursor it will be
* closed.
*/
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}

/**
* Swap in a new Cursor, returning the old Cursor. Unlike
* {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
* closed.
*/
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
final Cursor oldCursor = mCursor;
if (oldCursor != null && mDataSetObserver != null) {
oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (mCursor != null) {
if (mDataSetObserver != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
return oldCursor;
}

private class NotifyingDataSetObserver extends DataSetObserver {
@Override
public void onChanged() {
super.onChanged();
mDataValid = true;
notifyDataSetChanged();
}

@Override
public void onInvalidated() {
super.onInvalidated();
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
}

}

如果你们中的任何人知道比这更好的解决方案来启动 onclicklistenter 并在 Items 位置获取光标,我将不胜感激。

谢谢

最佳答案

您没有将光标设置到您的 viewHolder 上,只是在 onBindViewHolder 方法中设置

@Override
public void onBindViewHolder(Mainrow_Adapter.ViewHolder viewHolder, final Cursor cursor)
{
PersonDetails personDetails = PersonDetails.from(cursor);
AddLog addLog = new AddLog();
viewHolder.mName.setText(personDetails.getName());
viewHolder.cursor = cursor;
NumberFormat currency = addLog.changeamount();
viewHolder.mAmount.setText(currency.format(personDetails.getAmount()));
}

不要打电话

cursor.moveToPosition(position);

在您的 OnClick 方法中。

而且我更喜欢在 onBindViewHolder 方法中而不是在 viewHolder 类中实现您的 OnClickListner 方法。

关于Android Recyclerview Onclicklistener 不适用于 Cursor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37509486/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com