본문 바로가기

ANDROID/UI - UX

[안드로이드] RecyclerView의 사이즈를 애니메이션과 함께 바꾸기, 아이템이 추가될 때 애니메이션 적용하기

 

UI/UX를 구성하는 중에 유동적으로 사이즈를 바꾸는 RecyclerView의 구현이 필요했다.

 

목표로는 두가지 목표가 있었는데,

 

첫째로는 2개 이상의 아이템이 RecyclerView에 추가될 때 RecyclerView의 사이즈를 늘리기.

 

둘째로는 신규 아이템이 추가될 때 Fade in 애니메이션 적용하는 것이었다. 

 

여러 방법들을 동원하던 중 코드 수도 적고 무난하게 사이즈를 늘릴 수 있는 레퍼런스를 찾았다.

 

 

https://stackoverflow.com/questions/32835397/android-property-animation-how-to-increase-view-height

 

Android property animation: how to increase view height?

How to increase the view height using Property Animations in Android? ObjectAnimator a = ObjectAnimator.ofFloat(viewToIncreaseHeight, "translationY", -100); a.setInterpolator(new

stackoverflow.com

구조로는 ValueAnimator를 하나 만들고

 

ValueAnimator.ofInt에 첫번째 파라미터로 RecyclerView의 Height을, 두번째 파라미터로 조정 후의 사이즈를

 

넣어주게 되어있다. 

 

여기에다 addUpdateListener를 추가하고, 보여줄 시간을 마지막으로 설정해주면 마무리된다.

 

ValueAnimator anim = ValueAnimator.ofInt(리사이클러뷰.getMeasuredHeight(), 조정할사이즈);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        int val = (Integer) valueAnimator.getAnimatedValue();
        ViewGroup.LayoutParams layoutParams = 리사이클러뷰.getLayoutParams();
        layoutParams.height = val;
        리사이클러뷰.setLayoutParams(layoutParams);
    }
});
anim.setDuration(애니메이션시간);
anim.start(); 

 

이어 둘째 목표였던 아이템이 추가될 때 아이템당 애니메이션 수행을 위해서는 아래의 레퍼런스를 참조했다.

 

https://stackoverflow.com/questions/45015681/animation-in-recyclerview-item-by-item

 

Animation in recyclerview item by item

I need to implement animations in RecyclerView which has a slide up effect for every item. I have searched for this and tried many different things. It works when you scroll but it is not working w...

stackoverflow.com

방식은 단순한데, RecyclerView의 CustomAdapter를 만들고,

 

CustomAdapter에서 마지막 item의 position을 저장할 변수 lastPosition을 추가해 새로운 position이 들어올 때

 

갱신해 신규 아이템일때를 가려 애니메이션을 적용하도록 한다. 

 

>> oBindViewHolder가 RecyclerView가 갱신될 때 전체 아이템 갯수만큼 실행되기 때문인 듯.

 

@Override
    public void onBindViewHolder(ViewHolderHelper holder, int position, List<Object> payloads) {
        super.onBindViewHolder(holder, position, payloads);

        setAnimation(holder.itemView, position);
    }

    private void setAnimation(View viewToAnimate, int position)
    {
        if (position > lastPosition)
        {
            Animation animation = AnimationUtils.loadAnimation(mcontext, R.anim.slide_in_bottom_list_item);
            animation.setInterpolator(new DecelerateInterpolator());
            if(position < 4)
                animation.setStartOffset(position * 200);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }