Recyclerview +内容提供商+ CursorLoader

我在SQLite数据库中有一些数据。我有一个内容提供者将从数据库中获取数据。 现在的问题是我如何实现cursorLoader与recyclerview一起工作?

另外,任何人都可以解释为什么我们需要将数据从光标传输到一个对象来显示在listview / recyclerview而不是直接从光标?

例如,在自定义的cursorAdapter类中,

Person person = new Person(cursor.getString(cursor.getColumnIndexOrThrow(PERSON_NAME))); textview.setText = person.getName(); 

要么

 textview.setText = cursor.getString(cursor.getColumnIndexOrThrow(PERSON_NAME)); 

上述哪一种方法比较好?

在过去,我们曾经有过listview和gridview,现在看起来他们被合并成为回收站。 那么,我如何实现基于网格的recyclerview?

Solutions Collecting From Web of "Recyclerview +内容提供商+ CursorLoader"

一般来说,您应该尝试将视图和数据职责分开。 所以你需要从数据库中提取所有对象,然后设置一个Adapter,如下所示:

 public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private final List<Person> objectList = new ArrayList<>(); @Override public CustomAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) { final LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); return new ViewHolder(layoutInflater.inflate(R.layout.adapter_item, parent, false)); } @Override public void onBindViewHolder(final CustomAdapter.ViewHolder holder, final int position) { holder.bindItem(objectList.get(position)); } // Set the persons for your adapter public void setItems(final List<Person> persons) { objectList.addAll(persons); notifyDataSetChanged(); } @Override public int getItemCount() { return objectList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView mTextViewTitle; private Object mObject; public ViewHolder(final View itemView) { super(itemView); mTextViewTitle = (TextView) itemView.findViewById(R.id.view_item_textViewTitle); mTextViewTitle.setText(mObject.getText()); } private void bindItem(@NonNull final Person object) { mObject = object; } } } 

然后你可以通过以下方式将适配器绑定到RecyclerView:

 final CustomAdapter adapter = new CustomAdapter(); adapter.setItems(mPersons); mRecyclerView.setAdapter(); 

为了回答你的第二个问题(“过去,我们曾经有过listview和gridview,现在看起来他们被合并为recyclerview,那么我该如何实现一个基于grid的回收站?”):

将LayoutManager绑定到RecyclerView时,您可以决定使用哪一个:

 final LinearLayoutManager layoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(layoutManager); 

要么

 final GridLayoutManager layoutManager = new GridLayoutManager(this, COLUMN_SPAN_COUNT); mRecyclerView.setLayoutManager(layoutManager); 

有几个布局pipe理器。 在这里了解更多。

更新:你不必提前加载所有的项目,只需重命名setItems addItems,你很好去

有几个这样的Github gists /项目, 这显示了这样一个用例。

虽然你将会使用一个适配器,这个适配器是为游标适配器定制的,但是你可以像往常一样使用GridLayoutManager / LinearLayoutManager。

我认为你可以直接使用自定义CursorAdapterRecyclerView所以你不必将光标转换为ArrayList

 public class ProductListAdapter extends RecyclerView.Adapter<ProductListAdapter.ViewHolder> { // Because RecyclerView.Adapter in its current form doesn't natively // support cursors, we wrap a CursorAdapter that will do all the job // for us. CursorAdapter mCursorAdapter; Activity mContext; Random rnd; public ProductListAdapter(AppCompatActivity context, Cursor c) { mContext = context; rnd = new Random(); mCursorAdapter = new CursorAdapter(mContext, c, 0) { @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { // Inflate the view here LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); return inflater.inflate(R.layout.row_product_layout_grid, parent, false); } @Override public void bindView(View view, Context context, Cursor cursor) { String productName = cursor.getString(cursor.getColumnIndex(TProduct.PRODUCT_NAME)); // Binding operations ((TextView) view.findViewById(R.id.sub_product_name_text_view)).setText(productName); int color = Color.argb(200, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)); String url = "http://dummyimage.com/300/" + color + "/ffffff&text=" + (cursor.getPosition() + 1); Picasso .with(context) .load(url) .placeholder(R.mipmap.ic_launcher) // can also be a drawable .into((ImageView) view.findViewById(R.id.sub_product_image_view)); } }; } public void reQuery(Cursor c) { if (mCursorAdapter != null) { mCursorAdapter.changeCursor(c); mCursorAdapter.notifyDataSetChanged(); } } @Override public int getItemCount() { return mCursorAdapter.getCount(); } @Override public void onBindViewHolder(ViewHolder holder, int position) { // Passing the binding operation to cursor loader mCursorAdapter.getCursor().moveToPosition(position); //EDITED: added this line as suggested in the comments below, thanks :) mCursorAdapter.bindView(holder.view, 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); return new ViewHolder(v); } public static class ViewHolder extends RecyclerView.ViewHolder { View view; public ViewHolder(View itemView) { super(itemView); view = itemView.findViewById(R.id.product_row_card_view); } } } 

愿它对你有用。 🙂