日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

自定义 View 循环滚动刻度控件

發(fā)布時(shí)間:2023/11/29 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义 View 循环滚动刻度控件 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

LoopScaleView

先看效果圖:

enter description here

LoopScaleView 是一個(gè)自定義的刻度尺風(fēng)格的選值控件,從上面的動(dòng)圖大家可以看到 LoopScaleView 的運(yùn)行效果.可以設(shè)置屏幕內(nèi)顯示的刻度數(shù),也可以設(shè)置每一個(gè)刻度代表的值得大小。

LoopScaleView.class

Nested class

OnValueChangeListener刻度取值監(jiān)聽接口

Public methods

方法名返回值類型說(shuō)明
getItemsCount()int獲取總的刻度數(shù)
setCursorColor(int color)void設(shè)置游標(biāo)顏色(游標(biāo)不采用圖片時(shí))
setCursorWidth(int width)void設(shè)置游標(biāo)寬度(同上)
setCursorMap(Bitmap map)void設(shè)置圖片作為游標(biāo)
setScaleWidth(int scaleWidth)void設(shè)置刻度寬度
setShowItemSize(int showItemSize)void設(shè)置屏幕內(nèi)可見的大刻度數(shù)
setScaleHeight(float scaleHeight)void設(shè)置刻度的高度
setLineColor(int lineColor)void設(shè)置底部直線的顏色
setScaleTextColor(int scaleTextColor)void設(shè)置刻度標(biāo)值的顏色
setScaleTextSize(int scaleTextSize)void設(shè)置刻度標(biāo)值的文字大小
setMaxValue(int maxValue)void設(shè)置最大值
setOneItemValue(int oneItemValue)void設(shè)置一個(gè)刻度表示的值的大小
setCurrentValue(int currValue)void設(shè)置當(dāng)前的值

