Android Scroller的使用方法
本文實(shí)例為大家分享了Android Scroller的使用方法,供大家參考,具體內(nèi)容如下
1、scrollTo和ScrollBy
View類定義了兩個(gè)用于滾動(dòng)View內(nèi)容的方法:scrollTo和scrollBy:
/** * Set the scrolled position of your view. This will cause a call to * {@link #onScrollChanged(int, int, int, int)} and the view will be * invalidated. * @param x the x position to scroll to * @param y the y position to scroll to */ public void scrollTo(int x, int y) { if (mScrollX != x || mScrollY != y) { int oldX = mScrollX; int oldY = mScrollY; mScrollX = x; mScrollY = y; invalidateParentCaches(); onScrollChanged(mScrollX, mScrollY, oldX, oldY); if (!awakenScrollBars()) { postInvalidateOnAnimation(); } } } /** * Move the scrolled position of your view. This will cause a call to * {@link #onScrollChanged(int, int, int, int)} and the view will be * invalidated. * @param x the amount of pixels to scroll by horizontally * @param y the amount of pixels to scroll by vertically */ public void scrollBy(int x, int y) { scrollTo(mScrollX + x, mScrollY + y); }
可以看到scrollBy傳入的x和y參數(shù)實(shí)際上是X方向和Y方向的滾動(dòng)距離的增量,最終還是調(diào)用了scrollTo方法。而scrollTo方法中做了一些刷新和通知操作,最重要的是對(duì)mScrollX和mScrollY進(jìn)行了賦值。
在View的draw方法中,我們可以看到如下代碼:
int sx = 0; int sy = 0; if (!drawingWithRenderNode) { computeScroll(); sx = mScrollX; sy = mScrollY; } ... if (offsetForScroll) { canvas.translate(mLeft - sx, mTop - sy); }
也就是說(shuō),mScrollX和mScrollY最終是用在了內(nèi)容繪制的地方,其mLeft和mTop本身都沒(méi)有因?yàn)閟crollTo發(fā)生變化。scrollTo作用在View的內(nèi)容上,而不是View本身。
2、 computeScroll
在上面的View的draw方法的節(jié)選中我們看到在對(duì)mScrollX和mScrollY取值之前,調(diào)用了computeScroll方法。computeScroll方法聲明如下:
/** * Called by a parent to request that a child update its values for mScrollX * and mScrollY if necessary. This will typically be done if the child is * animating a scroll using a {@link android.widget.Scroller Scroller} * object. */ public void computeScroll() { }
根據(jù)注釋,computeScroll的典型用法是與Scroller結(jié)合使用實(shí)現(xiàn)內(nèi)容/字節(jié)點(diǎn)的滾動(dòng)動(dòng)畫(huà)。
3、Scroller的使用
Scroller事實(shí)上并不直接操作View的滾動(dòng),而是根據(jù)設(shè)置來(lái)計(jì)算當(dāng)前X和Y方向的距離。Scroller的一般使用步驟:
1、初始化Scroller,可以指定插值器,不指定則使用默認(rèn)的ViscousFluidInterpolator
2、調(diào)用Scroller#startScroll方法,開(kāi)始在一段時(shí)間內(nèi)不斷計(jì)算X和Y方向的滾動(dòng)
3、通知View刷新
4、在View#computeScroll中通過(guò)scrollTo實(shí)現(xiàn)真正的滾動(dòng)操作
5、通知View刷新
其中在滾動(dòng)執(zhí)行完成之前4和5會(huì)不斷地循環(huán),直至scroller.computeScrollOffset()返回false。
class ScrollableLinearLayout @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : LinearLayout(context, attrs, defStyleAttr) { private val scroller = Scroller(context, BounceInterpolator()) override fun computeScroll() { if(scroller.computeScrollOffset()) { // 真正實(shí)現(xiàn)滾動(dòng)操作的地方 scrollTo(scroller.currX, scroller.currY) // 刷新 invalidate() } } fun scroll() { // 調(diào)用Scroller的startScroll if(scrollX == 0) { scroller.startScroll(scrollX, scrollY, /*dx*/ -500, /*dy*/ 0, /*duration*/ 300) } else { scroller.startScroll(scrollX, scrollY, 500, 0, 300) } // 刷新 invalidate() } }
xml布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".scroller.activity.ScrollerSampleActivity"> <com.sahooz.customviewdemo.scroller.view.ScrollableLinearLayout android:id="@+id/sll" android:layout_width="match_parent" android:layout_height="200dp" android:gravity="center_vertical" android:orientation="vertical" android:background="#FFAAAA"> <Button android:id="@+id/btnScroll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Scroll" /> </com.sahooz.customviewdemo.scroller.view.ScrollableLinearLayout> </LinearLayout>
Activity
class ScrollerSampleActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_scroller_sample) val btnScroll = findViewById<Button>(R.id.btnScroll) btnScroll.setOnClickListener { findViewById<ScrollableLinearLayout>(R.id.sll).scroll() } } }
運(yùn)行結(jié)果:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用Scroller實(shí)現(xiàn)彈性滑動(dòng)效果
- Android用Scroller實(shí)現(xiàn)一個(gè)可向上滑動(dòng)的底部導(dǎo)航欄
- Android Scroller大揭秘
- Android Scroller及下拉刷新組件原理解析
- android使用 ScrollerView 實(shí)現(xiàn) 可上下滾動(dòng)的分類欄實(shí)例
- Android Scroller完全解析
- 深入理解Android中Scroller的滾動(dòng)原理
- Android程序開(kāi)發(fā)之UIScrollerView里有兩個(gè)tableView
- 詳解Android應(yīng)用開(kāi)發(fā)中Scroller類的屏幕滑動(dòng)功能運(yùn)用
- 詳解Android Scroller與computeScroll的調(diào)用機(jī)制關(guān)系
相關(guān)文章
Android簡(jiǎn)單實(shí)現(xiàn)圓盤(pán)抽獎(jiǎng)界面
這篇文章主要介紹了Android簡(jiǎn)單實(shí)現(xiàn)圓盤(pán)抽獎(jiǎng)界面的相關(guān)資料,需要的朋友可以參考下2016-01-01Android RenderScript實(shí)現(xiàn)高斯模糊
這篇文章主要為大家詳細(xì)介紹了Android RenderScript實(shí)現(xiàn)高斯模糊的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12Android獲取當(dāng)前手機(jī)網(wǎng)絡(luò)類型(2g、3g、4g、wifi)以及手機(jī)型號(hào)、版本號(hào)代碼
這篇文章主要介紹了Android獲取當(dāng)前手機(jī)網(wǎng)絡(luò)類型(2g、3g、4g、wifi)以及手機(jī)型號(hào)、版本號(hào)的相關(guān)資料,需要的朋友可以參考下2016-03-03基于Alarmmanager實(shí)現(xiàn)簡(jiǎn)單鬧鐘功能
這篇文章主要為大家詳細(xì)介紹了基于Alarmmanager實(shí)現(xiàn)簡(jiǎn)單鬧鐘功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Android優(yōu)化之電量?jī)?yōu)化的實(shí)現(xiàn)
這篇文章主要介紹了Android優(yōu)化之電量?jī)?yōu)化的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07簡(jiǎn)單實(shí)用的Android UI微博動(dòng)態(tài)點(diǎn)贊效果
這篇文章主要為大家詳細(xì)介紹了簡(jiǎn)單實(shí)用的Android UI微博動(dòng)態(tài)點(diǎn)贊效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10Android?音頻波形圖實(shí)現(xiàn)效果示例
這篇文章主要為大家介紹了Android?音頻波形圖實(shí)現(xiàn)效果示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08