Support RecyclerView doesn't show anything until touched

匿名 (未验证) 提交于 2019-12-03 02:50:02

问题:

I'm using the support RecyclerView in my app, and I see the most bizarre thing. It doesn't display any items until I touch to scroll. Then, all of a sudden, the RecyclerView populates itself. I have verified that the list backing the adapter is populated, and that onCreatViewHolder and onBindViewHolder are never called until a touch event.

Here's how I set up the recyclerview:

    @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);      } 

Here's a gist of my adapter:

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();     }   } 

Here's the layout file:

<?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> 

I'm using recyclerview-v7:21.0.3 running on a Moto X with version 4.4.4.

EDIT: Smooth scrolling at the end of the onPostExecute seems to resolve the issue:

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

回答1:

If anyone else is having this issue using RxJava and Retrofit, I solved this issue by adding the .observeOn(AndroidSchedulers.mainThread()) operator into my method chain before subscribing. I had read this was taken care of by default, and thus not explicitly necessary, but I guess not. Hope this helps.

Example:

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


回答2:

You would have to run the stuff you do in onPostExecute on the UI thread so that the RecyclerView gets redrawn. That's why the smooth scrolling works, because that is running on the UI thread and therefore causing the view to redraw.



回答3:

It's most likely because you're not calling the correct notification methods of RecyclerView.Adapter. You have a much more granular interface for this than you previously had in ListAdapters. For example, in addAll() you should call notifyItemRangeInserted(oldConversationsSize, conversations.size()) instead of notifyDataSetChanged



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!