Android 사용자 정의 LinearLayout 타 오 바 오 구현 상세 페이지

1.간단 한 설명
타 오 바 오 상세 페이지 는 제 가 일일이 소개 하지 않 아 도 됩 니 다.어제 타 오 바 오 를 돌아 다 니 면서 이 효 과 를 보 았 을 때 저 는 작년 에 안 드 로 이 드 를 처음 배 웠 을 때 이미 만들어 진 것 만 사 용 했 을 때 인터넷 에서 이런 효 과 를 찾 아 사 용 했 는데 어떻게 실현 되 었 는 지 몰 랐 습 니 다.지금 은 한 가지 효 과 를 보고 스스로 실현 하고 싶 습 니 다.이것 이 바로 어떤 지식 을 처음 접 했 을 때의 호기심 이 라 고 생각 합 니 다.
가자 고 하면 가자.본 고 는 실현 방향 만 소개 할 뿐 인터넷 에 도 이미 여러 가지 실현 방식 이 있 으 니 문제 가 있 으 면 지적 해 주 십시오.
효과 도.

2.사고의 실현
LinearLayout 을 계승 하여 방향 을 수직 으로 설정 합 니 다.
컨트롤 에 두 개의 ScrollView 가 있 습 니 다.왜 ScrollView 를 사용 해 야 하 는 지 에 대해 서 는 내용 이 한 페이지 를 넘 을 때 미끄럼 을 줄 이기 때 문 입 니 다.
관건 은 사건 분배 처리 다.두 개의 ScrollView 의 미끄럼 사건 을 감청 하고 첫 페이지 가 끝까지 미 끄 러 졌 을 때 위로 드래그 할 때 사건 을 차단 하고 거 리 를 판단 하 며 설정 치 를 초과 할 때 두 번 째 페이지 로 미 끄 러 집 니 다.그렇지 않 으 면 다시 연주 합 니 다.마찬가지 로 두 번 째 페이지 가 맨 위로 미 끄 러 졌 을 때 아래로 드래그 할 때 사건 을 차단 하고 거 리 를 판단 하 며 설정 치 를 초과 할 때 첫 페이지 로 미 끄 러 집 니 다.그렇지 않 으 면 리 턴(코드 설명 과 결합 해 야 할 세부 사항 이 많 습 니 다)
리 턴 과 슬라이딩 페이지 를 바 꾸 는 데 사용 되 는 것 은 Scroller 입 니 다.Scroller 의 사용 에 대해 본 고 는 지나치게 설명 하지 않 습 니 다.
3.실현
3.1 다시 쓰기 스크롤 뷰
실현 방향 에 따라 스크롤 뷰 가 상단 과 아래쪽 까지 미 끄 러 지 는 지 감청 해 야 합 니 다.그러나 스크롤 뷰 의 setOn 스크롤 Change Listener()방법 은 api 23 에 추 가 됩 니 다.주로 Scrollviewon ScrollChanged(int l,int t,int oldl,int oldt)방법 을 다시 씁 니 다.
l:현재 수평 방향 스크롤 값 은 getScrollX()와 같 습 니 다.
t:현재 세로 방향 스크롤 값 은 getScrolly()와 같 습 니 다.
oldl:이전 수평 스크롤 값
oldt:지난번 수직 스크롤 값
감청 인터페이스:

public interface OnScrollEndListener {
 void scrollToBottom(View view);
 void scrollToTop(View view);
 void scrollToMiddle(View view);
 }

onScrollChanged 방법

 @Override
 protected void onScrollChanged(int l, int t, int oldl, int oldt) {
 super.onScrollChanged(l, t, oldl, oldt);
 if(t == 0){
  if (mOnScrollBottomListener != null) {
  mOnScrollBottomListener.scrollToTop(this);
  }
 } else if(t + getMeasuredHeight() >= getChildAt(0).getMeasuredHeight()){
  if (mOnScrollBottomListener != null) {
  mOnScrollBottomListener.scrollToBottom(this);
  }
 } else {
  if (mOnScrollBottomListener != null) {
  mOnScrollBottomListener.scrollToMiddle(this);
  }
 }
 }
3.2 onMeasure 재 작성 방법,page 의 획득 과 설정
두 번 째 아 이 를 호출 하 는 측정 방법 을 표시 합 니 다.그렇지 않 으 면 사이즈 가 0 일 수 있 습 니 다.

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 /**
  *                ,        0
  */
 View child2 = getChildAt(1);
 if (child2 != null) {
  child2.measure(widthMeasureSpec, heightMeasureSpec);
 }
 }