分解剖析

  • onMeasure 方法中初始化一個(gè)刻度的像素寬度,整個(gè)視圖的寬度 @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);viewHeight = MeasureSpec.getSize(heightMeasureSpec);//一個(gè)小刻度的寬度(十進(jìn)制,每5個(gè)小刻度為一個(gè)大刻度)scaleDistance = getMeasuredWidth() / (showItemSize * 5);//尺子長(zhǎng)度總的個(gè)數(shù)*一個(gè)的寬度viewWidth = maxValue / oneItemValue * scaleDistance;maxX = getItemsCount() * scaleDistance;minX = -maxX;}復(fù)制代碼
  • onDraw() 方法重寫繪制 ScaleView 的視圖 @Overrideprotected void onDraw(Canvas canvas) {canvas.clipRect(getPaddingStart(), getPaddingTop(), getWidth() - getPaddingRight(), viewHeight - getPaddingBottom());// 繪制底部線條drawLine(canvas);// 繪制游標(biāo)drawCursor(canvas);paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setStrokeWidth(scaleWidth);// 繪制反向的一個(gè)刻度尺for (int i = 0; i < maxValue / oneItemValue; i++) {//drawScale 為繪制刻度線的方法drawScale(canvas, i, -1);}//繪制正向的一個(gè)刻度尺for (int i = 0; i < maxValue / oneItemValue; i++) {//drawScale 為繪制刻度線的方法drawScale(canvas, i, 1);}}復(fù)制代碼可以看出上面的繪制過(guò)程,實(shí)際上是繪制出了兩個(gè)刻度尺。經(jīng)過(guò)上面的步驟,靜止?fàn)顟B(tài)下的 ScaleView 已經(jīng)繪制完成,接下來(lái)就是要讓他動(dòng)起來(lái)了
  • 手勢(shì)識(shí)別來(lái)處理滑動(dòng)
    在 onTouchEvent() 方法中將觸摸事件交給手勢(shì)識(shí)別 GestureDetector.SimpleOnGestureListener 來(lái)處理:

    /*** 滑動(dòng)手勢(shì)處理*/private GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {@Overridepublic boolean onDown(MotionEvent e) {return true;}//滾動(dòng)事件public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {scrollView(distanceX);return true;}//快速滑動(dòng)時(shí)間public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {if (!mScroller.computeScrollOffset()) {mScroller.fling((int) currLocation, 0, (int) (-velocityX / 1.5), 0, minX, maxX, 0, 0);setNextMessage(0);}return true;}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return super.onSingleTapUp(e);}};復(fù)制代碼

    上述代碼主要注意兩個(gè)地方:onScroll() 和 onFling()。當(dāng)正常左右滑動(dòng)時(shí),觸發(fā) onScroll 方法調(diào)用 srcollView(float distance) 對(duì)整個(gè)視圖進(jìn)行重繪。當(dāng)快速慣性滑動(dòng)時(shí)通過(guò) Scroller 讓慣性滑動(dòng)變得流暢,慣性滑動(dòng)的狀態(tài)更新是通過(guò) Handler 進(jìn)行不斷的查詢 Scroller 的執(zhí)行狀態(tài)得到的,當(dāng) Scroller 執(zhí)行完慣性滑動(dòng)的動(dòng)畫到達(dá)目的地時(shí),停止 Handler 的查詢?nèi)蝿?wù),當(dāng) onFling 多次觸發(fā)時(shí)只會(huì)執(zhí)行第一次的狀態(tài)。

  • 循環(huán)滾動(dòng)的實(shí)現(xiàn)
    開始說(shuō)到的繪制了正向反向兩個(gè)方向的刻度尺即是為了實(shí)現(xiàn)循環(huán)滾動(dòng)而設(shè)定的,在 drawScale() 方法中有如下代碼: if (currLocation + showItemSize / 2 * 5 * scaleDistance >= viewWidth) {currLocation = -showItemSize / 2 * 5 * scaleDistance;float speed = mScroller.getCurrVelocity();mScroller.fling((int) currLocation, 0, (int) speed, 0, minX, maxX, 0, 0);setNextMessage(0);} else if (currLocation - showItemSize / 2 * 5 * scaleDistance <= -viewWidth) {currLocation = showItemSize / 2 * 5 * scaleDistance;float speed = mScroller.getCurrVelocity();mScroller.fling((int) currLocation, 0, (int) speed, 0, minX, maxX, 0, 0);setNextMessage(0);}復(fù)制代碼當(dāng) currLocation 加上可視視圖一半的距離大于刻度尺的寬度 viewWidth 或者 currLocation 減去可視視圖一半的距離小于 -viewWidth 時(shí)(即正向或者反向滑到最大/最小值時(shí))通過(guò)為 currLocation 重新賦值將刻度值重置,來(lái)達(dá)到循環(huán)滾動(dòng)的目的.如果到達(dá)臨界點(diǎn)時(shí)是在 Scroller 執(zhí)行快速滑動(dòng)的過(guò)程則重置之后需要再為 Scroller 重新設(shè)置初速度來(lái)達(dá)到流暢的滑動(dòng).
    基本思路就是上面所說(shuō)的這樣了,詳細(xì)操作大家自己查看 LoopScaleView 的源碼。

    接入使用

    project's build.gradle (工程的 build.gradle)allprojects {repositories {jcenter()maven{url "http://dl.bintray.com/huxinyu/maven"}} }復(fù)制代碼module's build.gradle (模塊的build.gradle)dependencies {compile 'com.pandaq:loopscale:1.0.1' }復(fù)制代碼
  • xml 文件中進(jìn)行屬性配置,這些屬性也可以通過(guò) Java 代碼進(jìn)行修改 <com.pandaq.loopscaleview.LoopScaleViewandroid:id="@+id/lsv_4"android:layout_width="match_parent"android:layout_height="50dp"android:layout_margin="8dp"android:background="@drawable/loopscaleview_bg"android:padding="8dp"app:cursorColor="@color/colorAccent"app:maxShowItem="4"app:maxValue="1000"app:oneItemValue="5"app:scaleTextColor="@color/colorPrimary"/>復(fù)制代碼

    最后

    覺得本文對(duì)你有幫助
    簡(jiǎn)書PandaQ404
    掘金PandaQ
    GithubPandaQAQ
    持續(xù)分享中,歡迎關(guān)注和 star。。。

總結(jié)

以上是生活随笔為你收集整理的自定义 View 循环滚动刻度控件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。