Android,시차 효과 있 는 ListView 구현
이른바 시차 효 과 는 웹 디자인 과 모 바 일 애플 리 케 이 션 에서 흔히 볼 수 있다.우 리 는 일부 주요 플랫폼 에서 그의 모습 을 발견 할 수 있다.윈도 폰 에서 iOS,심지어 안 드 로 이 드 까지.위 키 백과 에 따 르 면 시차 스크롤 은 컴퓨터 그래 픽 에서 특수 한 스크롤 기술 로 이 카메라 의 이동 배경 이미지 가 전경 이미지 보다 느 려 시각 적 깊이 의 가상 을 일 으 켰 다.
그렇다면 과연 시차 효 과 는 무엇 일 까?효과 도 를 함께 보면 알 수 있다.
ListView
의HeaderView
는ListView
의 미끄럼 에 따라 커지 고HeaderView
의 그림 은 크기 조정 효과 가 있 는 것 을 볼 수 있다.이것들 은 속성 애니메이션 을 사용 하여 실현 할 수 있다.이제 우리 가 시작 합 시다!우선 몇 개의 속성 을 사용자 정의 하고 나중에 사용 할 수 있 습 니 다.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ZoomListView">
<!-- headerView -->
<attr name="header_height" format="dimension|reference"></attr>
<!-- headerView -->
<attr name="header_max_height" format="dimension|reference"></attr>
<!-- headerView -->
<attr name="header_max_scale" format="float"></attr>
</declare-styleable>
</resources>
이후 창설ZoomListView
클래스,계승ListView
:
public class ZoomListView extends ListView {
//
private final float defaultHeaderMaxScale = 1.2f;
//
private float headerMaxHeight;
//
private float headerHeight;
//
private float defaultHeaderHeight;
//
private float defaultHeaderMaxHeight;
private ImageView headerView;
private ViewGroup.LayoutParams layoutParams;
private LinearLayout linearLayout;
//
private float headerMaxScale;
public ZoomListView(Context context) {
this(context, null);
}
public ZoomListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ZoomListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
defaultHeaderHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 160, context.getResources().getDisplayMetrics());
defaultHeaderMaxHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 240, context.getResources().getDisplayMetrics());
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ZoomListView);
headerHeight = a.getDimension(R.styleable.ZoomListView_header_height, defaultHeaderHeight);
headerMaxHeight = a.getDimension(R.styleable.ZoomListView_header_max_height, defaultHeaderMaxHeight);
headerMaxScale = a.getFloat(R.styleable.ZoomListView_header_max_scale, defaultHeaderMaxScale);
a.recycle();
initView();
}
...
}
여기까지 순서대로 사용자 정의 속성의 초기 값 을 설정 하고 호출initView()
하면 initView()
방법 을 보 겠 습 니 다.
private void initView() {
headerView = new ImageView(getContext());
headerView.setScaleType(ImageView.ScaleType.CENTER_CROP);
linearLayout = new LinearLayout(getContext());
linearLayout.addView(headerView);
layoutParams = headerView.getLayoutParams();
if (layoutParams == null) {
layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) headerHeight);
} else {
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.height = (int) headerHeight;
}
headerView.setLayoutParams(layoutParams);
addHeaderView(linearLayout);
}
public void setDrawableId(int id) {
headerView.setImageResource(id);
}
이 를 통 해 알 수 있 듯 이initView()
에서 우 리 는headerView
을 만 들 었 고ListView
의 머리 에 추가 했다.setDrawableId(int id)
는headerView
에 관련 사진 을 설치 하 는 것 이다.다음은 시차 효과 의 주요 실현 코드 입 니 다.
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if (deltaY < 0 && isTouchEvent) {
if (headerView.getHeight() < headerMaxHeight) {
int newHeight = headerView.getHeight()
+ Math.abs(deltaY / 3);
headerView.getLayoutParams().height = newHeight;
headerView.requestLayout();
float temp = 1 + (headerMaxScale - 1f) * (headerView.getHeight() - headerHeight) / (headerMaxHeight - headerHeight);
headerView.animate().scaleX(temp)
.scaleY(temp).setDuration(0).start();
}
}
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
우 리 는overScrollBy()
방법 을 다시 썼 습 니 다.deltay 가 0 보다 작 을 때(즉ListView
이미 정상 에 도 착 했 지만 사용자 의 손짓 은 아래로 당 겼 습 니 다)동적 으로headerView
의 높이 와headerView
의scale
값 을 설정 합 니 다.이렇게 하면headerView
높 아 지고 사진 이 확대 되 는 효 과 를 낼 수 있다.다음 에 고려 해 야 할 문 제 는 사용자 가 손가락 을 풀 었 을 때 원래 의 모습 으로 돌아 가 는 것 이다.그래서 우 리 는
onTouchEvent(MotionEvent ev)
에서 관련 조작 을 실현 해 야 한다.
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
startAnim();
break;
}
return super.onTouchEvent(ev);
}
//
private void startAnim() {
ValueAnimator animator = ValueAnimator.ofFloat(headerView.getHeight(), headerHeight);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float fraction = (float) animation.getAnimatedValue();
headerView.getLayoutParams().height = (int) fraction;
headerView.requestLayout();
}
});
animator.setDuration(500);
animator.setInterpolator(new LinearInterpolator());
ValueAnimator animator2 = ValueAnimator.ofFloat(headerView.getScaleX(), 1f);
animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float fraction = (float) animation.getAnimatedValue();
headerView.setScaleX(fraction);
headerView.setScaleY(fraction);
}
});
animator2.setDuration(500);
animator2.setInterpolator(new LinearInterpolator());
animator.start();
animator2.start();
}
위의 코드 는 간단하게 말 하면 ACTION 에 있 습 니 다.UP 시 두 개의 속성 애니메이션 을 시작 합 니 다.하나의 속성 애니메이션 은headerView
의 높이 를 원래 의 값 으로 회복 하 는 것 입 니 다.다른 속성 애니메이션 은headerView
의 scale 을 다시 1f 로 복원 하 는 것 입 니 다.다 들 알 아 보 실 거 라 고 믿 습 니 다.총결산
이상 이 이 글 의 전체 내용 입 니 다.이 글 의 내용 이 안 드 로 이 드 개발 자 여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 댓 글 을 남 겨 주 십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.