欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android View移動(dòng)的3種方式總結(jié)

 更新時(shí)間:2016年09月18日 08:43:28   投稿:daisy  
這篇文章主要給大家介紹了Android View移動(dòng)的三種方式,在介紹這三種方式之前先介紹了Android坐標(biāo)系的定義規(guī)則以及View的一些位置參數(shù)。有需要的朋友們可以參考借鑒。

前言

在A(yíng)ndroid開(kāi)發(fā)中,View一直是Android開(kāi)發(fā)人員的一塊心病,一方面想要進(jìn)階,一方面又害怕進(jìn)階,可以說(shuō)Android的View是進(jìn)階路上的最大絆腳石,因?yàn)樗婕暗臇|西太多了,比如本次我們此次要寫(xiě)的View移動(dòng),另外還包括View的觸摸事件的傳遞,創(chuàng)建自定義View,這些都是極其重要且不得不面對(duì)的難題。但是無(wú)論如何,現(xiàn)在不克服的困難將來(lái)就會(huì)被困難克服。

在此之前,我們還是先了解Android坐標(biāo)系的定義規(guī)則以及View的一些位置參數(shù)。

Android坐標(biāo)系

View的位置及大小是由四個(gè)參數(shù)決定,即left、top、right、bottom,并且這四個(gè)參數(shù)都是相對(duì)于其父View的。

int width = right-left;
 int height = bottom-top;

在A(yíng)ctivity中布局完成后,我們可以通過(guò)View一些方法獲取這些參數(shù)信息:

//left,top,right,bottom值的獲取
 int left = getLeft();
 int top = getTop();
 int right = getRight();
 int bottom = getBottom();

另外Android 3.0以后加入x,y,translationX,translationY等參數(shù)。(x,y)表示為View在ViewGroup中左上角的x,y的值,translationX,translationY在用于平移一個(gè)View。默認(rèn)是都為0,在調(diào)用了View的setTranslationX()/setTranslationY()之后發(fā)生改變。

//x,y,translationX,translationY參數(shù)的獲取
 int x = getX();
 int y = getY();
 int translationX = getTranslationX();
 int translationY = getTranslationY();

PS:調(diào)用View的setTranslationX()setTranslationY()方法雖然可以使得View平移指定距離,但是這一過(guò)程是瞬間完成的。為了使View的移動(dòng)使得更為平滑,因此可以使用View的屬性動(dòng)畫(huà)來(lái)指定translationX和translationY。

ObjectAnimator valueAnimator = ObjectAnimator.ofFloat(textView, "translationX", 200);
 valueAnimator.setDuration(2000);
 valueAnimator.start();

另外,如果給View設(shè)置setTranslationX()setTranslationY()后,如果設(shè)置的值沒(méi)有發(fā)生變化,那么其只會(huì)移動(dòng)一次,即首次指定的移動(dòng)距離。查看源碼后我們發(fā)現(xiàn)原因:原來(lái)在設(shè)置值之后其會(huì)將設(shè)置進(jìn)去的值和當(dāng)前的translationX,translationY進(jìn)行對(duì)比,不一致時(shí)才進(jìn)行移動(dòng)。

了解了View的一些基本參數(shù)之后,我們看關(guān)于View的三種移動(dòng)方式。

一、使用Android系統(tǒng)提供的scrollTo()/scrollBy()方法實(shí)現(xiàn)View的移動(dòng)。

不管是scrollTo()還是scrollBy()其移動(dòng)的本質(zhì)都是View/ViewGroup中的內(nèi)容。并且其移動(dòng)的過(guò)程是瞬間完成的,因此,為了實(shí)現(xiàn)更好的移動(dòng)效果,他需要與Scroller類(lèi)結(jié)合使用。另外,它不同于上面的Translation,移動(dòng)的是View本身,這一點(diǎn)需要好好理解一下。

scrollTo()scrollBy()都是View中的方法, 不是Scroller中的方法 ,但是控制View的平滑移動(dòng)與Scroller類(lèi)密不可分。

scrollTo() :指是的移動(dòng)的絕對(duì)位置,如果位置沒(méi)有變化,多次調(diào)用則不會(huì)起作用。

scrollTo移動(dòng)過(guò)程示意圖

scrollBy() :其本質(zhì)依然是調(diào)用的scrollTo() ,指的的移動(dòng)當(dāng)前位置的相對(duì)距離(每次都是先將當(dāng)前的位置和設(shè)置的距離相加之和調(diào)用scrollTo(),這樣如果你多次調(diào)用,你就會(huì)發(fā)現(xiàn)其每次都會(huì)移動(dòng)一段距離,這是和scrollTo()的本質(zhì)區(qū)別)

