<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      安卓筆記俠

      專注安卓開發

      導航

      Android View體系(二)實現View滑動的六種方法

      1.View的滑動簡介

      View的滑動是Android實現自定義控件的基礎,同時在開發中我們也難免會遇到View的滑動的處理。其實不管是那種滑動的方式基本思想都是類似的:當觸摸事件傳到View時,系統記下觸摸點的坐標,手指移動時系統記下移動后的觸摸的坐標并算出偏移量,并通過偏移量來修改View的坐標。
      實現View滑動有很多種方法,這篇文章主要講解六種滑動的方法,分別是:layout()、offsetLeftAndRight()與offsetTopAndBottom()、LayoutParams、動畫、scollTo與scollBy和Scroller;在下一篇文章我們會詳細介紹屬性動畫。

      2.實現View滑動的六種方法

      layout()

      view進行繪制的時候會調用onLayout()方法來設置顯示的位置,因此我們同樣也可以通過修改View的left、top、right、bottom這四種屬性來控制View的坐標。

      首先我們要自定義一個View,在onTouchEvent()方法中獲取觸摸點的坐標:
      public boolean onTouchEvent(MotionEvent event) {
              //獲取到手指處的橫坐標和縱坐標
              int x = (int) event.getX();
              int y = (int) event.getY();
      
              switch (event.getAction()) {
                  case MotionEvent.ACTION_DOWN:
                      lastX = x;
                      lastY = y;
                      break;
      
      
      接下來我們在ACTION_MOVE事件中計算偏移量,再調用layout()方法重新放置這個自定義View的位置就好了
      case MotionEvent.ACTION_MOVE:
          //計算移動的距離
          int offsetX = x - lastX;
          int offsetY = y - lastY;
          //調用layout方法來重新放置它的位置
          layout(getLeft()+offsetX, getTop()+offsetY,
                  getRight()+offsetX , getBottom()+offsetY);
          break;
      
      當我們每次移動時都會調用layout()方法來對自己重新布局,從而達到移動View的效果。
      
      自定義View的全部代碼(CustomView.java):
      public class CustomView extends View {
          private int lastX;
          private int lastY;
      
          public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
          }
          public CustomView(Context context, AttributeSet attrs) {
              super(context, attrs);
          }
      
          public CustomView(Context context) {
              super(context);
          }
      
          public boolean onTouchEvent(MotionEvent event) {
              //獲取到手指處的橫坐標和縱坐標
              int x = (int) event.getX();
              int y = (int) event.getY();
      
              switch (event.getAction()) {
                  case MotionEvent.ACTION_DOWN:
                      lastX = x;
                      lastY = y;
                      break;
      
                  case MotionEvent.ACTION_MOVE:
                      //計算移動的距離
                      int offsetX = x - lastX;
                      int offsetY = y - lastY;
                      //調用layout方法來重新放置它的位置
                      layout(getLeft()+offsetX, getTop()+offsetY,
                              getRight()+offsetX , getBottom()+offsetY);
                      break;
              }
      
              return true;
          }
      }
      
      布局中引用自定義View:
      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
      
          <com.example.liuwangshu.moonviewslide.CustomView
              android:id="@+id/customview"
              android:layout_width="80dp"
              android:layout_height="80dp"
              android:layout_margin="50dp"
              android:background="@android:color/holo_red_light" />
      </LinearLayout>
      View Code

      offsetLeftAndRight()與offsetTopAndBottom()

      這兩種方法和layout()方法效果方法差不多,使用也差不多,我們將ACTION_MOVE中的代碼替換成如下代碼:

      case MotionEvent.ACTION_MOVE:
          //計算移動的距離
          int offsetX = x - lastX;
          int offsetY = y - lastY;
          //對left和right進行偏移
          offsetLeftAndRight(offsetX);
          //對top和bottom進行偏移
          offsetTopAndBottom(offsetY);
          break;
      View Code

      LayoutParams(改變布局參數)

      LayoutParams主要保存了一個View的布局參數,因此我們可以通過LayoutParams來改變View的布局的參數從而達到了改變View的位置的效果。同樣的我們將ACTION_MOVE中的代碼替換成如下代碼:

      LinearLayout.LayoutParams layoutParams= (LinearLayout.LayoutParams) getLayoutParams();
                    layoutParams.leftMargin = getLeft() + offsetX;
                    layoutParams.topMargin = getTop() + offsetY;
                    setLayoutParams(layoutParams);
      View Code

      動畫

      可以采用View動畫來移動,在res目錄新建anim文件夾并創建translate.xml:
      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
          <translate android:fromXDelta="0" android:toXDelta="300" android:duration="1000"/>
      </set>
      
      在Java代碼中引用:
      mCustomView.setAnimation(AnimationUtils.loadAnimation(this, R.anim.translate));
      
      當然使用屬性動畫移動那就更簡單了,我們讓CustomView在1000毫秒內沿著X軸像右平移300像素:
      ObjectAnimator.ofFloat(mCustomView,"translationX",0,300).setDuration(1000).start();
      View Code

      scollTo與scollBy

      scollTo(x,y)表示移動到一個具體的坐標點,而scollBy(dx,dy)則表示移動的增量為dx、dy。其中scollBy最終也是要調用scollTo的。scollTo、scollBy移動的是View的內容,如果在ViewGroup中使用則是移動他所有的子View。我們將ACTION_MOVE中的代碼替換成如下代碼:

      ((View)getParent()).scrollBy(-offsetX,-offsetY);

      Scroller

      我們用scollTo/scollBy方法來進行滑動時,這個過程是瞬間完成的,所以用戶體驗不大好。這里我們可以使用Scroller來實現有過度效果的滑動,這個過程不是瞬間完成的,而是在一定的時間間隔完成的。Scroller本身是不能實現View的滑動的,它需要配合View的computeScroll()方法才能彈性滑動的效果。
      在這里我們實現CustomView平滑的向右移動。

      首先我們要初始化Scroller:
      public CustomView(Context context, AttributeSet attrs) {
            super(context, attrs);
            mScroller = new Scroller(context);
      }
      
      接下來重寫computeScroll()方法,系統會在繪制View的時候在draw()方法中調用該方法,這個方法中我們調用父類的scrollTo()方法并通過Scroller來不斷獲取當前的滾動值,每滑動一小段距離我們就調用invalidate()方法不斷的進行重繪,重繪就會調用computeScroll()方法,這樣我們就通過不斷的移動一個小的距離并連貫起來就實現了平滑移動的效果:
      @Override
      public void computeScroll() {
          super.computeScroll();
          if(mScroller.computeScrollOffset()){
              ((View) getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
               //通過不斷的重繪不斷的調用computeScroll方法
               invalidate();
          }  
      }
      
      調用Scroller.startScroll()方法。我們在CustomView中寫一個smoothScrollTo()方法,調用Scroller.startScroll()方法,在2000毫秒內沿X軸平移delta像素:
      public void smoothScrollTo(int destX,int destY){
            int scrollX=getScrollX();
            int delta=destX-scrollX;
            //1000秒內滑向destX
            mScroller.startScroll(scrollX,0,delta,0,2000);
            invalidate();
      }
      
      最后我們在ViewSlideActivity.java中調用CustomView的smoothScrollTo()方法:
      //使用Scroll來進行平滑移動
      mCustomView.smoothScrollTo(-400,0);
      
      這里我們是設定CustomView沿著X軸向右平移400像素。
      View Code

       

      3.完整代碼:

      public class ViewSlideActivity extends AppCompatActivity {
          private CustomView mCustomView;
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_view_slide);
              mCustomView= (CustomView) this.findViewById(R.id.customview);
              //使用屬性動畫使view滑動
      //        ObjectAnimator.ofFloat(mCustomView,"translationX",0,300).setDuration(1000).start();
              //使用View動畫使view滑動
      //      mCustomView.setAnimation(AnimationUtils.loadAnimation(this, R.anim.translate));
              //使用Scroll來進行平滑移動
              mCustomView.smoothScrollTo(-400,0);
          }
      }
      
      
      public class CustomView extends View {
          private int lastX;
          private int lastY;
          private Scroller mScroller;
      
          public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
      
          }
      
          public CustomView(Context context, AttributeSet attrs) {
              super(context, attrs);
              mScroller = new Scroller(context);
          }
      
          public CustomView(Context context) {
              super(context);
          }
      
      
          public boolean onTouchEvent(MotionEvent event) {
              //獲取到手指處的橫坐標和縱坐標
              int x = (int) event.getX();
              int y = (int) event.getY();
      
              switch (event.getAction()) {
                  case MotionEvent.ACTION_DOWN:
      
                      lastX = x;
                      lastY = y;
      
                      break;
      
                  case MotionEvent.ACTION_MOVE:
      
                      //計算移動的距離
                      int offsetX = x - lastX;
                      int offsetY = y - lastY;
                      //調用layout方法來重新放置它的位置
      //                layout(getLeft()+offsetX, getTop()+offsetY,
      //                        getRight()+offsetX , getBottom()+offsetY);
      
                      //對left和right進行偏移
      //                offsetLeftAndRight(offsetX);
                      //對top和bottom進行偏移
      //                offsetTopAndBottom(offsetY);
                      //使用LayoutParams
      //                LinearLayout.LayoutParams layoutParams= (LinearLayout.LayoutParams) getLayoutParams();
      //                layoutParams.leftMargin = getLeft() + offsetX;
      //                layoutParams.topMargin = getTop() + offsetY;
      //                setLayoutParams(layoutParams);
      
                      //使用MarginLayoutParams
      //                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
      //                layoutParams.leftMargin = getLeft() + offsetX;
      //                layoutParams.topMargin = getTop() + offsetY;
      //                setLayoutParams(layoutParams);
                      //使用scrollBy
                      ((View)getParent()).scrollBy(-offsetX,-offsetY);
                      break;
              }
      
              return true;
          }
          public void smoothScrollTo(int destX,int destY){
              int scrollX=getScrollX();
              int delta=destX-scrollX;
              //1000秒內滑向destX
              mScroller.startScroll(scrollX,0,delta,0,2000);
              invalidate();
          }
          @Override
          public void computeScroll() {
              super.computeScroll();
              if(mScroller.computeScrollOffset()){
                  ((View) getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
                  //通過不斷的重繪不斷的調用computeScroll方法
                  invalidate();
              }
      
          }
      }
      View Code

       

      posted on 2016-11-05 16:19  安卓筆記俠  閱讀(534)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 在线观看热码亚洲av每日更新| 久久亚洲美女精品国产精品| 国产尤物精品自在拍视频首页 | 日韩永久永久永久黄色大片| 亚洲性日韩精品一区二区 | 五月婷婷中文字幕| 精品乱码一区二区三四区视频 | 极品美女自拍偷精品视频| 乐平市| 日韩人妻一区中文字幕| 2021国产精品视频网站| 婷婷色爱区综合五月激情韩国| 久久91精品牛牛| 国内精品视频一区二区三区八戒| 国产亚洲精品日韩av在| 亚洲成av人无码免费观看| 国产精品伦人视频免费看| 337p西西人体大胆瓣开下部| 开心五月激情综合久久爱| 一区二区三区国产不卡| 中国CHINA体内裑精亚洲日本| 精品国产成人a在线观看| 国产人成777在线视频直播| 国产成人一区二区三区视频免费| 欧美国产精品啪啪| jizz国产免费观看| 国产午夜鲁丝片av无码| 国产第一区二区三区精品| 国产99在线 | 免费| 黑人巨大AV在线播放无码| 成人一区二区人妻不卡视频| 国产成年码av片在线观看| 亚洲国产精品色一区二区| 永定县| 国产偷窥熟女高潮精品视频| 久久亚洲人成网站| 亚洲 欧美 唯美 国产 伦 综合| 国产精品久久久国产盗摄| 黑人玩弄人妻中文在线| 中文字幕在线精品国产| 国产精品无码av不卡|