In all the working examples of utilizing CBL Android and RecyclerView I see the LiveQuery employed as such:
public class MyTaskListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
OnItemClickListener mItemClickListener;
OnItemLongClickListener mItemLongClickListener;
public LiveQuery query;
public QueryEnumerator enumerator;
Context context;
public MyTaskListAdapter(Context context, LiveQuery query) {
this.context = context;
this.query = query;
query.addChangeListener(new LiveQuery.ChangeListener() {
@Override
public void changed(final LiveQuery.ChangeEvent changeEvent) {
((Activity) MyTaskListAdapter.this.context).runOnUiThread(new Runnable() {
@Override
public void run() {
enumerator = changeEvent.getRows();
notifyDataSetChanged();
}
});
}
});
query.start();
}
The method works well in keeping the view updated when I do any item add/delete/update operations. However, it appears to have one usage flaw in that calling notifyDataSetChanged() results in the default item animations from firing (i.e. notifyItemInserted(), notifyItemRemoved()) calls have no effect). So the problem is that when any item is deleted or added it shows up instantly and it is a bit jarring to the user instead of folding in/out of view gracefully which would occur if the default itemAnimator was firing.
So this appears to me as a design pattern problem. My knowledge of working with Query, LiveQuery is limited and I struggle with it as I try to figure out what would work here. Maybe taking out the LiveQuery and instead manually refresh the view with a standard query?? Here are some additional pieces of my code to help you get a better picture of what I currently have and if you can offer some advice or code examples it would be greatly appreciated. This is one of the last few pieces I need to nail before releasing the app.
Recycler Initialization:
public static Query allTasksQuery(Database database) {
com.couchbase.lite.View view = database.getView(VIEW_NAME);
if (view.getMap() == null) {
Mapper map = new Mapper() {
@Override
public void map(Map<String, Object> document, Emitter emitter) {
if (DOC_TYPE_EMAIL.equals(document.get("type"))) {
emitter.emit(document.get("created_at"), document);
}
if (DOC_TYPE_SMS.equals(document.get("type"))) {
emitter.emit(document.get("created_at"), document);
}
}
};
view.setMap(map, "2");
}
Query query = view.createQuery();
query.setDescending(true);
return query;
}
public static MyTaskListFragment newInstance(String param1, String param2) {
MyTaskListFragment fragment = new MyTaskListFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public MyTaskListFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_list_main, container, false);
mRecyclerView = (RecyclerView) v.findViewById(R.id.my_recycler_view);
LiveQuery query = allTasksQuery(((MyApplication) getActivity().getApplication()).getDatabase()).toLiveQuery();
mTaskListAdapter = new MyTaskListAdapter(getActivity(), query);
return v;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView.setAdapter(mTaskListAdapter);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mTaskListAdapter.SetOnItemClickListener(new MyTaskListAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, Document task) {
Log.d("TAG", "Inside MyTaskListFragment SetOnItemClickListener");
String docID = (String) task.getProperty("_id");
String taskType = (String) task.getProperty("type");
mListener.onTaskInteraction(view, docID, taskType, false);
}
});
mTaskListAdapter.SetOnItemLongClickListener(new MyTaskListAdapter.OnItemLongClickListener() {
@Override
public void onLongItemClick(View view, Document task) {
Log.d("TAG", "Inside MyTaskListFragment SetOnItemLONGClickListener");
String docID = (String) task.getProperty("_id");
String taskType = (String) task.getProperty("type");
mListener.onTaskInteraction(view, docID, taskType, true);
}
});
}