scrollBy移動(dòng)過(guò)程示意圖

PS:關(guān)于上面兩張圖,其實(shí)一直以來(lái),我自己都沒(méi)完全搞明白什么相對(duì)絕對(duì),所以?xún)蓮埵謭D可能會(huì)讓人更容易理解。還有就是scrollTo()scrollBy()移動(dòng)方向問(wèn)題,上面我們已經(jīng)畫(huà)過(guò)Android的坐標(biāo)系,x軸左→右為正,y軸從上→下為正。但是這并不適用于scrollTo和scrollBy,scrollTo和scrollBy剛好相反,即x軸左→右為負(fù),y軸從上→下為負(fù),簡(jiǎn)直是有點(diǎn)坑爹啊。

Scroller類(lèi)分析:而為什么使用Scroller類(lèi)中的方法可以對(duì)View/ViewGroup的內(nèi)容進(jìn)行移動(dòng)呢?下面我們?cè)囍治鲆幌隆?br />

首先

我們創(chuàng)建一個(gè)Scroller類(lèi)的對(duì)象mScroller。

然后

要使View在規(guī)定的時(shí)間中移動(dòng)到指定的位置,我們會(huì)調(diào)用startScroll()方法,startScroll()Scroller類(lèi)中的方法,另外Scroller類(lèi)中還有一個(gè)filing()方法也是很常用的,它主要是處理平滑的移動(dòng),一般營(yíng)造滑動(dòng)之后的慣性效果,使得View的移動(dòng)更逼真。下面我們看startScroll()的源碼:

//其接收四個(gè)/五個(gè)參數(shù)。如果duration不設(shè)置,則為默認(rèn)。這四個(gè)參數(shù)都不難理解,這里不再做解釋。
 public void startScroll(int startX, int startY, int dx, int dy, int duration) { 
 ...
 }

而一般我們調(diào)用這個(gè)方法后都要去調(diào)View的 invalidate() ,這個(gè)方法可以觸發(fā)View的draw()方法。而draw()中調(diào)用了 computeScroll() ,源碼中我們發(fā)現(xiàn)computeScroll()是個(gè)空方法,這也是為什么我們需要重寫(xiě) computeScroll()方法的原因。因?yàn)檎诘囊苿?dòng)操作就是在computeScroll()中進(jìn)行的。

@Override
 public void computeScroll() {
 if (mScroller.computeScrollOffset()) {
  scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
  //必須調(diào)用View的postInvalidate()/invalidate(),如果不加會(huì)導(dǎo)致View的移動(dòng)只會(huì)第一幀。
  postInvalidate();
 }
 super.computeScroll();
 }

上面我們看到Scroller類(lèi)中還有一個(gè)computeScrollOffset()方法,它又是干啥的呢?它的主要作用就是判斷mCurrX,和mCurrY是否有改變,有則返回true,無(wú)則返回false。通過(guò)這個(gè)方法的判斷可以指點(diǎn)是否需要持續(xù)的調(diào)用scrollTo()去移動(dòng)View。這里再給出一個(gè)示例,使用scrollTo()讓View跟著手指移動(dòng):

public class CuView extends LinearLayout {

 private float mStartX;
 private float mStartY;
 private Scroller mScroller;
 /**
 * 第一次滑動(dòng)是否完成
 */
 private boolean isFirstFinish;

 public CuView(Context context) {
 super(context);
 init(context);
 }

 public CuView(Context context, AttributeSet attrs) {
 super(context, attrs);
 init(context);
 }

 private void init(Context context) {
 mScroller = new Scroller(context);
 }

 public CuView(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 init(context);
 }

 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public CuView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
 super(context, attrs, defStyleAttr, defStyleRes);
 init(context);
 }


 /**
 * 讓View跟著你的手指走吧
 * @param event
 * @return
 */
 @Override
 public boolean onTouchEvent(MotionEvent event) {
 int action = event.getAction();
 switch (action) {
  case MotionEvent.ACTION_DOWN:
  /**
   * 第一次移動(dòng)完成后,我們不需要再去拿開(kāi)始的位置了,否則造成View重新移動(dòng)的最起始的位置。
   */
  if (!isFirstFinish) {
   mStartX = event.getRawX();
   mStartY = event.getRawY();
  }
  break;
  case MotionEvent.ACTION_MOVE:
  scrollTo((int) (mStartX - event.getRawX()), (int) (mStartY - event.getRawY()));
  break;
  case MotionEvent.ACTION_UP:
  //第一次移動(dòng)完成
  isFirstFinish = true;
  break;
 }
 return true;
 }

 /**
 * 測(cè)試startScroll
 */
 public void startScroll() {
 /**
  * 注意Scroller移動(dòng)方向,
  */
 mScroller.startScroll(20, 20, -500, -500, 5000);
 invalidate();
 }

 @Override
 public void computeScroll() {
 if (mScroller.computeScrollOffset()) {
  scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
  invalidate();
 }
 super.computeScroll();
 }
}

