Android Scroller的使用方法
本文實(shí)例為大家分享了Android Scroller的使用方法,供大家參考,具體內(nèi)容如下
1、scrollTo和ScrollByView類(lèi)定義了兩個(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)的ViscousFluidInterpolator2、調(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的startScrollif(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.ScrollableLinearLayoutandroid: android:layout_width='match_parent'android:layout_height='200dp'android:gravity='center_vertical'android:orientation='vertical'android:background='#FFAAAA'><Button android: 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í)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. ThinkPHP5 通過(guò)ajax插入圖片并實(shí)時(shí)顯示(完整代碼)2. javascript設(shè)計(jì)模式 ? 建造者模式原理與應(yīng)用實(shí)例分析3. Python使用oslo.vmware管理ESXI虛擬機(jī)的示例參考4. IDEA EasyCode 一鍵幫你生成所需代碼5. Java構(gòu)建JDBC應(yīng)用程序的實(shí)例操作6. 一篇文章帶你了解JavaScript-對(duì)象7. IntelliJ IDEA設(shè)置條件斷點(diǎn)的方法步驟8. Express 框架中使用 EJS 模板引擎并結(jié)合 silly-datetime 庫(kù)進(jìn)行日期格式化的實(shí)現(xiàn)方法9. python flask框架快速入門(mén)10. 解決Python paramiko 模塊遠(yuǎn)程執(zhí)行ssh 命令 nohup 不生效的問(wèn)題
