Android 實(shí)現(xiàn)滑動(dòng)的六種方式
1、效果視頻
2、剖析Android坐標(biāo)系
滑動(dòng)的本質(zhì)是移動(dòng),滑動(dòng)的原理就是通過(guò)不斷的改變View的坐標(biāo)而實(shí)現(xiàn)。
Android
系統(tǒng)提供了很多方法獲取坐標(biāo)值,可以將其分為兩種類別,具體如下:
View 提供的獲取坐標(biāo)的方法:
getTop():
獲取到的是View自身的頂邊到其父布局頂邊的距離getLeft():
獲取到的是View自身的左邊到其父布局左邊的距離getRight():
獲取到的是View自身的右邊到其父布局左邊的距離getBottom():
獲取到的是View自身的底邊到其父布局頂邊的距離
MotionEvent 提供的方法:
getX():
獲取點(diǎn)擊事件距離控件左邊的距離,即視圖坐標(biāo)getY():
獲取點(diǎn)擊事件距離控件頂邊的距離,即視圖坐標(biāo)getRawX():
獲取點(diǎn)擊事件距離整個(gè)屏幕左邊的距離,即絕對(duì)坐標(biāo)getRawY():
獲取點(diǎn)擊事件距離整個(gè)屏幕頂邊的距離,即絕對(duì)坐標(biāo)
3、實(shí)現(xiàn)方式
3.1 layout
使用絕對(duì)坐標(biāo)系,每次執(zhí)行移動(dòng)邏輯后需要重新設(shè)置初始化坐標(biāo)
@Override public boolean onTouchEvent(MotionEvent event) { int rawX = (int) (event.getRawX()); int rawY = (int) (event.getRawY()); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: lastX = rawX; lastY = rawY; break; case MotionEvent.ACTION_MOVE: int offsetX = rawX - lastX; int offsetY = rawY - lastY; layout( getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY ); lastX = rawX; lastY = rawY; break; case MotionEvent.ACTION_UP: break; } return true; }
3.2 scrollBy
@Override 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; ((View) getParent()).scrollBy( -offsetX, -offsetY ); break; case MotionEvent.ACTION_UP: break; } return true; }
3.3 offsetLeftAndRight offsetTopAndButton
@Override 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; offsetLeftAndRight( offsetX ); offsetTopAndBottom( offsetY ); break; case MotionEvent.ACTION_UP: break; } return true; }
3.4 LayoutParams
通過(guò)getLayoutParams()
獲取LayoutParams
時(shí),需要根據(jù)不同的父類型使用設(shè)置不同的類型,比如父布局為L(zhǎng)inearLayout則設(shè)置類型為 LinearLayout.LayoutParams
@Override 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; LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)getLayoutParams(); layoutParams.leftMargin = getLeft()+offsetX; layoutParams.topMargin = getTop()+offsetY; setLayoutParams( layoutParams ); break; case MotionEvent.ACTION_UP: break; } return true; }
更方便的是直接使用ViewGroup
,不需要判斷父布局類型
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)getLayoutParams(); layoutParams.leftMargin = getLeft()+offsetX; layoutParams.topMargin = getTop()+offsetY; setLayoutParams( layoutParams );
3.5 Scroller
初始化Scroller:
scroller = new Scroller( context );
重寫(xiě)computeScroll()
方法
使用computeScrollOffset()
判定是否完成了整個(gè)滑動(dòng):
@Override public void computeScroll() { if (scroller.computeScrollOffset()) { ((View) getParent()).scrollTo( scroller.getCurrX(), scroller.getCurrY() ); invalidate(); } super.computeScroll(); } @Override public boolean onTouchEvent(MotionEvent mv) { View parent = (View) getParent(); switch (mv.getAction()) { case MotionEvent.ACTION_DOWN: lastX = (int) mv.getX(); lastY = (int) mv.getY(); break; case MotionEvent.ACTION_MOVE: int upX = (int) (mv.getX() - lastX); int upY = (int) (mv.getY() - lastY); parent.scrollBy( -upX, -upY ); break; case MotionEvent.ACTION_UP: scroller.startScroll( parent.getScrollX(), parent.getScrollY(), -parent.getScrollX(), -parent.getScrollY(), 1000 ); invalidate(); break; } return super.onTouchEvent( mv ); }
3.6 平移動(dòng)畫(huà)
效果視頻:
private void InitAnimation(){ animation = new TranslateAnimation( 0,200,0,200 ); animation.setDuration( 1000 ); }
moveButton.startAnimation( animation );
到此這篇關(guān)于Android 實(shí)現(xiàn)滑動(dòng)的六種方式的文章就介紹到這了,更多相關(guān)Android 實(shí)現(xiàn)滑動(dòng)的方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android 滑動(dòng)小圓點(diǎn)ViewPager的兩種設(shè)置方法詳解流程
- Android深入探究自定義View之嵌套滑動(dòng)的實(shí)現(xiàn)
- Android實(shí)現(xiàn)背景顏色滑動(dòng)漸變效果的全過(guò)程
- Android直播軟件搭建之實(shí)現(xiàn)背景顏色滑動(dòng)漸變效果的詳細(xì)代碼
- Android HorizontalScrollView滑動(dòng)與ViewPager切換案例詳解
- Android滑動(dòng)拼圖驗(yàn)證碼控件使用方法詳解
- Android之FanLayout制作圓弧滑動(dòng)效果
- Android之ArcSlidingHelper制作圓弧滑動(dòng)效果
- Android 滑動(dòng)Scrollview標(biāo)題欄漸變效果(仿京東toolbar)
相關(guān)文章
Android窗口小部件基礎(chǔ)編寫(xiě)代碼實(shí)例
這篇文章主要介紹了Android窗口小部件基礎(chǔ)編寫(xiě)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11Android 實(shí)現(xiàn)九宮格抽獎(jiǎng)功能
這篇文章主要介紹了Android 實(shí)現(xiàn)九宮格抽獎(jiǎng)功能,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03Android插件化-RePlugin項(xiàng)目集成與使用詳解
這篇文章主要介紹了Android插件化-RePlugin項(xiàng)目集成與使用詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11Android UI控件之ListView實(shí)現(xiàn)圓角效果
這篇文章主要為大家詳細(xì)介紹了Android UI控件之ListView實(shí)現(xiàn)圓角效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android浮動(dòng)窗口實(shí)現(xiàn)原理及代碼實(shí)例
這篇文章主要介紹了Android浮動(dòng)窗口實(shí)現(xiàn)原理及代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07android利用websocket協(xié)議與服務(wù)器通信
這篇文章主要為大家詳細(xì)介紹了android利用websocket協(xié)議與服務(wù)器通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03Android Studio 4.0 正式發(fā)布在Ubuntu 20.04中安裝的方法
這篇文章主要介紹了Android Studio 4.0 正式發(fā)布如何在Ubuntu 20.04中安裝,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Okhttp、Retrofit進(jìn)度獲取的方法(一行代碼搞定)
本篇文章主要介紹了Okhttp、Retrofit進(jìn)度獲取的方法(一行代碼搞定),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04