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가 모든 항목을 그릴 때 ViewHolder의 새로운 크기를 고려하지 않는 것처럼 RecyclerView 내부에 때때로 간격이 생기는 것입니다. 무엇보다 항목의 일부는 글자 그대로 서로의 위에 놓여 있으며 원하는 경우 언제든지 전경으로 깜박입니다. 올바른 위치에 배치 된 항목 위에있는 항목은 틈에 배치해야하는 항목입니다. 그들은 그 격차로 돌아 가지 않을 것이지만, 수동으로 항목 집합을 조사 할 때, 나는 그들이 거기에 있어야한다는 것을 알아 차렸다.

RecyclerView는 SwipeRefreshLayout보기의 하위 항목이지만 문제가 될 것이라고 생각하지 않습니다.

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

내가 잘못 뭐하는 거지 레이아웃 파일

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

내부 :

I가 RecyclerView로 설정 한 매개 변수 중 일부

?

모든 애니메이션이 완료되었는지 확인하기 위해 이미 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(); 
    } 

편집 :

화면에있는 마지막으로 볼 수 항목 후 항목이 잘못된 장소에 배치 않은 것 같습니다

.

답변

1
내가 일주일 동안이 문제와 싸우고 있었어요

, 그러나 나는 해결책을 발견 : 이것에

변경 runEnterAnimation :

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 콜백을 , 이것은 아이템의 번역이 항상 애니메이션이 움직이고있는 원하는 번역으로 설정되어 있는지 확인합니다.

이 함께 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 배경과 같은 색의 배경을 아이템에 추가하여 버그가 수정되었습니다.

때로는 솔루션을 볼 때처럼 글을 쓰는 것이 매우 유용합니다. 이번처럼 그것은 해결책을 지적했다.

관련 문제