欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android自定義超級炫酷的ViewPage指示器

 更新時間:2022年07月22日 09:25:35   作者:豬飛啦~  
由于應公司開發(fā)要求,有一個顏色漸變帶縮放的指示器,雖然網(wǎng)上很多大佬開源的指示器開源庫,但如果一直都是使用別人造的輪子,那么對于自身的能力是毫無提升作用的,即使是參考別人的,然后自己動手寫一遍那對于自身來說也是一種升華

思路

其實主要的內(nèi)容就是自定義一個帶顏色漸變的一個TextView,需要定義兩個畫筆,一個負責繪制未選中顏色,一個負責繪制選中時的顏色,各自繪制各自的區(qū)域就能繪制出一個帶顏色漸變的TextView

然后外部再包裝一層LinearLayout,水平排放每個tab,再監(jiān)聽Viewpage的滑動,根據(jù)滑動百分比來改變TextView的選中以及未選中區(qū)域的大小三,代碼實現(xiàn)

難點

繪制漸變色的TextView其實最重要的還是計算基線的位置,基線位置計算出來,那么就能調(diào)用drawText()方法去繪制我們的文本了,基線計算方式參考文末

代碼實現(xiàn)漸變TextView

@RequiresApi(Build.VERSION_CODES.Q)
class CustomTextView : AppCompatTextView {
    /**
     * 未選中畫筆
     */
    private var mUnSelectPaint: Paint? = null
    /**
     * 選中畫筆
     */
    private var mSelectPaint: Paint? = null
    /**
     * 滑動進度百分比
     */
    var mScrollProcess = 0f
    /**
     * 是否左邊滑動
     */
    var mScrollToLeft = true
    /**
     * 文字縮放比例
     */
    var mTextScale = 0.7f
    /**
     * 選中顏色以及未選中顏色
     */
    private var mSelectColor = Color.parseColor("#8966FF")
    private var mUnSelectColor = Color.parseColor("#DBC0FF")
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attributeSet: AttributeSet?) : this(context, attributeSet, 0)
    constructor(context: Context, attributeSet: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attributeSet,
        defStyleAttr
    ) {
        //初始化畫筆
        mUnSelectPaint = Paint()
        mUnSelectPaint?.apply {
            color = mUnSelectColor
            textSize = this@CustomTextView.textSize
            isAntiAlias = true
            isDither = true
        }
        mSelectPaint = Paint()
        mSelectPaint?.apply {
            color = mSelectColor
            textSize = this@CustomTextView.textSize
            isAntiAlias = true
            isDither = true
        }
    }
    /**
     * 繪制內(nèi)容
     */
    override fun onDraw(canvas: Canvas?) {
        val x = width * mScrollProcess
        if (mScrollToLeft) {
            drawText(canvas!!, mUnSelectPaint!!, x, width.toFloat())
            drawText(canvas!!, mSelectPaint!!, 0f, x)
        } else {
            drawText(canvas!!, mUnSelectPaint!!, 0f, width - x)
            drawText(canvas!!, mSelectPaint!!, width - x, width.toFloat())
        }
    }
    /**
     * 繪制文字
     */
    private fun drawText(canvas: Canvas, paint: Paint, startX: Float, endX: Float) {
        paint.textSize = textSize * mTextScale
        //保存畫布,剪切畫布(設(shè)置畫布顯示區(qū)域)
        canvas.save()
        canvas.clipRect(startX, 0f, endX, height.toFloat())
        //獲取文字矩形區(qū)域
        var bounds = Rect()
        paint.getTextBounds(text, 0, text.length, bounds)
        //獲取文字的度量指標
        val fontMetrics = paint.fontMetrics
        //計算基線到中心點位置
        val dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
        //計算基線
        val baseLine = height / 2 + dy
        //繪制文字
        canvas.drawText(
            text.toString(),
            (width / 2 - bounds.width() / 2).toFloat(),
            baseLine,
            paint
        )
        canvas.restore()
    }
    /**
     * 設(shè)置選中 未選中顏色
     */
    fun setColor(selectColor: Int, unSelectColor: Int) {
        mSelectColor = selectColor
        mUnSelectColor = unSelectColor
        mSelectPaint?.color = selectColor
        mUnSelectPaint?.color = unSelectColor
        invalidate()
    }
}

