Pregunta Soporte RecyclerView no muestra nada hasta que se tocó


Estoy usando el soporte RecyclerView en mi aplicación, y veo lo más extraño. No muestra ningún elemento hasta que toco para desplazarse. Entonces, de repente, el RecyclerView se rellena solo. He verificado que la lista que respalda el adaptador está llena y que onCreatViewHolder y onBindViewHolder nunca se invocan hasta que se produce un evento táctil.

Así es como configuré la vista de reciclador:

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        Drawable divider = new ColorDrawable(ProfileInfo.getCurrentProfileColor());
        mInboxList.addItemDecoration(new DividerItemDecoration(getActivity(), divider, false));
        mInboxList.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
        mInboxList.setAdapter(new InboxAdapter(getActivity(), new ArrayList<Conversation>()));
        new AsyncTask<Void, Void, List<Conversation>{

              public List<Conversation> doInBackground(...){
                   //load the conversations
                   return conversations;
              }

              public void onPostExecute(List<Conversation> conversations){
                   ((InboxAdapter) mInboxList.getAdapter()).clear(false);
                   ((InboxAdapter) mInboxList.getAdapter()).addAll(conversations);

              }

        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }

Aquí hay una esencia de mi adaptador:

public class InboxAdapter extends RecyclerView.Adapter<InboxAdapter.ViewHolder> {
    List<Conversation> mConversations; //initialized in contructor

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = mInflater.inflate(R.layout.inbox_item, parent, false);
        ViewHolder holder = new ViewHolder(v);
        Log.d(LOG_TAG, "oncreateviewholder : " + viewType); //never called when I first bind the adapter
        return holder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        final Conversation item = mConversations.get(position);
        Log.d(LOG_TAG, "binding " + position);
        ...
    }

    @Override
    public int getItemCount() {
        Log.d(LOG_TAG, "item count: " + mConversations.size());
        return mConversations.size();
    }

    /**
     * Empties out the whole and optionally notifies
     */
    public void clear(boolean notify) {
        mConversations.clear();
        if (notify) {
            notifyDataSetChanged();
        }
    }

    public void addAll(List<Conversation> conversations) {
        mConversations.addAll(conversations);
        notifyDataSetChanged();
    }


}

Aquí está el archivo de diseño:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingTop="?attr/actionBarSize">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/lv_inbox"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        ></android.support.v7.widget.RecyclerView>
</RelativeLayout>

Estoy usando recyclerview-v7: 21.0.3 ejecutándose en un Moto X con la versión 4.4.4.

EDITAR: El desplazamiento suave al final de onPostExecute parece resolver el problema:

if (mInboxList.getAdapter().getItemCount() > 0) {
    mInboxList.smoothScrollToPosition(0);
}

32
2018-01-15 02:08


origen


Respuestas:


Si alguien más está teniendo este problema usando RxJava y Retrofit, resolví este problema agregando el .observeOn(AndroidSchedulers.mainThread()) operador en mi cadena de métodos antes de suscribirse. Había leído que esto se había solucionado de forma predeterminada, y por lo tanto no explícitamente necesario, pero supongo que no. Espero que esto ayude.

Ejemplo:

public void loadPhotos() {
    mTestPhotoService.mServiceAPI.getPhotos()
                                 .subscribeOn(Schedulers.io())
                                 .observeOn(AndroidSchedulers.mainThread())
                                 .subscribe(photoList -> mRecyclerActivity.OnPhotosLoaded(photoList));
}

7
2017-09-07 02:30



Tendría que ejecutar las cosas que hace en onPostExecute en el subproceso UI para que RecyclerView se vuelva a dibujar. Es por eso que el desplazamiento suave funciona porque se ejecuta en el subproceso de interfaz de usuario y, por lo tanto, hace que la vista se vuelva a dibujar.


-1
2017-07-01 19:17



Es más probable porque no está llamando a los métodos de notificación correctos de RecyclerView.Adapter. Tiene una interfaz mucho más granular para esto de la que tenía anteriormente en ListAdapters. Por ejemplo, en addAll () debe llamar notifyItemRangeInserted(oldConversationsSize, conversations.size()) en lugar de notifyDataSetChanged


-2
2018-01-19 16:03