onFinish Inflate 에서 두 페이지 초기 화

@Override
 protected void onFinishInflate() {
 super.onFinishInflate();
 if(getChildCount() == 2){
  View child1 = getChildAt(0);
  if (child1 instanceof ScrollEndScrollView){
  scrollView1 = (ScrollEndScrollView) child1;
  }
  View child2 = getChildAt(1);
  if(child2 instanceof ScrollEndScrollView){
  scrollView2 = (ScrollEndScrollView) child2;
  }
 }

 initEvent();
 }

두 페이지 에 미끄럼 감청 설정

private ScrollEndScrollView.OnScrollEndListener scrollEndListener = new ScrollEndScrollView.OnScrollEndListener() {
 @Override
 public void scrollToBottom(View view) {
  if(view == scrollView1){
  isToBotttom = true;
  }
 }

 @Override
 public void scrollToTop(View view) {
  if(view == scrollView2){
  isToTop = true;
  }
 }

 @Override
 public void scrollToMiddle(View view) {
  if(view == scrollView1){
  isToBotttom = false;
  }
  if(view == scrollView2){
  isToTop = false;
  }
 }
 };

3.3 Scroller 가 사용 하 는 몇 단계
Scroller 의 영어 해석 은:
This class encapsulates scrolling. You can use scrollers (Scroller or OverScroller) to collect the data you need to produce a scrolling animation―for example, in response to a fling gesture. Scrollers track scroll offsets for you over time, but they don't automatically apply those positions to your view. It's your responsibility to get and apply new coordinates at a rate that will make the scrolling animation look smooth.
이러한 패키지 스크롤.스크롤 바(롤러 나 OverScroller)를 사용 하여 스크롤 하 는 애니메이션 을 만 들 수 있 습 니 다.예 를 들 어 제스처 에 응답 하 는 데 이 터 를 수집 할 수 있 습 니 다.스크롤 바 는 스크롤 오프셋 을 시간 이 지 날수 록 추적 하지만 새로운 위 치 를 View 에 자동 으로 설정 하지 않 습 니 다.스크롤 애니메이션 을 더 부 드 럽 게 보이 도록 적당 한 속 도 를 가 져 오고 사용 하 는 것 이 작업 입 니 다.
한 마디 로 미 끄 러 지 는 것 에 관 한 당신 은 모두 이 를 사용 하여 실현 할 수 있 습 니 다.
다시 쓰 는 방법 이 필요 해 요.

@Override
 public void computeScroll() {
 super.computeScroll();
 //   mScroller      
 if (mScroller.computeScrollOffset()) {
  //    View scrollTo()       
  scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
  //       ,            
  postInvalidate();
 }
 }
보조 방법

 //              
 public void smoothScrollBy(int dx, int dy) {
 //  mScroller      
 mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy, Math.max(300, Math.abs(dy)));
 invalidate();//      invalidate()    computeScroll()    ,          ,       
 }

//            
 public void smoothScrollTo(int fx, int fy) {
 int dx = fx - mScroller.getFinalX();
 int dy = fy - mScroller.getFinalY();
 smoothScrollBy(dx, dy);
 }

