2015-01-15 14 views
28

私のアプリでRecyclerViewのサポートを使用していますが、私は最も奇妙なことを見ています。私はスクロールするためにタッチするまで項目を表示しません。それから、突然、RecyclerViewが自動的に生成されます。アダプターのバッキングリストが作成され、onCreatViewHolderとonBindViewHolderがタッチイベントまで呼び出されないことを確認しました。ここでサポートRecyclerViewは、タッチするまで何も表示しません。

は私が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); 
    } 

は、ここに私のアダプタの要旨です:私はrecyclerviewを使用してい

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

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


} 

は、ここでレイアウトファイルです-v7:バージョン4.4.4のMoto Xで動作する21.0.3。

EDIT: スムーズスクロールonPostExecuteの終わりには、問題を解決しているようだ:

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

はあなたがサポートライブラリ22.2.1を試してみましたか?多くのバグが修正されました。 –

+3

あなたの 'EDIT'は答えが必要です: –

+0

うわー...このアンドロイドバグはありますか?それでもまだ起きている – Zyoo

答えて

-2

あなたがRecyclerView.Adapterの正しい通知方法を呼び出していないので、それが最も可能性が高いです。これまでListAdapterで使用していたものよりもはるかにきめ細かなインターフェースがあります。たとえば、addAll()ではnotifyDataSetChangedの代わりにnotifyItemRangeInserted(oldConversationsSize, conversations.size())を呼び出す必要があります。

+3

あなたはnotifyDataSetChange UIを更新しないことをお勧めですか? – WindsurferOak

+0

notifyItemRangeInserted(oldConversationsSize、conversations.size())は問題を解決しませんでした。 –

-1

リサイクルビューが再描画されるように、UIスレッドでonPostExecuteで行う作業を実行する必要があります。そのため、スムーズなスクロールはUIスレッドで実行されているため、ビューが再描画されるためです。

+2

onPostExecuteはメインスレッドで実行されます。 – WindsurferOak

4

RxJavaとRetrofitを使用して他の誰かがこの問題を抱えている場合は、サブスクライブする前に.observeOn(AndroidSchedulers.mainThread())演算子をメソッドチェーンに追加してこの問題を解決しました。私はこれがデフォルトで世話をされたことを読んだので、明示的に必要ではないが、私はそうは思わない。お役に立てれば。

例:

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

subscribeメソッドがバックグラウンドスレッドで呼び出されているためです。それがその根本的な原因です。 – ImMathan

+0

正しい。これをよりよく説明するために、チェーンに.subscribeOn()を追加しました。 – saganaut

関連する問題