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 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
ScrollView에 포함된 ListView는 하나의 해결 방법만 표시합니다.일반적으로 우리는 ScrollView에 ListView를 끼워 넣지 않지만, 면접관이 굳이 끼워 넣지 않아도 된다. ScrollView에 ListView를 추가하면 listview 컨트롤이 완전하지 않습니다. 보통 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.