Android 사용자 정의 뷰 서랍 효과 구현

11763 단어 Android서랍 효과
Android 사용자 정의 뷰 서랍 효과 구현
설명 하 다.
  • 이 사용자 정의 View 는 터치 문 제 를 많이 처리 하지 않 았 습 니 다
  • View 는 손가락 을 따라 이동 합 니 다.전통 적 인 scrollBy 방법 을 사용 하지 않 고 끊임없이 하위 View 를 다시 배치 하 는 방식 으로 하위 View 가 스크롤 효 과 를 낼 수 있 도록 menuView.layot(menuLeft,0,menuLeft+menuWidth,menuHeight);
  • 이에 따라 scrollBy 방법 을 사용 하지 않 으 면 getScrollX 값 이 발생 하지 않 기 때문에 Scroller 의 startScroll 방법 으로 손가락 이 떠 난 후의 부 드 러 운 스크롤 효 과 를 완성 할 수 없고 Animation 애니메이션 의 apply Transformation 방법 으로 삽입 값 을 완성 하여 애니메이션 효 과 를 실현 합 니 다.
  • 주요 알고리즘:애니메이션 현재 값=시작 값+(목표 값-시작 값)*interpolatedTime
    그 중에서 interpolated Time 은 0.0f~1.0f 의 숫자 로 시스템 자체 의 플러그 인 계산 이 되 었 습 니 다(기본 값 은 선형 변화 입 니 다).물론 직접 플러그 인 을 쓸 수 있 습 니 다.
    
     /**
       *         scrollBy,         Scroller           ,       
       */
      class MyAnimation extends Animation {
    
        private int viewCurrentLfet;
        private int viewStartLfet;
        private int viewTargetLfet;
        private int viewWidth;
        private View view;
        private int cha;
    
        public MyAnimation(View view, int viewStartLfet, int viewTargetLfet, int viewWidth) {
          this.view = view;
          this.viewStartLfet = viewStartLfet;
          this.viewTargetLfet = viewTargetLfet;
          this.viewWidth = viewWidth;
          cha = viewTargetLfet - viewStartLfet;
          setDuration(Math.abs(cha));
        }
    
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
          super.applyTransformation(interpolatedTime, t);
    
          viewCurrentLfet = (int) (viewStartLfet + cha * interpolatedTime);
          view.layout(viewCurrentLfet, 0, viewCurrentLfet + viewWidth, menuHeight);
    
    
        }
      }
    
    
    전체 코드
    
    package com.sunshine.choutidemo;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.VelocityTracker;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.view.ViewGroup;
    import android.view.animation.Animation;
    import android.view.animation.AnimationSet;
    import android.view.animation.Transformation;
    
    /**
     * Created by a on 2016/8/15.
     */
    public class ChouTiView extends ViewGroup {
    
      private View mainView;
      private View menuView;
      private int menuWidth;
      private int downX;
      private int lastX;
      private int moveX;
      private int deltaX;
      private int menuLeft;
      private int mainLeft;
      private int menuHeight;
      private int mainWidth;
      private int mainHeight;
      private int menuLeftBorder;
      private int mainLeftBorder;
      private int menuRightBorder;
      private int mainRightBorder;
      private int mMaxVelocity;
      private VelocityTracker mVelocityTracker;
      private int mPointerId;
      private float velocityX;
      private float velocityY;
    
      public ChouTiView(Context context) {
        super(context);
        init();
      }
    
    
      public ChouTiView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
      }
    
      private void init() {
    //   0.        
        mMaxVelocity = ViewConfiguration.get(getContext()).getMaximumFlingVelocity();
      }
    
      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mainView.measure(widthMeasureSpec, heightMeasureSpec);
        menuView.measure(widthMeasureSpec, heightMeasureSpec);
    //       View     (          ),          ,    match―parent -1
        menuWidth = menuView.getLayoutParams().width;
        menuLeft = (int) (-menuWidth * 0.5);
        menuLeftBorder = (int) (-menuWidth * 0.5);
        menuRightBorder = 0;
        mainLeft = 0;
        mainLeftBorder = 0;
        mainRightBorder = menuWidth;
    
      }
    
      @Override
      protected void onLayout(boolean changed, int l, int t, int r, int b) {
        menuHeight = b;
        mainWidth = r;
        mainHeight = b;
        mainView.layout(l, t, r, b);
        menuView.layout(menuLeft, t, menuLeft + menuWidth, b);
    
      }
    
      @Override
      protected void onFinishInflate() {
        super.onFinishInflate();
        mainView = getChildAt(1);
        menuView = getChildAt(0);
      }
    
      @Override
      public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getActionMasked();
    
        acquireVelocityTracker(event); //1. VelocityTracker  MotionEvent
        final VelocityTracker verTracker = mVelocityTracker;
        switch (action) {
    
          case MotionEvent.ACTION_DOWN:
            //2.       id,          ,     
            //      0   id
            mPointerId = event.getPointerId(0);
            downX = (int) event.getX();
            lastX = downX;
            break;
    
          case MotionEvent.ACTION_MOVE:
    //       id      ,   ACTION_DOWN   ,         0
            //    ,          ,         up  ,         
    
            //           ,                    ,
            //         event.getActionIndex()     
            final int pointerIndex = event.findPointerIndex(mPointerId);
    
    
            moveX = (int) event.getX(pointerIndex);
            deltaX = moveX - lastX;
    //                  ,   menu main   left 
            menuLeft = (int) (menuLeft + deltaX * 0.43);//         
            mainLeft = mainLeft + deltaX;
    //                   ,        (     layout      )
    //             scrollBy,  scrollBy        View,            view     View
    //        scrollBy  ,            ,        ,
    //           ,   view  scrollBy,       ,
    //            view,  menu  scrollBy  ,  menu       ,
    //           , menu        ,  menu        View   
    //             ,       scrollBy
            if (menuLeft >= menuRightBorder) {
              menuLeft = menuRightBorder;
            } else if (menuLeft <= menuLeftBorder) {
              menuLeft = menuLeftBorder;
            }
            menuView.layout(menuLeft, 0, menuLeft + menuWidth, menuHeight);
    
    
    //                    ,        
            if (mainLeft >= mainRightBorder) {
              mainLeft = mainRightBorder;
            } else if (mainLeft <= mainLeftBorder) {
              mainLeft = mainLeftBorder;
            }
            mainView.layout(mainLeft, 0, mainLeft + mainWidth, mainHeight);
    
            lastX = moveX;
            break;
    
    
          case MotionEvent.ACTION_UP:
            //3.      
            verTracker.computeCurrentVelocity(1000, mMaxVelocity);
            velocityX = verTracker.getXVelocity(mPointerId);
            Log.e("qwe", velocityX + "/" + mMaxVelocity);
            if (velocityX > 1000) {
              smoothToMenu();
            } else if (velocityX < -2000) {
              smoothToMain();
            } else {
    //               ,    1/2.5          ,       
    
              if (mainLeft > menuWidth / 2.5) {
                Log.e("qqq", "    ");
                smoothToMenu();
              } else {
                Log.e("qqq", "     ");
                smoothToMain();
              }
            }
    //        4.ACTION_UP  VelocityTracker,        
            releaseVelocityTracker();
            break;
          case MotionEvent.ACTION_CANCEL:
    
    //        4.ACTION_UP  VelocityTracker,        
            releaseVelocityTracker();
    
          case MotionEvent.ACTION_POINTER_UP:
            //             
            int pointerIndexLeave = event.getActionIndex();
            int pointerIdLeave = event.getPointerId(pointerIndexLeave);
            if (mPointerId == pointerIdLeave) {
              //               ,        ,      VelocityTracker
              int reIndex = pointerIndexLeave == 0 ? 1 : 0;
              mPointerId = event.getPointerId(reIndex);
              //       ,      
              downX = (int) event.getX(reIndex);
    //          y = event.getY(reIndex);
              releaseVelocityTracker();
            }
            releaseVelocityTracker();
    
            break;
        }
    
    
        return true;
      }
    
      private void smoothToMain() {
        MyAnimation menuAnimation = new MyAnimation(menuView, menuLeft, menuLeftBorder, menuWidth);
        MyAnimation mainAnimation = new MyAnimation(mainView, mainLeft, mainLeftBorder, mainWidth);
        AnimationSet animationSet = new AnimationSet(true);
        animationSet.addAnimation(menuAnimation);
        animationSet.addAnimation(mainAnimation);
        startAnimation(animationSet);
        //      menu main     ,     ,           ,    
        menuLeft = menuLeftBorder;
        mainLeft = mainLeftBorder;
      }
    
      private void smoothToMenu() {
        MyAnimation menuAnimation = new MyAnimation(menuView, menuLeft, menuRightBorder, menuWidth);
        MyAnimation mainAnimation = new MyAnimation(mainView, mainLeft, mainRightBorder, mainWidth);
        AnimationSet animationSet = new AnimationSet(true);
        animationSet.addAnimation(menuAnimation);
        animationSet.addAnimation(mainAnimation);
        startAnimation(animationSet);
        //      menu main     ,     ,           ,    
        menuLeft = menuRightBorder;
        mainLeft = mainRightBorder;
      }
    
    
      /**
       * @param event  VelocityTracker  MotionEvent
       * @see android.view.VelocityTracker#obtain()
       * @see android.view.VelocityTracker#addMovement(MotionEvent)
       */
      private void acquireVelocityTracker(final MotionEvent event) {
        if (null == mVelocityTracker) {
          mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
      }
    
      /**
       *   VelocityTracker
       *
       * @see android.view.VelocityTracker#clear()
       * @see android.view.VelocityTracker#recycle()
       */
      private void releaseVelocityTracker() {
        if (null != mVelocityTracker) {
          mVelocityTracker.clear();
          mVelocityTracker.recycle();
          mVelocityTracker = null;
        }
      }
    
    
      /**
       *         scrollBy,         Scroller           ,       
       */
      class MyAnimation extends Animation {
    
        private int viewCurrentLfet;
        private int viewStartLfet;
        private int viewTargetLfet;
        private int viewWidth;
        private View view;
        private int cha;
    
        public MyAnimation(View view, int viewStartLfet, int viewTargetLfet, int viewWidth) {
          this.view = view;
          this.viewStartLfet = viewStartLfet;
          this.viewTargetLfet = viewTargetLfet;
          this.viewWidth = viewWidth;
          cha = viewTargetLfet - viewStartLfet;
          setDuration(Math.abs(cha));
        }
    
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
          super.applyTransformation(interpolatedTime, t);
    
          viewCurrentLfet = (int) (viewStartLfet + cha * interpolatedTime);
          view.layout(viewCurrentLfet, 0, viewCurrentLfet + viewWidth, menuHeight);
    
    
        }
      }
    
    }
    
    
    읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

    좋은 웹페이지 즐겨찾기