最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android自定義View之漸變色折線圖的實現(xiàn)

 更新時間:2022年04月26日 11:41:42   作者:ChenYhong  
折線圖的實現(xiàn)方法在github上有很多開源的程序,但是對于初學者來講,簡單一點的教程可能更容易入門,下面這篇文章主要給大家介紹了關于Android自定義View之漸變色折線圖的相關資料,需要的朋友可以參考下

前言

在之前的項目中,有做過一個需求,需要實現(xiàn)一個顏色漸變的折線圖。當時項目中使用的圖表庫是MPAndroidChart,但是該庫沒有提供合適的方法來實現(xiàn)想要的效果,因此只能通過自定義view來實現(xiàn)。

通過這篇文章記錄一下,便于之后需要實現(xiàn)類似的效果時查找使用。

如何實現(xiàn)

通過創(chuàng)建LinearGradient來實現(xiàn)顏色漸變,并將之設置到畫筆Paint的著色器Shader,繪制想要的路徑即可實現(xiàn)該效果。

實現(xiàn)代碼如下:

class GradientLineChart : View {
    private var viewWidth: Int = 0
    private var viewHeight: Int = 0

    private var chartWidth: Int = 0
    private var chartHeight: Int = 0

    /**
     * 折線寬度
     */
    private var lineWidth: Float = 0f

    /**
     * 網(wǎng)格線寬度
     */
    private var gridLineWidth: Float = 0f

    /**
     * 網(wǎng)格線顏色
     */
    private var gridLineColor: Int = 0

    /**
     * 背景顏色
     */
    private var backgroundColorRes: Int = 0

    private var linePaint: Paint? = null
    private var gridLinePaint: Paint? = null
    private var gradientColor: IntArray? = null

    private val rectF = RectF()
    private val linePath = Path()

    private val lineValueList = ArrayList<LineEntity>()

    constructor(context: Context?) : this(context, null)

    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        lineValueList.add(LineEntity(3f, 28f))
        lineValueList.add(LineEntity(7f, 2f))
        lineValueList.add(LineEntity(14f, 18f))
        lineValueList.add(LineEntity(17f, 12f))
        lineValueList.add(LineEntity(22f, 21f))

        context?.let {
            gradientColor = intArrayOf(
                ContextCompat.getColor(it, R.color.color_FFD200),
                ContextCompat.getColor(it, R.color.color_FF2600),
                ContextCompat.getColor(it, R.color.color_49E284),
                ContextCompat.getColor(it, R.color.color_00A5FF)
            )
        }

        initAttr(attrs, defStyleAttr)
        initPaint()
    }

    private fun initAttr(attrs: AttributeSet?, defStyleAttr: Int) {
        val typeArray =
            context.theme.obtainStyledAttributes(attrs, R.styleable.GradientLineChart, defStyleAttr, 0)

        lineWidth = typeArray.getDimension(
            R.styleable.GradientLineChart_tc_lineWidth,
            DensityUtil.dp2Px(2).toFloat()
        )
        gridLineWidth = typeArray.getDimension(
            R.styleable.GradientLineChart_tc_grid_line_width,
            DensityUtil.dp2Px(1).toFloat()
        )
        gridLineColor = typeArray.getColor(
            R.styleable.GradientLineChart_tc_grid_line_color,
            ContextCompat.getColor(context, R.color.color_1Affffff)
        )
        backgroundColorRes = typeArray.getColor(
            R.styleable.GradientLineChart_tc_background_color,
            ContextCompat.getColor(context, R.color.color_23242a)
        )

        typeArray.recycle()
    }

    private fun initPaint() {
        linePaint = Paint()
        linePaint?.isAntiAlias = true
        linePaint?.style = Paint.Style.STROKE
        linePaint?.strokeWidth = lineWidth

        gridLinePaint = Paint()
        gridLinePaint?.isAntiAlias = true
        gridLinePaint?.style = Paint.Style.FILL
        gridLinePaint?.color = gridLineColor
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        viewWidth = MeasureSpec.getSize(widthMeasureSpec)
        viewHeight = MeasureSpec.getSize(heightMeasureSpec)
        //MUST CALL THIS
        setMeasuredDimension(viewWidth, viewHeight)

        chartWidth = viewWidth - paddingStart - paddingEnd
        chartHeight = viewHeight - paddingTop - paddingBottom
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //設置畫布背景色
        canvas?.drawColor(backgroundColorRes)
        //繪制網(wǎng)格線
        drawGradLine(canvas)
        //繪制折線
        drawLine(canvas)
    }

    /**
     * 繪制網(wǎng)格線
     */
    private fun drawGradLine(canvas: Canvas?) {
        gridLinePaint?.let {
            val yGridValues = 7
            val xGridValues = 6

            //Y軸網(wǎng)格線間距
            val yGridDistance = (chartHeight - yGridValues * gridLineWidth) / (yGridValues - 1)
            for (index in 0 until yGridValues) {
                val left = paddingStart.toFloat()
                val top = paddingTop.toFloat() + index * yGridDistance + index * gridLineWidth
                val right = left + chartWidth
                val bottom = top + gridLineWidth
                rectF.set(left, top, right, bottom)
                canvas?.drawRect(rectF, it)
            }

            //X軸網(wǎng)格線間距
            val xGridDistance = (chartWidth - xGridValues * gridLineWidth) / (xGridValues - 1)
            for (index in 0 until xGridValues) {
                val left = paddingStart + xGridDistance * index + gridLineWidth * index
                val top = paddingTop.toFloat()
                val right = left + gridLineWidth
                val bottom = top + chartHeight
                rectF.set(left, top, right, bottom)
                canvas?.drawRect(rectF, gridLinePaint!!)
            }
        }
    }

    /**
     * 繪制折線
     */
    private fun drawLine(canvas: Canvas?) {
        val yGridValues = 7
        val xGridValues = 6
        val yGridDistance = (chartHeight - yGridValues * gridLineWidth) / (yGridValues - 1)
        val xGridDistance = (chartWidth - xGridValues * gridLineWidth) / (xGridValues - 1)

        for ((index, linePoint) in lineValueList.withIndex()) {
            val pointX =
                ((linePoint.xValue - 5 * index) / 5) * xGridDistance + (xGridDistance * index)
            val pointY =
                chartHeight - (linePoint.yValue / 30 * (yGridDistance * 6))
            if (index == 0) {
                linePath.moveTo(pointX, pointY)
            } else {
                linePath.lineTo(pointX, pointY)
            }
        }

        linePaint?.shader = createLineGradient(gradientColor!!)
        canvas?.drawPath(linePath, linePaint!!)
    }

    private fun createLineGradient(gradientColor: IntArray): LinearGradient {
        return LinearGradient(
            0f,
            0f,
            0f,
            viewHeight.toFloat(),
            gradientColor,
            null,
            Shader.TileMode.CLAMP
        )
    }
}

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="GradientLineChart">
        <!--線寬度-->
        <attr name="tc_lineWidth" format="dimension" />
        <!--網(wǎng)格線寬度-->
        <attr name="tc_grid_line_width" format="dimension" />
        <!--網(wǎng)格線顏色-->
        <attr name="tc_grid_line_color" format="color" />
        <!--等級顏色指示器寬度-->
        <attr name="tc_level_indicator_width" format="dimension" />
        <!--背景顏色-->
        <attr name="tc_background_color" format="color" />
    </declare-styleable>