1,在構(gòu)造方法中初始化兩支畫筆,分別用于繪制未選中區(qū)域和選中區(qū)域

2,在onDraw()方法中根據(jù)滑動百分計算出繪制區(qū)域的寬度

3,判斷滑動方向

4,開始繪制文本

  • 設(shè)置畫筆的文字大?。ㄎ淖执笮?* 縮放比例)
  • 保存畫布,并根據(jù)計算出來的繪制區(qū)域的開始坐標和結(jié)束坐標剪切畫布,這是整個繪制核心,一旦剪切等下調(diào)用darwText()方法就只會繪制剪切的這部分
  • 獲取文字矩形區(qū)域,通過調(diào)用paint.getTextBounds()這個方法就能拿到我們繪制文本的區(qū)域
  • 獲取文字的度量指標,計算出基線的位置
  • 調(diào)用畫布的drawText()去繪制我們的文本

5,效果如下,對算法不理解的需要自行去搜索getTextBounds(),getFontMetrics()這兩個方法的作用及其屬性變量的作用,到這里,一個漸變色的TextView就出來了,最后容我埋下一個bug

代碼實現(xiàn)指示器

@RequiresApi(Build.VERSION_CODES.Q)
class MyIndicator : LinearLayout, ViewPager.OnPageChangeListener {
    var mTextScale = 0.7f
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attributeSet: AttributeSet?) : this(context, attributeSet, 0)
    constructor(context: Context, attributeSet: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attributeSet,
        defStyleAttr
    )
    /**
     * 添加多個tab
     */
    fun addTabs(texts: List<String>) {
        texts.forEach {
            addTab(it)
        }
        //選中第一個
        val customTextView = getChildAt(0) as CustomTextView
        customTextView.mScrollToLeft = false
        customTextView.mScrollProcess = 1f
        customTextView.mTextScale = 1f
        customTextView.invalidate()
    }
    /**
     * 添加tab
     */
    fun addTab(text: String) {
        val layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
        layoutParams.weight = 1f
        val customTextView = CustomTextView(context)
        customTextView.textSize = 21f
        customTextView.gravity = Gravity.CENTER
        customTextView.text = text
        customTextView.mScrollProcess = 0f
        customTextView.mTextScale = 0.7f
        customTextView.layoutParams = layoutParams
        addView(customTextView)
    }
    /**
     * 關(guān)聯(lián)ViewPage
     */
    fun relationViewPage(viewPage: ViewPager) {
        viewPage.addOnPageChangeListener(this)
    }
    /**
     * 滑動回調(diào)
     */
    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        if (positionOffset > 0) {
            val tabView = getChildAt(position) as CustomTextView
            tabView.mScrollToLeft = false
            tabView.mScrollProcess = 1 - positionOffset
            tabView.mTextScale = if ((1 - positionOffset) > mTextScale) 1 - positionOffset else mTextScale
            tabView.invalidate()
            val rightTabView = getChildAt(position + 1) as CustomTextView
            rightTabView.mScrollToLeft = true
            rightTabView.mScrollProcess = positionOffset
            rightTabView.mTextScale = if (positionOffset > mTextScale) positionOffset else mTextScale
            rightTabView.invalidate()
        }
    }
    /**
     * 選中某個item回調(diào)
     */
    override fun onPageSelected(position: Int) {
    }
    /**
     * 滑動狀態(tài)改變回調(diào)
     */
    override fun onPageScrollStateChanged(state: Int) {
    }
}

1,循環(huán)添加多個顏色漸變的CustomTextView,默認選中第一個

