Reputation: 63
I'm trying to implement an adapter for a Recyclerview
with the use of CusrorAdapter
as below as suggested in the one of the solutions here.
I am new to Android and I don't quite know how I should override CursorAdapter
's newView method and bindView
method. Also I am guessing that mine adapter will have multiple variables in ViewHolder
instead of one (View v1) as there are several textViews
in my layout file, but I just don't know how they all fit in in the code.
public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.ViewHolder {
// PATCH: Because RecyclerView.Adapter in its current form doesn't natively support
// cursors, we "wrap" a CursorAdapter that will do all teh 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.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);
}
}
Upvotes: 3
Views: 4436
Reputation: 63
Somehow I managed to get it working although I don't understand how it works in details. Basically I added a ViewHolder
variable as a class variable and change some parts of the code. The solution looks something like this when you have 2 TextView
items (name
and date
) in your layout file called row.xml
:
public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.ViewHolder>{
// PATCH: Because RecyclerView.Adapter in its current form doesn't natively support
// cursors, we "wrap" a CursorAdapter that will do all teh job for us
private CursorAdapter mCursorAdapter;
private Context mContext;
private ViewHolder holder;
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
View v = LayoutInflater.from(context)
.inflate(R.layout.row_rv, parent, false);
return v;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Binding operations
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
String date = cursor.getString(cursor.getColumnIndexOrThrow("date"));
holder.tvName.setText(name);
holder.tvDate.setText(date);
}
};
}
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView tvName;
public TextView tvDate;
public ViewHolder(View itemView) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.name);
tvDate = (TextView) itemView.findViewById(R.id.date);
}
}
@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);
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;
}
}
If anyone knows why it works, please feel free to join in the discussion. Thanks.
Upvotes: 2
Reputation: 325
Instead of you create a ViewHolder with a View, you should create the ViewHolder with all the objects you have on the layout (all the elements you need). The layout view must be created (inflate) in method onCreateViewHolder.
Something like that:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
class ViewHolder extends RecyclerView.ViewHolder {
TextView textView1;
TextView textView2;
public ViewHolder(View itemView) {
super(itemView);
textView1 = (TextView) itemView.findViewById(R.id.textView1);
textView2 = (TextView) itemView.findViewById(R.id.textView2);
}
public void insertView(String result1, String result2) {
textView1.setText(result1);
textView2.setText(result2);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_name, parent, false);
RecyclerView.ViewHolder viewHolder = new ViewHolder(itemView);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ViewHolder) holder).insertView(results.get(position).getResult1(), results.get(position).getResult2());
}
@Override
public int getItemCount() {
return results.size();
}
}
You can use a ORMSugar for persistence. Still, if you have the possibility of access to the database outside the adapter it would be much better. You will get the necessary information from the database and pass that information to the adapter constructor.
If you need an example, just you have to tell me.
Upvotes: 0