update - recyclerview android studio ejemplo
¿Cómo actualizar RecyclerView en los cambios en los conjuntos de datos? (0)
Estoy usando ActiveAndroid ORM y UltimateRecyclerView en mi aplicación Android. No sé cómo mostrar una información en una lista usando estas bibliotecas populares. Lo sé, los datos se guardan en la base de datos correctamente. Utilizando el siguiente método, estoy obteniendo un cursor para los datos que quiero mostrar.
public Cursor eventsCursor() {
// `Event` is an ActiveAndroid model class
String query = new Select()
.from(Event.class)
.orderBy("time")
.toSql();
return ActiveAndroid.getDatabase().rawQuery(query, null);
}
Escribí mi implementación RecyclerView.Adapter<VH>
( EventCursorRecyclerAdapter
) compatible con UltimateViewAdapter, que contiene un miembro CursorAdapter para trabajar con la base de datos (el código se basa en esta solución ). No hay ContentObservers en ActiveAndroid ( problema n. ° 3 ), así que registro un observador en ContentProvider durante la inicialización. La inicialización se ve así:
Clase de Fragmento
protected UltimateRecyclerView listView;
private AbstractCursorRecyclerAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
cursor = eventsCursor();
cursor.setNotificationUri(getActivity().getContentResolver(),
ContentProvider.createUri(Event.class, null));
adapter = new EventCursorRecyclerAdapter(getActivity(), cursor, R.layout.list_item_event);
getActivity().getSupportLoaderManager().initLoader(0, savedInstanceState, this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/* ... */
// Configure RecyclerView
listView.setLayoutManager(new LinearLayoutManager(getActivity()));
listView.setAdapter(adapter);
}
Utilicé ContentProvider de ActiveAndroid ( documentos ) para crear URI para CursorLoader:
AndroidManifest.xml
<application ...>
<provider
android:name="com.activeandroid.content.ContentProvider"
android:authorities="com.activeandroid.content.ContentProvider"
android:exported="false" />
...
</application>
LoaderManager.LoaderCallbacks<T>
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle cursor) {
return new CursorLoader(
MyFragment.this.getActivity(),
ContentProvider.createUri(Event.class, null),
null, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.asCursorAdapter().changeCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.asCursorAdapter().changeCursor(null);
}
Cuando detecto un cambio en el conjunto de datos, llamo
MyFragment.this.getActivity().getContentResolver().notifyChange(
ContentProvider.createUri(Event.class, modifiedId), null);
No sé por qué, pero no está funcionando. No se muestran datos, sin errores registrados.
ACTUALIZAR Código completo del adaptador (recuerda a un matryoshka) .
EventCursorAdapter
public class EventCursorAdapter extends CursorAdapter {
private final int itemLayoutId;
private final LayoutInflater inflater;
/**
* @param itemLayoutId List item layout
*/
public EventCursorAdapter(Context context, Cursor cursor, @LayoutRes int itemLayoutId) {
super(context, cursor, 0);
this.itemLayoutId = itemLayoutId;
this.inflater = LayoutInflater.from(context);
}
/**
* It is used to inflate a new view and return it.
*
* @return a new View
*/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return inflater.inflate(itemLayoutId, parent, false);
}
/**
* Bind all data to a given view (such as setting the text on a TextView).
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
EventItemViewHolder holder = (EventItemViewHolder) view.getTag();
// Extract properties and populate fields
holder.tvName.setText(cursor.getString(holder.nameIndex));
/* ... */
}
}
EventCursorRecyclerAdapter
public final class EventCursorRecyclerAdapter extends AbstractCursorRecyclerAdapter {
/**
* @param itemLayoutId List item layout
*/
public EventCursorRecyclerAdapter(Context context, Cursor cursor, @LayoutRes int itemLayoutId) {
super(new EventCursorAdapter(context, cursor, itemLayoutId), context);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// Passing the binding operation to cursor loader
cursorAdapter.bindView(holder.itemView, context, cursorAdapter.getCursor());
}
@Override
public UltimateRecyclerviewViewHolder onCreateViewHolder(ViewGroup parent) {
// Passing the inflater job to the cursor-adapter
View v = cursorAdapter.newView(context, cursorAdapter.getCursor(), parent);
return new EventItemViewHolder(v, cursorAdapter.getCursor());
}
/**
* See ViewHolder Pattern.
*/
public final class EventItemViewHolder extends UltimateRecyclerviewViewHolder {
// Column indices
int nameIndex, timeIndex /*, ...*/;
// Views
TextView tvName, tvTime;
/* ... */
public EventItemViewHolder(View view, Cursor cursor) {
super(view);
// Find fields to populate in inflated template
tvName = (TextView) view.findViewById(R.id.tv_event_name);
tvTime = (TextView) view.findViewById(R.id.tv_event_time);
/* ... */
// Find columns
nameIndex = cursor.getColumnIndexOrThrow("name");
timeIndex = cursor.getColumnIndexOrThrow("time");
}
}
}
AbstractCursorRecyclerAdapter
public abstract class AbstractCursorRecyclerAdapter extends UltimateViewAdapter {
// 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
protected final CursorAdapter cursorAdapter;
protected final Context context;
public AbstractCursorRecyclerAdapter(CursorAdapter cursorAdapter, Context context) {
setHasStableIds(true);
this.cursorAdapter = cursorAdapter;
this.context = context;
}
@Override
public int getAdapterItemCount() {
return cursorAdapter.getCount();
}
@Override
public long getItemId(int position) {
return cursorAdapter.getItemId(position);
}
private Model getItem(int position) {
return (Model) cursorAdapter.getItem(position);
}
public CursorAdapter asCursorAdapter() {
return cursorAdapter;
}
public void remove(int position) {
Model entity = getItem(position);
if (entity != null) {
entity.delete();
notifyDataSetChanged();
}
}
}
Dependencias de Gradle
compile ''com.michaelpardo:activeandroid:3.1.0-SNAPSHOT''
compile ''com.marshalchen.ultimaterecyclerview:library:0.3.2''