2,關(guān)聯(lián)ViewPage,給ViewPage設(shè)置一個OnPageChangeListener監(jiān)聽器,監(jiān)聽其滑動距離,根據(jù)滑動百分比計算出CustomTextView的滑動比例,CustomTextView的文字縮放比例

3,效果如下,如有不理解的版代碼過去自行改改參數(shù)就理解其中奧秘了,動起來

基線計算方式

在自定義View的過程中canvas.drawText(mText,0,y,mPaint);很容易出現(xiàn)字體不能完全漏出的問題,y的值其實不是距離畫布的距離,這個y是基準線的距離,所以在繪制的過程中一定要求得正確的基準線。所以在draw的過程中首先要計算好基準線的y

Paint.FontMetricsInt fontMetrics = p.getFontMetricsInt();

p.descent,  //底部文本的最低點距離基準線的y值(正數(shù))

p.ascent,  //頂部文本的最高點距離及基準線的y值(負數(shù))

到此這篇關(guān)于Android自定義超級炫酷的ViewPage指示器的文章就介紹到這了,更多相關(guān)Android ViewPage內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android利用Gson解析嵌套多層的Json的簡單方法

    Android利用Gson解析嵌套多層的Json的簡單方法

    下面小編就為大家?guī)硪黄狝ndroid利用Gson解析嵌套多層的Json的簡單方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • AndroidStudio中AVD虛擬機設(shè)備空間不足調(diào)試過程出現(xiàn)的黑屏問題及解決方案

    AndroidStudio中AVD虛擬機設(shè)備空間不足調(diào)試過程出現(xiàn)的黑屏問題及解決方案

    這篇文章主要介紹了解決AndroidStudio中AVD虛擬機設(shè)備空間不足調(diào)試過程出現(xiàn)的黑屏問題,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • Android實現(xiàn)可瀏覽和搜索的聯(lián)系人列表

    Android實現(xiàn)可瀏覽和搜索的聯(lián)系人列表

    這篇文章主要為大家詳細介紹了Android實現(xiàn)可瀏覽和搜索的聯(lián)系人列表的相關(guān)代碼,瀏覽所有聯(lián)系人和根據(jù)名稱搜索聯(lián)系人,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Android滑動動態(tài)分頁實現(xiàn)方法

    Android滑動動態(tài)分頁實現(xiàn)方法

    這篇文章主要介紹了Android滑動動態(tài)分頁實現(xiàn)方法,結(jié)合實例形式分析了Android實現(xiàn)滑動動態(tài)分頁的操作步驟與核心實現(xiàn)代碼,需要的朋友可以參考下
    2016-10-10
  • 詳解Android截屏事件監(jiān)聽

    詳解Android截屏事件監(jiān)聽

    本篇文章主要介紹了Android截屏事件監(jiān)聽,Android系統(tǒng)沒有直接對截屏事件監(jiān)聽的接口,本文介紹了2種方法,有興趣的可以了解一下。
    2016-12-12
  • Android studio實現(xiàn)菜單效果

    Android studio實現(xiàn)菜單效果

    這篇文章主要為大家詳細介紹了Android studio實現(xiàn)菜單效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Android最新狀態(tài)欄處理介紹

    Android最新狀態(tài)欄處理介紹

    大家好,本篇文章主要講的是Android最新狀態(tài)欄處理介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Android自定義View onDraw()方法會調(diào)用兩次的問題解決

    Android自定義View onDraw()方法會調(diào)用兩次的問題解決

    這篇文章主要介紹了Android自定義View onDraw()方法會調(diào)用兩次的問題解決,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • android實現(xiàn)拍照或從相冊選取圖片

    android實現(xiàn)拍照或從相冊選取圖片

    這篇文章主要為大家詳細介紹了android實現(xiàn)拍照或從相冊選取圖片,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • android實現(xiàn)清理緩存功能

    android實現(xiàn)清理緩存功能

    這篇文章主要為大家詳細介紹了android實現(xiàn)清理緩存,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11

最新評論