</resources>

效果如下圖:

總結

到此這篇關于Android自定義View之漸變色折線圖的文章就介紹到這了,更多相關Android漸變色折線圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Android仿QQ復制昵稱效果

    Android仿QQ復制昵稱效果

    這幾天做一個復制文本的需求,突然看到QQ上復制昵稱跟QQ號的效果,覺得很不錯,就想要模仿一波,辦法比較簡單粗暴,反編譯QQ獲取了那個.9圖片,然后就是用PopWindow實現(xiàn)了,需要的朋友可以參考下
    2019-05-05
  • android自定義帶箭頭對話框

    android自定義帶箭頭對話框

    這篇文章主要為大家詳細介紹了android自定義帶箭頭對話框,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • Android文件讀寫的幾種方式

    Android文件讀寫的幾種方式

    文件讀寫作為Android四大數(shù)據(jù)存儲方式之一,又分為內(nèi)部存儲和外部存儲兩種,下面這篇文章主要給大家介紹了關于Android文件讀寫的幾種方式,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • 實例探究Android開發(fā)中Fragment狀態(tài)的保存與恢復方法

    實例探究Android開發(fā)中Fragment狀態(tài)的保存與恢復方法

    這篇文章主要介紹了實例探究Android開發(fā)中Fragment狀態(tài)的保存與恢復方法,或許開發(fā)者們對Fragment的操作都比較熟悉,但onSaveInstanceState()方法并不能夠很好地保存Fragment狀態(tài),需要的朋友可以參考下
    2016-04-04
  • Android仿QQ空間主頁面的實現(xiàn)

    Android仿QQ空間主頁面的實現(xiàn)

    今天模仿安卓QQ空間,打開程序的啟動畫面和導航頁面我就不做了,大家可以模仿微信的那個做一下,很簡單。這次主要做一下主頁面的實現(xiàn),感興趣的朋友可以參考下
    2013-01-01
  • Android狀態(tài)欄白底黑字的示例代碼

    Android狀態(tài)欄白底黑字的示例代碼

    這篇文章主要介紹了Android狀態(tài)欄白底黑字的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Android 復制文本內(nèi)容到系統(tǒng)剪貼板的最簡單實例(分享)

    Android 復制文本內(nèi)容到系統(tǒng)剪貼板的最簡單實例(分享)

    下面小編就為大家?guī)硪黄狝ndroid 復制文本內(nèi)容到系統(tǒng)剪貼板的最簡單實例(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • Android獲取位置信息的方法

    Android獲取位置信息的方法

    這篇文章主要為大家詳細介紹了Android獲取位置信息的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • Android?Flutter實現(xiàn)有趣的頁面滾動效果

    Android?Flutter實現(xiàn)有趣的頁面滾動效果

    Flutter提供了?CustomScrollView?來粘合多個滑動組件,并且可以實現(xiàn)更有趣的滑動效果,本文就來為大家詳細講講實現(xiàn)的方法,需要的可以參考一下
    2022-06-06
  • Android開發(fā):TextView加入滾動條示例

    Android開發(fā):TextView加入滾動條示例

    利用scrollview來實現(xiàn)TextView中滾動條效果會好很多,具體代碼如下,感興趣的朋友可以參考下哈
    2013-06-06

最新評論

绍兴市| 青冈县| 三门县| 灵璧县| 宁化县| 古浪县| 肥西县| 延川县| 乳山市| 武城县| 丽江市| 图木舒克市| 页游| 乌苏市| 大安市| 祁连县| 龙游县| 恩平市| 和政县| 彭州市| 比如县| 阳山县| 新田县| 海南省| 大田县| 六安市| 嘉荫县| 北宁市| 文成县| 九龙坡区| 剑阁县| 信阳市| 南皮县| 邻水| 来凤县| 图木舒克市| 琼中| 武平县| 呼玛县| 南阳市| 嘉善县|