dev控件swiftplot图滚动方法_无限轮播图使用Scroller就这么简单
前言
這幾天又拾起老本行,復(fù)習(xí)復(fù)習(xí)Android,才發(fā)現(xiàn)忘的差不多了,上午做了一個小Demo,配合Scroller做了一個輪播圖,效果如下,但是不知為何,錄制的GIF成這樣,湊乎一下看看。
原理是繼承ViewGroup,然后自己擺放子View,也就是擺放在一條線上,開啟一個定時器,每隔X秒通過Scroller進(jìn)行滾動,當(dāng)然還有處理Touch事件,在手指按下的時候定時器停止,抬起的時候定時器重新啟動。
Scroller簡介
我們知道View中提供了scrollTo()和scrollBy()兩個方法用來滾動,也就是說任何一個控件都是可以滾動的,他兩的區(qū)別在于,scrollBy()讓View相對于當(dāng)前的位置滾動一段距離,scrollTo()則是讓View相對于初始的位置滾動一段距離。
注意這里的滾動是內(nèi)容的滾動,不是自身位置。
還有一個類是Scroller,用于處理滾動效果的工具類,但是這個類并不能直接使View滾動,而是提供計算滾動的值,我們拿到這個值在調(diào)用scrollTo或scrollBy進(jìn)行滾動。
Scroller的兩個重要方法是startScroll和computeScrollOffset,startScroll()方法是用來初始化滾動數(shù)據(jù)的,第一個參數(shù)是滾動開始時X的坐標(biāo),第二個參數(shù)是滾動開始時Y的坐標(biāo),如果我們的控件只支持X軸滾動,那么Y永遠(yuǎn)是0,,第三個參數(shù)是橫向滾動的距離,第四個參數(shù)是縱向滾動的距離,通常這個方法后面會調(diào)用invalidate()方法來刷新界面。
最后就是重寫computeScroll()方法,這個方法根據(jù)注釋的意思是在父級請求子級更新其mScrollX值時候調(diào)用,在這個方法下通過不斷調(diào)用Scroller的computeScrollOffset()方法來判斷滾動操作是否完成了,如果還沒完成的話,那就繼續(xù)調(diào)用scrollTo()方法,傳入Scroller的curX和curY,這樣就完成了內(nèi)容的平滑滾動。
另外Scroller還支持Interpolator,使?jié)L動更具有效果。
實現(xiàn)
package?com.example.androiddemo;import?android.content.Context;
import?android.os.Handler;
import?android.os.Message;
import?android.util.AttributeSet;
import?android.util.Log;
import?android.view.MotionEvent;
import?android.view.View;
import?android.view.ViewGroup;
import?android.widget.Scroller;
import?androidx.annotation.NonNull;
import?java.util.Timer;
import?java.util.TimerTask;
public?class?BannerView?extends?ViewGroup?{
????private?static?final?int?INVALIDATE_MSG?=?1000;
????private?static?final?int?DEFAULT_DURATION?=?1000;
????private?static?final?int?DEFAULT_PERIOD?=?2000;
????private?static?final?String?TAG?=?"TAG";
????private?int?mPeriod;
????private?int?mDuration;
????private?boolean?isTouch?=?false;
????private?int?mDownX;
????private?Scroller?mScroller;
????private?Timer?mTimer;
????private?Handler?handler?=?new?Handler()?{
????????@Override
????????public?void?handleMessage(@NonNull?Message?msg)?{
????????????super.handleMessage(msg);
????????????switch?(msg.what)?{
????????????????case?INVALIDATE_MSG:
????????????????????nextItem();
????????????????????break;
????????????}
????????}
????};
????public?BannerView(Context?context)?{
????????super(context);
????????init();
????}
????public?BannerView(Context?context,?AttributeSet?attrs)?{
????????super(context,?attrs);
????????init();
????}
????public?BannerView(Context?context,?AttributeSet?attrs,?int?defStyleAttr)?{
????????super(context,?attrs,?defStyleAttr);
????????init();
????}
????private?void?init()?{
????????mPeriod?=?DEFAULT_PERIOD;
????????mDuration?=?DEFAULT_DURATION;
????????mScroller?=?new?Scroller(getContext());
????????startTimer(0);
????}
????private?void?startTimer(int?delay)?{
????????mTimer?=?new?Timer();
????????mTimer.schedule(new?TimerTask()?{
????????????@Override
????????????public?void?run()?{
????????????????if?(!isTouch)
????????????????????handler.sendEmptyMessage(INVALIDATE_MSG);
????????????}
????????},?delay,?mPeriod);
????}
????private?void?nextItem()?{
????????mScroller.startScroll(getScrollX(),?0,?getMeasuredWidth(),?0,?mDuration);
????????invalidate();
????}
????@Override
????protected?void?onFinishInflate()?{
????????super.onFinishInflate();
????}
????@Override
????protected?void?onLayout(boolean?changed,?int?l,?int?t,?int?r,?int?b)?{
????????int?left?=?0;
????????for?(int?i?=?0;?i?????????????View?childAt?=?getChildAt(i);
????????????childAt.layout(left,?t,?r?+?left,?b);
????????????left?+=?r;
????????}
????}
????@Override
????public?void?computeScroll()?{
????????if?(mScroller.computeScrollOffset())?{
????????????scrollTo(mScroller.getCurrX(),?mScroller.getCurrY());
????????????invalidate();
????????}
????????if?(mScroller.isFinished()?&&?getScrollX()?==?getMeasuredWidth()?*?(getChildCount()?-?1))?{
????????????Log.i(TAG,?"computeScroll:?"?+?getScrollX());
????????????scrollTo(0,?0);
????????}
????}
????@Override
????public?boolean?onTouchEvent(MotionEvent?event)?{
????????switch?(event.getAction())?{
????????????case?MotionEvent.ACTION_DOWN:
????????????????mDownX?=?(int)?event.getX();
????????????????mTimer.cancel();
????????????????break;
????????????case?MotionEvent.ACTION_UP:
????????????????int?targetIndex?=?(getScrollX()?+?getWidth()?/?2)?/?getWidth();
????????????????int?dx?=?targetIndex?*?getWidth()?-?getScrollX();
????????????????mScroller.startScroll(getScrollX(),?0,?dx,?0,?mDuration);
????????????????invalidate();
????????????????startTimer(mPeriod);
????????????????break;
????????????case?MotionEvent.ACTION_MOVE:
????????????????scrollBy((int)?(mDownX?-?event.getX()),?0);
????????????????mDownX?=?(int)?event.getX();
????????????????break;
????????}
????????return?true;
????}
}
<?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"android:background="#FFFFFF"android:paddingLeft="10dp"android:paddingRight="10dp"android:paddingTop="20dp"tools:context=".MainActivity">
????<RelativeLayoutandroid:layout_width="match_parent"android:layout_height="150dp">
????????<com.example.androiddemo.BannerViewandroid:layout_width="match_parent"android:layout_height="match_parent">
????????????<ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner1"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
????????????<ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner2"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
????????????<ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner3"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
????????????<ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner4"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
????????????<ImageViewandroid:scaleType="centerCrop"android:src="@drawable/banner1"android:layout_width="match_parent"android:layout_height="match_parent">ImageView>
????????com.example.androiddemo.BannerView>
????RelativeLayout>
LinearLayout>
- END - 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎
總結(jié)
以上是生活随笔為你收集整理的dev控件swiftplot图滚动方法_无限轮播图使用Scroller就这么简单的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像太宽无法输出请裁剪图像或降低分辨率然
- 下一篇: 从零开始学java 框架_从零开始学 J