由于带有 cursorloader 的 recyclerview,空白主 activity

Blank main activity due to recyclerview with a cursorloader

现在我正在尝试将 recyclerview 与游标加载器一起使用。根据我的研究,我将 cursorloader 包含在我的 recyclerview 适配器中。我不想将我的 SQLite 数据库数据放入数组列表中。现在看起来我的代码是正确的,但是当我加载应用程序时,我得到一个空白屏幕。谁能帮我看看我的代码中的错误?

这是我的适配器:

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

private CursorAdapter mCursorAdapter;
private Context mContext;
private ViewHolder holder;
Cursor prescriptionCursor;




public PrescriptionRecyclerAdapter(Context context, Cursor c) {
    mContext = context;
    prescriptionCursor = c;
    mCursorAdapter = new CursorAdapter(mContext, c, 0) {




        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            // Inflate the view here

                    View v = LayoutInflater.from(context)
                    .inflate(R.layout.recycle_item, parent, false);
                return v;

        }




        @Override
        public void bindView(View view, Context context, Cursor cursor) {



            // Extract data from the current store row and column
            int nameColumnIndex = cursor.getColumnIndex(PrescriptionContract.PrescriptionEntry.COLUMN_PRESCRIPTION_NAME);
            int amountColumnIndex = cursor.getColumnIndex(PrescriptionContract.PrescriptionEntry.COLUMN_PRESCRIPTION_AMOUNT);
            int durationColumnIndex = cursor.getColumnIndex(PrescriptionContract.PrescriptionEntry.COLUMN_PRESCRIPTION_FREQUENCY_DURATION);
            final int columnIdIndex = cursor.getColumnIndex(PrescriptionContract.PrescriptionEntry._ID);

            //Read the store attritubes from the Cursor for the current stores
            String name = cursor.getString(nameColumnIndex);
            String amount = cursor.getString(amountColumnIndex);
            String duration = cursor.getString(durationColumnIndex);
            String col = cursor.getString(columnIdIndex);

            // Populate fields with extracted properties
            holder.prescriptionName.setText(name);
            holder.prescriptionAmount.setText(amount);
            holder.prescriptionDays.setText(duration);


        }
    };



}

public static class ViewHolder extends RecyclerView.ViewHolder {

    public TextView prescriptionName;
    public TextView prescriptionAmount;
    public TextView prescriptionDays;
    final public Button prescriptionButton;

    public ViewHolder(View itemView) {
        super(itemView);
        // Find fields to populate in inflated template
        prescriptionName = (TextView) itemView.findViewById(R.id.name);
        prescriptionAmount = (TextView) itemView.findViewById(R.id.amountlist);
        prescriptionDays = (TextView) itemView.findViewById(R.id.daysList);
        prescriptionButton = itemView.findViewById(R.id.scheduleButton);

    }
}

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

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

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // Passing the binding operation to cursor loader
    mCursorAdapter.getCursor().moveToPosition(position);
    mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Passing the inflater job to the cursor-adapter
    View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
    holder = new ViewHolder(v);
    return holder;
}
}

这是我的展示activity。

 public class DisplayActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
private static final int PRESCRIPTION_LOADER = 0;
PrescriptionRecyclerAdapter mCursorAdapter;
private RecyclerView.LayoutManager mLayoutManager;





@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(DisplayActivity.this, EditorActivity.class);
            startActivity(intent);
        }
    });

    RecyclerView prescriptionRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    mLayoutManager = new LinearLayoutManager(getApplicationContext());
    prescriptionRecyclerView.setLayoutManager(mLayoutManager);


    mCursorAdapter = new PrescriptionRecyclerAdapter(this, null);
    prescriptionRecyclerView.setAdapter(mCursorAdapter);


    //Kick off the loader
    getLoaderManager().initLoader(PRESCRIPTION_LOADER,null,this);

}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_display, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // User clicked on a menu option in the app bar overflow menu
    switch (item.getItemId()) {
        // Respond to a click on the "Delete all entries" menu option
        case R.id.action_delete_all_entries:
            deleteAllPrescriptions();
            return true;

    }

    return super.onOptionsItemSelected(item);
}

/**
 * Helper method to delete all items in the database.
 */
private void deleteAllPrescriptions() {
    int rowsDeleted = getContentResolver().delete(PrescriptionEntry.CONTENT_URI, null, null);
    Log.v("CatalogActivity", rowsDeleted + " rows deleted from prescription database");
}

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    // Since the editor shows all store attributes, define a projection that contains
    // all columns from the store table
    String[] projection = {
            PrescriptionEntry._ID,
            PrescriptionEntry.COLUMN_PRESCRIPTION_NAME,
            PrescriptionEntry.COLUMN_PRESCRIPTION_AMOUNT,
            PrescriptionEntry.COLUMN_PRESCRIPTION_FREQUENCY_HOURS,
            PrescriptionEntry.COLUMN_PRESCRIPTION_FREQUENCY_TIMES,
            PrescriptionEntry.COLUMN_PRESCRIPTION_FREQUENCY_DURATION,
            PrescriptionEntry.COLUMN_PRESCRIPTION_REFILL,
            PrescriptionEntry.COLUMN_PRESCRIPTION_EXPIRATION,
            PrescriptionEntry.COLUMN_PRESCRIPTION_PHARMACIST_NAME,
            PrescriptionEntry.COLUMN_PRESCRIPTION_PHARMACIST_NUMBER,
            PrescriptionEntry.COLUMN_PRESCRIPTION_PHYSICIAN_NAME,
            PrescriptionEntry.COLUMN_PRESCRIPTION_PHYSICIAN_NUMBER};

    // This loader will execute the ContentProvider's query method on a background thread
    return new CursorLoader(this,   // Parent activity context
            PrescriptionEntry.CONTENT_URI,         // Query the content URI for the current store
            projection,             // Columns to include in the resulting Cursor
            null,                   // No selection clause
            null,                   // No selection arguments
            null);                  // Default sort order
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    mCursorAdapter.swapCursor(data);
}



@Override
public void onLoaderReset(Loader<Cursor> loader) {
    mCursorAdapter.swapCursor(null);
}



}

我想我明白了你的问题。在 onLoadFinished 方法中获得新的 Cursor 后,您正在调用 PrescriptionRecyclerAdapterswapCursor() 方法,此方法正在更新 prescriptionCursor 游标引用。没关系。但是更新 prescriptionCursor 不会影响您的 CursorAdapter。你实际上依赖于CursorAdapter。所以你必须更新 CursorAdapterCursor。因为您的 mCursorAdapter 仍然持有您在构造函数中提供的 Cursor 的旧引用。

所以使用这个方法来更新游标引用mCursorAdapter.swapCursor(prescriptionCursor)

public Cursor swapCursor(Cursor cursor) {
  if (prescriptionCursor == cursor) {
    return null;
  }

  Cursor oldCursor = prescriptionCursor;
  this.prescriptionCursor = cursor;

  if (cursor != null) {
    this.notifyDataSetChanged();
    // update your Cursor for CursorAdapter
    mCursorAdapter.swapCursor(prescriptionCursor);
  }

  return oldCursor;
}

我认为您通过维护两个适配器使其变得复杂。您可以将 RecyclerView.AdapterListCursor 一起使用。没有必要让它变得复杂。

希望对您有所帮助。让我知道它可以解决您的问题。