2016-06-28 9 views
-1

私はウェブサイトからの画像を表示するアプリを開発中です。画像はすべて高さが異なり、表示されるビュー(ビューア)も同様です。RecyclerViewのデータセットを置き換える際の問題

フィルタを適用すると、前のデータセット(したがって現在表示されているもの)が直接削除されます。アダプタ。これが起こったことがアダプタに通知されます

final int removedSize = items.size(); 
items.clear(); 
notifyItemRangeRemoved(0, removedSize); 

これにより、古いアイテムが画面からアニメーション表示されます。アニメーションが終了したら、新しいデータセットを追加します。

RecyclerView attachedView; 

attachedView.getItemAnimator().isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() { // Add a listener to listen when the new items should be added 
      @Override 
      public void onAnimationsFinished() { 
       attachedView.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         addPhotosList(objects); 
         notifyItemRangeChanged(0, objects.size());        
         loading = false; 
         attachedView.requestLayout(); 
        } 
       },700); 
      } 
     }); 

これは、追加されたアイテムをアニメーション化します。 奇妙なことは、RecyclerViewが、すべてのアイテムを描画するときに、RecyclerViewがViewHolderの新しいディメンションを考慮しないように、ときどきRecyclerViewの内部にギャップが生じることです。さらに、アイテムのいくつかは、文字通りお互いの上に置かれ、好きなときは常に前景に点滅します。正しい位置に置かれたアイテムの上にあるアイテムは、そのギャップの内側に配置されるアイテムです。彼らはギャップに戻ることはありませんが、手動で項目セットを調べるとき、私は彼らがそこにいるはずであることに気付きました。

RecyclerViewはSwipeRefreshLayoutビューの子ですが、問題ではないと思います。

私はRecyclerViewに設定したパラメータの一部:

recents.setLayoutManager(layoutManager); 
recents.setHasFixedSize(false); 
recents.setItemViewCacheSize(100); 

レイアウトファイル内

android:animationCache="false" 
android:scrollingCache="false" 

私が間違って何をしているのですか?

私はすでにすべてのアニメーションが終了していることを確認するために、わずか0.7秒の遅延を追加しましたが、それはあまり役に立たないようです。

ItemAnimator:

@Override 
    public boolean animateAdd(RecyclerView.ViewHolder viewHolder) { 
     if (viewHolder.getItemViewType() != -8) { // ImageAdapter.ViewType.EMPTY = -8; 
      if (viewHolder.getLayoutPosition() > lastAddAnimatedItem) { 
       lastAddAnimatedItem++; 
       runEnterAnimation((ImageListView) viewHolder, viewHolder.getLayoutPosition()); 
       return false; 
      } 
     } 
     lastAddAnimatedItem = -6; 
     dispatchAddFinished(viewHolder); 
     return false; 
    } 

    @Override 
    public boolean animateRemove(RecyclerView.ViewHolder viewHolder) { 
     if (viewHolder.getItemViewType() != -8) { // ImageAdapter.ViewType.EMPTY = -8; 
      if (viewHolder.getLayoutPosition() > lastRemoveAnimatedItem) { 
       lastRemoveAnimatedItem++; 
       runExitAnimation((ImageListView) viewHolder, viewHolder.getLayoutPosition()); 
       return false; 
      } 
     } 

     lastRemoveAnimatedItem = -6; 
     dispatchRemoveFinished(viewHolder); 
     return false; 
    } 

    private void runEnterAnimation(final ImageListView holder, int position) { 
     final int screenHeight = Utils.getScreenHeight(holder.itemView.getContext()); 
     holder.itemView.setTranslationY(screenHeight + holder.itemView.getHeight()); 
     holder.itemView.animate() 
       .translationY(0) 
       .setStartDelay(150 + (20 * (position))) 
       .setInterpolator(new DecelerateInterpolator(3.f)) 
       .setDuration(700) 
       .setListener(new AnimatorListenerAdapter() { 
        @Override 
        public void onAnimationEnd(Animator animation) { 
         dispatchAddFinished(holder); 
        } 
       }) 
       .start(); 
    } 

    private void runExitAnimation(final ImageListView holder, int position) { 
     final int screenHeight = Utils.getScreenHeight(holder.itemView.getContext()); 
     holder.itemView.setTranslationY(0); 
     holder.itemView.animate() 
       .translationY(-screenHeight - holder.itemView.getHeight()) 
       .setStartDelay(Math.abs(20 * (position))) 
       .setInterpolator(new DecelerateInterpolator(3.f)) 
       .setDuration(700) 
       .setListener(new AnimatorListenerAdapter() { 
        @Override 
        public void onAnimationEnd(Animator animation) { 
         dispatchRemoveFinished(holder); 
        } 
       }) 
       .start(); 
    } 

EDIT:

画面上で最後の目に見えるアイテムが間違った場所に配置された後、それは、最初項目と思われます。

答えて

1

私は一週間以上のためにこの問題に戦ってきたが、私は解決策が見つかりました:

private void runEnterAnimation(final ImageListView holder, int position) { 
     final int screenHeight = Utils.getScreenHeight(holder.itemView.getContext()); 
     holder.itemView.setTranslationY(screenHeight); 
     holder.itemView.animate() 
       .translationY(0) 
       .setStartDelay(150 + (20 * (position))) 
       .setInterpolator(new DecelerateInterpolator(3.f)) 
       .setDuration(700) 
       .setListener(new AnimatorListenerAdapter() { 
        @Override 
        public void onAnimationEnd(Animator animation) { 
         dispatchAddFinished(holder); 
         holder.itemView.setTranslationY(0f); 
        } 
        @Override 
        public void onAnimationCancel(Animator animation){ 
         holder.itemView.setTranslationY(0f); 
        } 
       }) 
       .start(); 
    } 

お知らせonAnimationEndとonAnimationCancelコールバック内に新しい行:これに

変更runEnterAnimationをこれは、アイテムの翻訳が、常にアニメーションがアニメーション化されている所望の翻訳に設定されることを保証する。

これでrunExitAnimationを置き換えます

private void runExitAnimation(final ImageListView holder, int position) { 
     final int screenHeight = Utils.getScreenHeight(holder.itemView.getContext()); 
     holder.itemView.setTranslationY(0); 
     holder.itemView.animate() 
       .translationY(-screenHeight) 
       .setStartDelay(Math.abs(20 * (position))) 
       .setInterpolator(new DecelerateInterpolator(3.f)) 
       .setDuration(700) 
       .setListener(new AnimatorListenerAdapter() { 
        @Override 
        public void onAnimationEnd(Animator animation) { 
         dispatchRemoveFinished(holder); 
         holder.itemView.setTranslationY(-screenHeight); 
        } 
        @Override 
        public void onAnimationCancel(Animator animation){ 
         holder.itemView.setTranslationY(-screenHeight); 
        } 
       }) 
       .start(); 
    } 

はこれでendAnimationを置き換えます

@Override 
    public void endAnimation(RecyclerView.ViewHolder item) { 
     super.endAnimation(item); 
     item.itemView.setTranslationY(0f); 
    } 

このホルダーは、常にそれに戻っていることは、元の位置だということを確認します。お使いのアダプタで

、onBindViewHolderメソッドに次の行を追加します。上記の行で

holder.itemView.setTranslationY(0f); 

を、私はバックグラウンドで立ち往生している別のデータセットの最初の項目の奇妙なバグを得るが、あなたの場合RecyclerViewのバックグラウンドと同じ色の背景をアイテムに追加すると、バグも修正されます。

場合によっては解決策を見ているように物事を書き留めるのが非常に便利です。今回のように私は解決策を指摘しました。

関連する問題