一个超简单的渐变平行四边形进度条

hello啊,各位老铁,说实在话,真的是许久不见,屈指一数,这次断更了有些许时日了,没别的理由,就是懒,不想更[捂脸哭],之后尽量会多更一更,目前储备了有一些技术文章了,后续陆陆续续就写起来了,2023,开年第一篇,搞一个无比简单的自定义View吧。

这个自定义View,其实就是一个简单的进度条,无非就是平行四边形形状的,加了渐变以及状态颜色的切换。

今天的内容大致如下:

1、效果及代码具体调用。

2、具体实现过程。

3、开源地址。

4、总结及注意事项。

一、效果及代码具体调用。

效果展示

效果的话,没什么复杂的,就是一个纯粹的平行四边形,无非就是带了一点渐变的颜色如下图所示:

此进度条,比较适用于常见的,里程提示,油量多少等需要的场景,进度条的颜色,进度值,以及告警值,都可以动态设置,为了方便大家使用,大家可以下载源码查看,或者使用Maven依赖也行,如果使用Maven,可以参照下面的调用方式。

具体调用

1、在你的根项目下的build.gradle文件下,引入maven。

allprojects {
    repositories {
        maven { url "https://gitee.com/AbnerAndroid/almighty/raw/master" }
    }
}

2、在你需要使用的Module中build.gradle文件下,引入依赖。

dependencies {
    implementation 'com.vip:mprogress:1.0.2'
}

代码使用

属性介绍

属性

类型

概述

mp_background

color

整体的背景颜色

mp_angle_width

dimension

平行四边形角度的宽(倾斜度)

mp_anamorphism_color

reference

渐变颜色(传递颜色数组,定义array资源)

mp_max_progress

Int

最大进度

mp_default_progress

Int

默认进度

mp_warn_progress

Int

告警进度(低于多少就改变进度颜色)

mp_warn_background

color

告警颜色

mp_is_dim_progress

boolean

是否模糊颜色(进度前进头的颜色)

方法介绍

方法

参数

概述

changeProgress

Int

传递进度值

二、具体实现过程

绘制一个平行四边形,这里采用的是path路径绘制,只需要记录四点坐标就可以了,也就是四个顶点的坐标。

一个超简单的渐变平行四边形进度条_第1张图片

设置默认宽高

宽度和高度,根据在XML中设置得宽高进行适应,这里需要做一个简单的判断,也就是,如果XML中设置的是wrap_content,我们尽量给一个默认的宽度或高度,让其展示出来。

设置默认的宽度和高度,需要在onMeasure方法中进行模式判断,当宽度或高度取得的模式为MeasureSpec.AT_MOST,我们单独给一个默认的值,代码如下:

   override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        var windowWidth = heightMeasureSpec
        var windowHeight = heightMeasureSpec
        if (widthMode == MeasureSpec.AT_MOST) {
            windowWidth = getScreenWidth()
        }
        if (heightMode == MeasureSpec.AT_MOST) {
            windowHeight = mDefaultHeight
        }
        setMeasuredDimension(windowWidth, windowHeight)
    }

这里简单的概述一下,MeasureSpec有三个模式,分别为MeasureSpec.EXACTLY,MeasureSpec.AT_MOST和MeasureSpec.UNSPECIFIED。

MeasureSpec.EXACTLY是精确模式,当我们将控件的layout_width或layout_height指定为具体数值时,如andorid:layout_width="50dp",或者为match_parent时,既控件大小已经确定的情况,都是精确模式。

MeasureSpec.AT_MOST是最大模式,当控件的layout_width或layout_height指定为wrap_content时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的模式是AT_MOST。

MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。

是否要设置一个默认的高度或者宽度,取决于实际的业务情况,一般情况下,使用者都会自己来设置宽和高,至于在此做一层约束,只是为了能让View视图展示出来。

绘制视图

绘制,上述已经说过,找到四个顶点即可,依次进行连接,如下代码所示,mAngleWidth变量为平行四边形的倾斜度。

 	val path = Path()
        path.apply {
            moveTo(0f, height.toFloat())//第一个点的位置
            lineTo(mAngleWidth, 0f)//第二个
            lineTo(width.toFloat(), 0f)//第三个
            lineTo((width - mAngleWidth), height.toFloat())//第四个
            close()
            canvas.drawPath(this, mPaint!!)
        }

渐变色

实现渐变色,也是非常的简单,画笔Paint有个设置的方法setShader,也就是着色器,可以帮助我们实现想要的渐变颜色,Shader有五个子类,分别是:BitmapShader、LinearGradient、RadialGradient、SweepGradient和ComposeShader,具体的就不多介绍了,单独介绍一下LinearGradient。

LinearGradient是用来创建线性渐变效果的,它是沿着某条直线的方向渐变的,有四个构造函数,这里我们选取下面这个构造。

 public LinearGradient(float x0, float y0, float x1, float y1, 
                       @NonNull long[] colors, @Nullable float[] positions, 
                       @NonNull TileMode tile) {
       
  }

此构造函数中有七个参数,前四个是坐标点,前两个x0,y0是这条渐变直线的起点,后两个x1,y1是这条渐变直线的终点,第五个参数为int数组colors,也就是需要的渐变颜色,颜色值从开始到结束依次排开即可,第六个参数为位置,和前边的颜色数组是一一对应的,用来标记颜色的位置,最后一个参数是颜色渐变的模式,有三种模式。

TileMode.CLAMP:超出其原始边界,则复制边缘颜色。

TileMode.REPEAT: 重复填充以前的渐变色。

TilmMode.MIRROR :镜像填充。

设置shader,如下代码。

 val linearShader = LinearGradient(
            0f, 0f, width.toFloat(), height.toFloat(), colorArray,
            progressArray, Shader.TileMode.CLAMP
        )
        mPaint?.shader = linearShader

需要注意的是,是否需要模糊进度,也就是进度前边的一块,我这里我采用的方式是,颜色数组和位置数组都增加两个,第二个位置到三个位置,稍微增加一点position即可实现,比如原来是(0f,1f),目前改为了四个,就成了(0f,0,5f,0,54f,1f)类似这样,当然了第二个进度需要动态处理的,毕竟是一个进度条。

具体的代码实现,大家可以去看源码,没有什么特别复杂的地方,都是比较基础的Api操作。

三、开源地址。

目前项目已经开源,需要的朋友可以查看:https://github.com/AbnerMing888/Mileage。

四、总结及注意事项。

如此一个简单的自定义View,需要掌握的就三点,一个是LinearGradient渐变色的处理,一个就是path路径的轨迹,最后一个是MeasureSpec模式的判断,其他的都是最基本的绘制方法,也没有什么可说的,大家看源码或第二步实现过程就可以了。

你可能感兴趣的:(android,kotlin,平行四边形,自定义View)