3.4 사건 배포
가장 관건 적 인 부분 은 논리 가 약간 복잡 하고 세부 적 인 처리 가 비교적 많다.디 스 패 치 터치 이 벤트 를 다시 쓰 겠 습 니 다.
첫 페이지 보이 기
끝까지 미 끄 러 지지 않 았 습 니 다.이 벤트 는 scrollView 1 이 직접 처리 합 니 다.
끝까지 미 끄 러 질 때 계속 위로 드래그 하면 이 벤트 를 차단 하고 부모 컨트롤 이 미 끄 러 집 니 다.계속 아래로 드래그 할 때 부모 컨트롤(즉 이 컨트롤)이 현재 스크롤 마지막 위치(mScroller.getFinaly()가 0 이 아 닌 경우 부모 컨트롤 이 계속 스크롤 하면 마이너스 가 나타 나 지 않 을 때(마이너스 가 나타 날 때 머리 공백 이 발생 합 니 다.이 때 는 부모 컨트롤 이 므 로 scrollView 1 이 미 끄 러 지지 않 습 니 다)이 벤트 를 차단 하지 않 고 부모 컨트롤 이 미 끄 러 지지 않 습 니 다.그렇지 않 으 면 0 위치 로 강제로 미 끄 러 집 니 다.하위 컨트롤 에 이벤트 보 내기
두 번 째 페이지 보이 기
맨 위로 미 끄 러 지지 않 았 을 때 이 벤트 는 scrollView 2 가 직접 처리 합 니 다.
맨 위로 미 끄 러 질 때 계속 아래로 드래그 하면 이 벤트 를 차단 하고 부모 컨트롤 이 미 끄 러 집 니 다.계속 위로 드래그 할 때 부모 컨트롤 이 현재 스크롤 위치 가 첫 페이지 높이 보다 작 으 면 차단 이벤트,부모 컨트롤 이 미 끄 러 집 니 다.그렇지 않 으 면 두 번 째 페이지 의 시작 위치 로 미 끄 러 지고 이 벤트 를 하위 컨트롤 에 보 냅 니 다.
ACTION_MOVE 에서 이벤트 배포 진행,ACTIONUP 중 페이지 전환,리 턴 진행
scroller 를 사용 하여 미끄럼 을 일 으 키 고 탄성 효 과 를 실현 하 는 것 에 대해 간단하게 실현 하려 면 여 기 를 보십시오간단 한 탄성 실현 코드

@Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
 int action = ev.getAction();
 int yPosition = (int) ev.getY();
 switch (action) {
  case MotionEvent.ACTION_DOWN:
  mScroller.abortAnimation();
  mLastY = yPosition;
  mMoveY = 0;
  break;
  case MotionEvent.ACTION_MOVE:
  mMoveY = (mLastY - yPosition);
  mLastY = yPosition;
  if(isToBotttom){
   if(mMoveY > 0){
   //  
   smoothScrollBy(0, mMoveY);
   return true;
   } else {
   //  
   if(mScroller.getFinalY() != 0){
    //                
    if(getScrollY() + mMoveY > 0){
    smoothScrollBy(0, mMoveY);
    return true;
    } else{
    smoothScrollTo(0, 0);
    return super.dispatchTouchEvent(ev);
    }
   }
   }
  }
  else if(isToTop){
   if(mMoveY < 0){
   //  
   smoothScrollBy(0, mMoveY);
   return true;
   } else {
   //  
   if(mScroller.getFinalY() < scrollView1.getHeight()){
    //                
    smoothScrollBy(0, mMoveY);
    return true;
   } else {
    smoothScrollTo(0, scrollView1.getHeight());
    return super.dispatchTouchEvent(ev);
   }
   }
  }

  //             
  if(pageIndex == 0){
   smoothScrollTo(0, 0);
  } else if(pageIndex == 1){
   smoothScrollTo(0, scrollView1.getHeight());
  }

  break;

  case MotionEvent.ACTION_UP:
  case MotionEvent.ACTION_CANCEL:
  if(isToBotttom){
   if(Math.abs(getScrollY()) > TO_NEXT_PAGE_HEIGHT){
   //      
   pageIndex = 1;
   smoothScrollTo(0, scrollView1.getHeight());
   isToBotttom = false;
   isToTop = true;
   } else {
   //  
   smoothScrollBy(0, -mScroller.getFinalY());
   }
  } else if(isToTop){
   if(scrollView1.getHeight() - getScrollY() > TO_NEXT_PAGE_HEIGHT){
   //      
   pageIndex = 0;
   smoothScrollTo(0, 0);
   isToBotttom = true;
   isToTop = false;
   } else {
   //  
   smoothScrollTo(0, scrollView1.getHeight());
   }
  }

  break;
  default:
  break;
 }

 return super.dispatchTouchEvent(ev);
 }

4.총화
이 컨트롤 을 실현 하려 면 파악 해 야 할 지식 은 주로 사용자 정의 컨트롤 의 기본 절차,Scroller 의 기본 사용 과 이벤트 배포 입 니 다.물론 여기 서 가장 관건 적 인 처 리 는 이벤트 배포 입 니 다.처음에 도 이것 은 많은 사람들 이 이 루 었 지만 자신의 방식 으로 이 루 고 싶다 고 말 했다.크게 웃 으 며 하하 하,또 하나의 사용자 정의 컨트롤 을 실현 합 니 다.블 로 거들 은 사용자 정의 컨트롤 학습 단계 에 있 습 니 다.이 컨트롤 을 프로젝트 에 사용 하 는 것 을 조심 하 세 요.
5.다운로드
https://github.com/LineChen/TwoPageLayout
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기