二、使用動(dòng)畫(huà)實(shí)現(xiàn)View的移動(dòng)。

這里包括View的Tween Animation/Frame Animation,以及3.0之后加入的Property Animation。其移動(dòng)的是View的一個(gè)映像,View本身的位置及大小并沒(méi)有發(fā)生任何改變。

三、設(shè)置View的LayoutParams來(lái)移動(dòng)View

LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
 layoutParams.leftMargin = 50;
 textView.requestLayout();

總結(jié)

以上就是總結(jié)Android View移動(dòng)的3種方式的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家開(kāi)發(fā)Android的時(shí)候能有所幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • Studio 編譯報(bào)錯(cuò):compileSdkVersion ''android-24'' requires JDK 1.8 or later to compile.的解決辦法

    Studio 編譯報(bào)錯(cuò):compileSdkVersion ''android-24'' requires JDK 1.

    今天小編就為大家分享一篇關(guān)于Studio編譯報(bào)錯(cuò):compileSdkVersion 'android-24' requires JDK 1.8 or later to compile.的解決辦法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • camera錄制視頻的縮略圖獲取原理心得分享

    camera錄制視頻的縮略圖獲取原理心得分享

    camera錄制的視頻的縮略圖如何獲取,想必有很多的朋友都不會(huì)吧,下面與大家分享下獲取的原理,感興趣的你可不要錯(cuò)過(guò)了哈
    2013-06-06
  • Android中主要資源文件及文件夾介紹

    Android中主要資源文件及文件夾介紹

    在A(yíng)ndroid項(xiàng)目文件夾里面,主要的資源文件是放在res文件夾里面的,下面為大家詳細(xì)介紹下各個(gè)資源文件的作用,感興趣的朋友可以參考下哈
    2013-06-06
  • android獲取圖片尺寸的兩種方式及bitmap的縮放操作

    android獲取圖片尺寸的兩種方式及bitmap的縮放操作

    這篇文章主要介紹了android獲取圖片尺寸的兩種方式及bitmap的縮放操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Android ListView下拉刷新上拉自動(dòng)加載更多DEMO示例

    Android ListView下拉刷新上拉自動(dòng)加載更多DEMO示例

    這篇文章主要介紹了Android ListView下拉刷新上拉自動(dòng)加載更多DEMO示例的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Android中l(wèi)ayer-list基本使用詳解

    Android中l(wèi)ayer-list基本使用詳解

    這篇文章主要介紹了Android中l(wèi)ayer-list基本使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Android仿微信輸入框效果的實(shí)現(xiàn)代碼

    Android仿微信輸入框效果的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Android仿微信輸入框效果的實(shí)現(xiàn)代碼,需要的朋友參考下吧
    2017-05-05
  • 使用Android的OkHttp包實(shí)現(xiàn)基于HTTP協(xié)議的文件上傳下載

    使用Android的OkHttp包實(shí)現(xiàn)基于HTTP協(xié)議的文件上傳下載

    OkHttp(GitHub主頁(yè)https://github.com/square/okhttp)是近來(lái)人氣攀升的一款安卓第三方HTTP包,這里我們來(lái)講解一下如何使用Android的OkHttp包實(shí)現(xiàn)基于HTTP協(xié)議的文件上傳下載:
    2016-07-07
  • Android非異常情況下的Activity生命周期分析

    Android非異常情況下的Activity生命周期分析

    這篇文章主要介紹了Android非異常情況下的Activity生命周期分析,幫助大家更好的理解和使用Android,感興趣的朋友可以了解下
    2021-01-01
  • Android中View位置和觸摸事件詳解

    Android中View位置和觸摸事件詳解

    這篇文章主要給大家介紹了關(guān)于A(yíng)ndroid中View位置和觸摸事件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08

最新評(píng)論