亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

在之前的項(xiàng)目中,有做過(guò)一個(gè)需求,需要實(shí)現(xiàn)一個(gè)顏色漸變的折線(xiàn)圖。當(dāng)時(shí)項(xiàng)目中使用的圖表庫(kù)是MPAndroidChart,但是該庫(kù)沒(méi)有提供合適的方法來(lái)實(shí)現(xiàn)想要的效果,因此只能通過(guò)自定義view來(lái)實(shí)現(xiàn)。

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

如何實(shí)現(xiàn)

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

實(shí)現(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

    /**
     * 折線(xiàn)寬度
     */
    private var lineWidth: Float = 0f

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

    /**
     * 網(wǎng)格線(xiàn)顏色
     */
    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)
        //設(shè)置畫(huà)布背景色
        canvas?.drawColor(backgroundColorRes)
        //繪制網(wǎng)格線(xiàn)
        drawGradLine(canvas)
        //繪制折線(xiàn)
        drawLine(canvas)
    }

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

            //Y軸網(wǎng)格線(xiàn)間距
            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)格線(xiàn)間距
            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!!)
            }
        }
    }

    /**
     * 繪制折線(xiàn)
     */
    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">
        <!--線(xiàn)寬度-->
        <attr name="tc_lineWidth" format="dimension" />
        <!--網(wǎng)格線(xiàn)寬度-->
        <attr name="tc_grid_line_width" format="dimension" />
        <!--網(wǎng)格線(xiàn)顏色-->
        <attr name="tc_grid_line_color" format="color" />
        <!--等級(jí)顏色指示器寬度-->
        <attr name="tc_level_indicator_width" format="dimension" />
        <!--背景顏色-->
        <attr name="tc_background_color" format="color" />
    </declare-styleable>
</resources>

效果如下圖:

總結(jié)

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

相關(guān)文章

  • Android自動(dòng)提示控件AutoCompleteTextView

    Android自動(dòng)提示控件AutoCompleteTextView

    這篇文章主要介紹了Android自動(dòng)提示控件AutoCompleteTextView的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Android如何自定義升級(jí)對(duì)話(huà)框示例詳解

    Android如何自定義升級(jí)對(duì)話(huà)框示例詳解

    對(duì)話(huà)框是我們?cè)谄綍r(shí)經(jīng)常會(huì)遇到的一個(gè)功能,但自帶的對(duì)話(huà)框不夠美觀(guān),大家一般都會(huì)自定義,下面這篇文章主要給大家介紹了關(guān)于A(yíng)ndroid如何自定義升級(jí)對(duì)話(huà)框的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-08-08
  • Android獲取SD卡中選中圖片的路徑(URL)示例

    Android獲取SD卡中選中圖片的路徑(URL)示例

    一個(gè)圖片上傳功能需要提供上傳圖片在SD卡中的路徑,總結(jié)了網(wǎng)上的一些列子,修改了一下,代碼很簡(jiǎn)單,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助
    2013-07-07
  • 淺談Android studio 生成apk文件時(shí)的 key store path 的問(wèn)題

    淺談Android studio 生成apk文件時(shí)的 key store path 的問(wèn)題

    這篇文章主要介紹了淺談Android studio 生成apk文件時(shí)的 key store path 的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • Android控制文本輸入框最多輸入10個(gè)字符長(zhǎng)度

    Android控制文本輸入框最多輸入10個(gè)字符長(zhǎng)度

    這篇文章主要為大家詳細(xì)介紹了Android控制文本輸入框最多輸入10個(gè)字符長(zhǎng)度,即最多輸入5個(gè)漢字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android中js和原生交互的示例代碼

    Android中js和原生交互的示例代碼

    本篇文章主要介紹了Android中js和原生交互的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 使用RecyclerView添加Header和Footer的方法

    使用RecyclerView添加Header和Footer的方法

    RecyclerView雖然作為L(zhǎng)istView的替代者有著較好的性能提升,但是ListView的一些常用功能卻沒(méi)有提供,比如我們平時(shí)會(huì)經(jīng)常用到的addHeaderView,addFooterView,既然RecyclerView沒(méi)有提供這個(gè)方法,我們應(yīng)該如何為列表添加頭部和底部呢,接下來(lái)通過(guò)本文給大家介紹
    2016-03-03
  • Android開(kāi)發(fā)自定義實(shí)時(shí)圖表控件實(shí)現(xiàn)示例

    Android開(kāi)發(fā)自定義實(shí)時(shí)圖表控件實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了Android自定義實(shí)時(shí)圖表控件實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • android ListView和GridView拖拽移位實(shí)現(xiàn)代碼

    android ListView和GridView拖拽移位實(shí)現(xiàn)代碼

    有些朋友對(duì)android中ListView和GridView拖拽移位功能的實(shí)現(xiàn)不是很了解,接下來(lái)將詳細(xì)介紹,需要了解的朋友可以參考下
    2012-12-12
  • android實(shí)現(xiàn)直播點(diǎn)贊飄心動(dòng)畫(huà)效果

    android實(shí)現(xiàn)直播點(diǎn)贊飄心動(dòng)畫(huà)效果

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)直播點(diǎn)贊飄心動(dòng)畫(huà)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03

最新評(píng)論