android RecylcerView ImageResize (카카오톡 이미지 커지는 애니메이션 구현 방법)
sieunju2018. 1. 13. 20:36
반응형
오랜만에 포스팅을 하게 되었습니다. 일단 어떤걸 말하는 건지 이해가 잘 안되는 분들을 위해서 알려드리도록 하겠습니다. 우선 카카x톡을 들어가면
저 텝이 보이는데 저 텝을 클릭해서 스크롤을 하면 영상이 점점 커져서 보이는 애니메이션 같은게 있습니다.
(이 구현영상은 제가 구현한 것으로 실제 녹화해서 찍은 영상입니다.)
제가 만든 것은 이미지로 구현했지만 카카x톡에서는 영상으로 되어있습니다. (딱히 상관은 없습니다.)
이제 본론으로 넘어와서 저것이 어떻게 구현되는건지 소스에 대해서 부분부분 보여드리도록 하겠습니다.
-CustomLinearLayoutManager.java-
package com.example.jsieu.work.view; import android.content.Context; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import com.example.jsieu.work.adapter.CustomRecyclerAdapter; /** * 특정 뷰홀더 확대 전용 LayoutMnager * Created by jsieu on 2018-01-12. */ public class CustomLinearLayoutManager extends LinearLayoutManager {
private CustomRecyclerAdapter mRecyclerAdapter; public CustomLinearLayoutManager(Context context) { super(context); }
/** * 0% ~ 100% 사이즈 크기 * * @param heightPercentage * @author jsieun */ public void resizeEvt(int heightPercentage) { //연산 계산 ( 최대값 - 최소값 ) * x% -> y //y += 최소값 -> 0%~100% 이미지 크기만큼 나온다. double percentage = (double) heightPercentage / 100; int value = (int) (mCalculation * percentage); value += mMinImageHeight; if (value >= mMaxImageHeight) { value = mMaxImageHeight; } else if (value <= mMinImageHeight) { value = mMinImageHeight; }
//이미지를 감싸고 있는 Layout의 높이값을 Set RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.height = value; mResizeViewRelativeLayout.setLayoutParams(layoutParams); //아래에서 위로 스크롤할경우 텍스트색상은 점점 연하게 //위에서 아래로 스크롤할경우 텍스트색상은 점점 진하게 mResizeTextView.setTextColor(Color.parseColor(calculationAlpha(heightPercentage))); }
/** * 0% ~ 100% 에 맞게 알파값 HexCode 로 변환 * * @param heightPercentage * @return * @author jsieun */ private String calculationAlpha(int heightPercentage) { String hexCode = ""; //퍼센트가 100% 로 넘어가는 것을 방지하기 위한 방어 코드 if (heightPercentage >= 100) { heightPercentage = 100; }
//점점 스크롤을 내릴수록 텍스트가 사라져야 하기때문에 0% ~ 100% 가 아닌 //100% ~ 0% 로 hexCode 가 나와야 함. heightPercentage = 100 - heightPercentage; //HexCode 0~255 에 맞게 계산. double percentage = (double) heightPercentage / 100; int round = (int) Math.round(percentage * 255); hexCode = Integer.toHexString(round).toUpperCase(); if (hexCode.length() == 1) { hexCode = "0" + hexCode; }
특정 카드가 원하는 위치에서 보일때 setResizeHeight 함수를 통하여 mResizeHeight 값은 계속해서 Set 이 됩니다.
그후에 ResizeViewHolder 를 그리는 부분에 대하여 설명하도록 하겠습니다.
저같은 경우에는 5번째에 ResizeViewHolder 가 나오도록 구현했습니다.
if (viewType == VIEWPAGER_TYPE) { view = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_resize, parent, false); view.getViewTreeObserver().addOnScrollChangedListener(this); return new ResizeViewHolder(view);
다른 일반 뷰홀더는 getViewTreeObserver().addOnScrollChangedListener(this); 이 리스너를 안했는데 이미지가 커지는 뷰홀더는 스크롤 리스너를 달았습니다. 그 이유는
CustomLinearLayoutManager 에서 받는 값을 바로 이미지가 커지는 뷰홀더에 값을 전달할수 없기 때문입니다. 그래서 스크롤 이벤트를 달아서 이미지가 커지는 뷰홀더가 스크롤이 됐을때
@Override public void onScrollChanged() { ((ResizeViewHolder) mResizeViewHolder).resizeEvt(mResizeHeight); }
ResizeViewHolder 클래스 안에 resizeEvt 함수를 호출하도록 구현을 했습니다.
/** * 0% ~ 100% 사이즈 크기 * * @param heightPercentage * @author jsieun */ public void resizeEvt(int heightPercentage) { //연산 계산 ( 최대값 - 최소값 ) * x% -> y //y += 최소값 -> 0%~100% 이미지 크기만큼 나온다. double percentage = (double) heightPercentage / 100; int value = (int) (mCalculation * percentage); value += mMinImageHeight; if (value >= mMaxImageHeight) { value = mMaxImageHeight; } else if (value <= mMinImageHeight) { value = mMinImageHeight; }
//이미지를 감싸고 있는 Layout의 높이값을 Set RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.height = value; mResizeViewRelativeLayout.setLayoutParams(layoutParams); //아래에서 위로 스크롤할경우 텍스트색상은 점점 연하게 //위에서 아래로 스크롤할경우 텍스트색상은 점점 진하게 mResizeTextView.setTextColor(Color.parseColor(calculationAlpha(heightPercentage))); }
그리고 resizeEvt 함수는 이미지의 최소크기와 최대 크기에 맞춰서 사이즈가 계속해서 Set 이 됩니다.
그와 동시에 가운데 텍스트 색상은 하->상 스크롤 할경우 점점 연하게
상->하 스크롤 할경우 점점 진하게 노출되도록 구현 했습니다.
이상 소스 해석은 마치도록 하겠습니다. 설명과 소스가 좀 많이 길어서 다시 위로 올려서 구현한 영상을 보기 귀찮은 분들을 위해서 다시 한번 올립니다.
마지막으로 제가 구현한 소스라서 마음대로 가져다가 사용하셔도 상관 없는데,
댓글은 남기고 사용하시면 정말 감사합니다.^^
Ps. 참고로 이미지가 커질때 나오는 저 이미지 소스는 제가 요새 관심있게 보는 다음 웹툰 홍도 입니다. :D