Android,시차 효과 있 는 ListView 구현

7099 단어 androidlistview시차
시차 효 과 는 무엇 입 니까?
이른바 시차 효 과 는 웹 디자인 과 모 바 일 애플 리 케 이 션 에서 흔히 볼 수 있다.우 리 는 일부 주요 플랫폼 에서 그의 모습 을 발견 할 수 있다.윈도 폰 에서 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 로 복원 하 는 것 입 니 다.다 들 알 아 보 실 거 라 고 믿 습 니 다.
총결산
이상 이 이 글 의 전체 내용 입 니 다.이 글 의 내용 이 안 드 로 이 드 개발 자 여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 댓 글 을 남 겨 주 십시오.

좋은 웹페이지 즐겨찾기