我正在开展一个包含Recyclerview
和Cursorloader
的项目,当用户点击recyclerview
中的项目时,它应该从项目中获取数据并开始新的Activity
但相反,它给了我一个例外
Attempt to invoke interface method 'boolean android.database.Cursor.moveToPosition(int)' on a null object reference
我的适配器:
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并在项目位置获得光标。
谢谢
答案 0 :(得分:1)
您没有将光标设置为只在onBindViewHolder方法中设置的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());
viewHolder.cursor = cursor;
NumberFormat currency = addLog.changeamount();
viewHolder.mAmount.setText(currency.format(personDetails.getAmount()));
}
并且不要打电话
cursor.moveToPosition(position);
在OnClick方法中。
我更喜欢在onBindViewHolder方法中实现OnClickListner方法而不是在viewHolder类中。