Los*_*ppy 126 android simplecursoradapter android-recyclerview
目前没有可用的RecyclerView.Adapter的默认实现.
可能正式发布,谷歌将添加它.
由于不存在用于支持CursorAdapter与RecyclerView当前,如何才能使用RecyclerView同一个数据库?有什么建议 ?
小智 100
如果你正在运行一个查询CursorLoader,你想RecyclerView的不是ListView.
您可以在RecyclerView中尝试我的CursorRecyclerViewAdapter:CursorAdapter
nbt*_*btk 86
我的解决方案是在recyclerView.Adapter实现中保存CursorAdapter成员.然后传递创建新视图的所有处理并将其绑定到游标适配器,如下所示:
public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.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;
Context mContext;
public MyRecyclerAdapter(Context context, Cursor c) {
mContext = context;
mCursorAdapter = new CursorAdapter(mContext, c, 0) {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// Inflate the view here
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Binding operations
}
};
}
public static class ViewHolder extends RecyclerView.ViewHolder {
View v1;
public ViewHolder(View itemView) {
super(itemView);
v1 = itemView.findViewById(R.id.v1);
}
}
@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.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);
return new ViewHolder(v);
}
}
Run Code Online (Sandbox Code Playgroud)
Pir*_*App 49
既然你的问题是"如何使用RecyclerView数据库"而你并不具体说明你是否想要SQLite或其他任何东西RecyclerView,我会给你一个非常优化的解决方案.我将使用Realm作为数据库,让你显示你的内部的所有数据RecyclerView.它也具有异步查询支持,无需使用Loaders或AsyncTask.
步骤1
为Realm添加gradle依赖项,可在此处找到最新版本的依赖项
第2步
创建你的模型类,例如,让我们说一些简单的东西,比如Data有两个字段,RecyclerView一行显示在行内,一个时间戳将用作itemId,允许RecyclerView动画项目.请注意,我RealmObject在下面进行了扩展,因为您的Data类将作为表存储,并且所有属性都将存储为该表的列Data.我已将数据文本标记为我的主键,因为我不希望多次添加字符串.但如果你喜欢重复,那么将时间戳作为@PrimaryKey.您可以拥有一个没有主键的表,但如果您在创建后尝试更新该行,则会导致问题.Realm不支持撰写此答案时的复合主键.
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class Data extends RealmObject {
@PrimaryKey
private String data;
//The time when this item was added to the database
private long timestamp;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}
Run Code Online (Sandbox Code Playgroud)
第3步
创建一个单行应该如何出现的布局RecyclerView.我们内部单个行项目的布局Adapter如下
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@android:color/white"
android:padding="16dp"
android:text="Data"
android:visibility="visible" />
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)
请注意,FrameLayout即使我有TextView内部,我也保持了root用户身份.我计划在这个布局中添加更多项目,因此现在变得灵活:)
第4步
创建您的RecyclerView.Adapter实现.在这种情况下,数据源对象是一个特殊的对象RealmResults,它基本上是一个LIVE ArrayList,换句话说,当你的表中添加或删除项时,这个RealmResults对象会自动更新.
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import io.realm.Realm;
import io.realm.RealmResults;
import slidenerd.vivz.realmrecycler.R;
import slidenerd.vivz.realmrecycler.model.Data;
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.DataHolder> {
private LayoutInflater mInflater;
private Realm mRealm;
private RealmResults<Data> mResults;
public DataAdapter(Context context, Realm realm, RealmResults<Data> results) {
mRealm = realm;
mInflater = LayoutInflater.from(context);
setResults(results);
}
public Data getItem(int position) {
return mResults.get(position);
}
@Override
public DataHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.row_data, parent, false);
DataHolder dataHolder = new DataHolder(view);
return dataHolder;
}
@Override
public void onBindViewHolder(DataHolder holder, int position) {
Data data = mResults.get(position);
holder.setData(data.getData());
}
public void setResults(RealmResults<Data> results) {
mResults = results;
notifyDataSetChanged();
}
@Override
public long getItemId(int position) {
return mResults.get(position).getTimestamp();
}
@Override
public int getItemCount() {
return mResults.size();
}
public void add(String text) {
//Create a new object that contains the data we want to add
Data data = new Data();
data.setData(text);
//Set the timestamp of creation of this object as the current time
data.setTimestamp(System.currentTimeMillis());
//Start a transaction
mRealm.beginTransaction();
//Copy or update the object if it already exists, update is possible only if your table has a primary key
mRealm.copyToRealmOrUpdate(data);
//Commit the transaction
mRealm.commitTransaction();
//Tell the Adapter to update what it shows.
notifyDataSetChanged();
}
public void remove(int position) {
//Start a transaction
mRealm.beginTransaction();
//Remove the item from the desired position
mResults.remove(position);
//Commit the transaction
mRealm.commitTransaction();
//Tell the Adapter to update what it shows
notifyItemRemoved(position);
}
public static class DataHolder extends RecyclerView.ViewHolder {
TextView area;
public DataHolder(View itemView) {
super(itemView);
area = (TextView) itemView.findViewById(R.id.area);
}
public void setData(String text) {
area.setText(text);
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我正在调用notifyItemRemoved删除发生的位置但是我没有调用,notifyItemInserted或者notifyItemRangeChanged因为没有直接的方法知道项目被插入到数据库中的位置,因为Realm条目没有以有序的方式存储.RealmResults每当从数据库添加,修改或删除新项目时,对象都会自动更新,因此我们notifyDataSetChanged在添加和插入批量条目时进行调用.在这一点上,你可能担心,因为你拨打的不会被触发动画notifyDataSetChanged到位的notifyXXX方法.这正是我让getItemId方法从结果对象返回每一行的时间戳的原因.notifyDataSetChanged如果您调用setHasStableIds(true)然后覆盖getItemId以提供除位置之外的其他内容,则动画分两步实现.
第5步
让我们添加RecyclerView到我们Activity或Fragment.就我而言,我正在使用Activity.包含它的布局文件RecyclerView非常简单,看起来像这样.
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/text_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
Run Code Online (Sandbox Code Playgroud)
我已经添加了一个,app:layout_behavior因为我RecyclerView进入了一个CoordinatorLayout我没有在这个答案中发布的简洁.
第6步
构造RecyclerView代码并提供所需的数据.在里面创建并初始化一个Realm对象onCreate并将其关闭,onDestroy就像关闭一个SQLiteOpenHelper实例一样.在最简单的onCreate内部,Activity看起来像这样.这种initUi方法是所有魔法发生的地方.我在里面打开一个Realm实例onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRealm = Realm.getInstance(this);
initUi();
}
private void initUi() {
//Asynchronous query
RealmResults<Data> mResults = mRealm.where(Data.class).findAllSortedAsync("data");
//Tell me when the results are loaded so that I can tell my Adapter to update what it shows
mResults.addChangeListener(new RealmChangeListener() {
@Override
public void onChange() {
mAdapter.notifyDataSetChanged();
Toast.makeText(ActivityMain.this, "onChange triggered", Toast.LENGTH_SHORT).show();
}
});
mRecycler = (RecyclerView) findViewById(R.id.recycler);
mRecycler.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new DataAdapter(this, mRealm, mResults);
//Set the Adapter to use timestamp as the item id for each row from our database
mAdapter.setHasStableIds(true);
mRecycler.setAdapter(mAdapter);
}
Run Code Online (Sandbox Code Playgroud)
请注意,在第一步中,我查询Realm Data,以异步方式向我提供类中的所有对象,这些对象按其变量名称data data排序.这给了我一个RealmResults在我设置的主线程上有0项的对象Adapter.我添加了一个RealmChangeListener通知,当数据从后台线程完成加载时我会通知notifyDataSetChanged我Adapter.我还调用setHasStableIds了true,让RecyclerView.Adapter实现跟踪添加,删除或修改的项目.在onDestroy我Activity关闭的领域实例
@Override
protected void onDestroy() {
super.onDestroy();
mRealm.close();
}
Run Code Online (Sandbox Code Playgroud)
这个方法initUi里面可以叫onCreate你的Activity或者onCreateView或onViewCreated你的Fragment.请注意以下事项.
第7步
BAM!里面你从数据库中有数据RecyclerViewasynchonously不装CursorLoader,CursorAdapter,SQLiteOpenHelper用动画.此处显示的GIF图像有点滞后,但是当您添加项目或删除它们时会发生动画.
| 归档时间: |
|
| 查看次数: |
83704 次 |
| 最近记录: |