博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自我绘制三
阅读量:6291 次
发布时间:2019-06-22

本文共 7114 字,大约阅读时间需要 23 分钟。

一让Padding值有效

前边我们已经绘制了两个自定义控件,细心的同学可能会发现问题:你自定义View设置padding值是无效的。但是margin是有效的。

android:layout_margin=""android:padding=""复制代码

观察上边的代码:

margin是以layout开头的,所以它是属于父类布局处理的事情,而父类布局我们使用的是系统的布局,系统已经帮我们处理了,所以它是有效的。

padding没有以layout开头,它属于控件自身的属性,需要我们自己去处理,如果没有处理,当然是无效属性。

由此可知:

自定义View时候需要开发者处理padding值

自定义ViewGroup时候需要开发者处理margin和padding值

这篇我们只说自定义View处理padding的事情,而自定义ViewGroup的问题处理等讲到自定义ViewGroup的时候再去讲怎么处理。

怎么处理呢?

很简单,只需要在计算的时候获取内边距的值,然后再计算的时候考虑进去即可。

怎么获取这个值呢?

在自定义View中通过get方法直接获取即可,对应的Kotlin中直接使用常量即可

paddingLeftpaddingRightpaddingToppaddingBottom复制代码

当然我们再自定义View,自己使用的时候一般都不去考虑这个四个属性(我反正是这样),但是自定义View给别人用的时候,我们一般要考虑四个属性。当然,为了规范开发,考虑上去这四个值没有什么错。(之前两个自定义View我就不做修改,知道有这个问题即可)

效果图:

原理图:

对应代码:

package MyViewsimport android.animation.ObjectAnimatorimport android.content.Contextimport android.graphics.Canvasimport android.graphics.Colorimport android.graphics.Paintimport android.graphics.Pathimport android.os.Buildimport android.support.annotation.RequiresApiimport android.util.AttributeSetimport android.util.Logimport android.view.View/** * Created by Administrator on 2018/7/10. * 自定义水平进度条,主要学习padding设置的用法 */class HorizontalProgress : View {    //控件默认的宽    val defult_Widht: Float    //控件默认高度    val defult_Hdight: Float    //topRect高度    val topRectHeight = DisplayUtils.dip2px(context, 14F)    //topRect宽度    val topRectWidth = DisplayUtils.dip2px(context, 24F)    //三角形的宽度高度    val triangle_Height_width = DisplayUtils.dip2px(context, 6F)    //进度条和三角形的间隔    val progressToTeiangle = DisplayUtils.dip2px(context, 6F)    //进度条线线的宽度    val progressLineWidth = DisplayUtils.dip2px(context, 4F)    //进度条和控件底部间隔    val progressToBottom = DisplayUtils.dip2px(context, 6F)    //画背景的画笔    private lateinit var bg_Paint: Paint    //画头部矩形的画笔    private lateinit var top_Paint: Paint    //顶部文字的画笔    private lateinit var text_Paint: Paint    //画进度条的画笔    private lateinit var progress_Paint: Paint    //当前进度    private var progress = 0        set(value) {            field = value            invalidate()        }    //结束进度,    var endProgress = 0    //构造方法    constructor(context: Context?) : this(context, null)    //构造方法    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)    //构造方法    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : this(context, attrs, defStyleAttr, 0)    //构造方法    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {        //控件的高度 = 上边巨型的高度+三角形的高度+三角形和进度条的间隔+进度条的高度+进度条到底部的高度        defult_Hdight = topRectHeight + triangle_Height_width + progressToTeiangle + progressLineWidth + progressToBottom        defult_Widht = DisplayUtils.getDisplayWidth(context) - topRectWidth        initPaint()    }    private fun initPaint() {        //创建画背景圆的画笔        bg_Paint = Paint(Paint.ANTI_ALIAS_FLAG)        //设置画线模式        bg_Paint.style = Paint.Style.STROKE        //设置画线的宽度        bg_Paint.strokeWidth = progressLineWidth        //设置线的颜色        bg_Paint.color = Color.parseColor("#cccccc")        //创建画背景的画笔        top_Paint = Paint(Paint.ANTI_ALIAS_FLAG)        //设置画笔颜色        top_Paint.color = Color.parseColor("#FFAA00")        //创建文字画笔        text_Paint = Paint(Paint.ANTI_ALIAS_FLAG)        //设置画笔颜色        text_Paint.color = Color.WHITE        //计算文字开始大小        text_Paint.textSize = DisplayUtils.sp2px(context, 8F).toFloat()        //设置中心位置        text_Paint.textAlign = Paint.Align.CENTER        progress_Paint = Paint(Paint.ANTI_ALIAS_FLAG)        //设置画线模式        progress_Paint.style = Paint.Style.STROKE        //设置画线的宽度        progress_Paint.strokeWidth = progressLineWidth        //设置线的颜色        progress_Paint.color = Color.parseColor("#FFAA00")    }    //测量    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {        setMeasuredDimension(resolveSize(defult_Widht.toInt(), widthMeasureSpec), resolveSize(defult_Hdight.toInt() + paddingBottom + paddingTop, heightMeasureSpec))    }    //绘制    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)    override fun onDraw(canvas: Canvas) {        drawBgLine(canvas)        drawTopRect(canvas)        drawTriangle(canvas)        drawTopText(canvas)        drawProgressLine(canvas)    }    //画背景线,这里考虑了Padding值    private fun drawBgLine(canvas: Canvas) {        //画线需要算出起始点和终止点        canvas.drawLine(0F + paddingLeft+topRectWidth/2, topRectHeight + triangle_Height_width + progressToTeiangle + paddingTop,                defult_Widht - paddingRight+topRectWidth/2, topRectHeight + triangle_Height_width + progressToTeiangle + paddingTop,                bg_Paint)    }    //画顶部矩形    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)    private fun drawTopRect(canvas: Canvas) {        var newLine = (defult_Widht - paddingRight - paddingLeft) * progress / 100 - topRectWidth / 2        canvas.drawRoundRect(0F + paddingLeft + newLine+topRectWidth/2, 0F + paddingTop, topRectWidth + paddingLeft + newLine+topRectWidth/2, topRectHeight + paddingTop, 2F, 2F, top_Paint)    }    //绘制三角形    fun drawTriangle(canvas: Canvas) {        var newLine = (defult_Widht.toFloat() - paddingRight - paddingLeft) * progress / 100 - topRectWidth / 2        var path = Path()        //需要计算三角形的三个点的坐标        var startX = (topRectWidth - triangle_Height_width) / 2 + paddingLeft + newLine+topRectWidth/2        var startY = topRectHeight - 2 + paddingTop        var twoX = (topRectWidth + triangle_Height_width) / 2 + paddingLeft + newLine+topRectWidth/2        var twoY = topRectHeight - 2 + paddingTop        var endX = topRectWidth / 2 + paddingLeft + newLine+topRectWidth/2        var endY = topRectHeight + triangle_Height_width + paddingTop        path.moveTo(startX, startY)        path.lineTo(twoX, twoY)        path.lineTo(endX, endY)        //封闭缺口        path.close()        canvas.drawPath(path, top_Paint)    }    //绘制顶部文字    private fun drawTopText(canvas: Canvas) {        var newLine = (defult_Widht.toFloat() - paddingRight - paddingLeft) * progress / 100 - topRectWidth / 2        //需要算出来文字的x以及baseLine        var x = topRectWidth / 2 + paddingLeft + newLine+topRectWidth/2        val fontMetrics = text_Paint.getFontMetrics()        var baseline = topRectHeight / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom + paddingTop        canvas.drawText("$progress%", x, baseline, text_Paint)    }    //绘制进度走的值    fun drawProgressLine(canvas: Canvas) {        //需要动态去设置这个终点的值,所以需要计算        //因为这里是直线,所以除了用DashPathEffect之外,还可以通过改变终点的坐标去执行动画,但是如果是曲线,就只有用DashPathEffect去绘制动画        var newLine = (defult_Widht - paddingRight - paddingLeft) * progress / 100        Log.e("rrrrrrrr", newLine.toString())        //画线需要算出起始点和终止点        canvas.drawLine(0F + paddingLeft+topRectWidth/2, topRectHeight + triangle_Height_width + progressToTeiangle + paddingTop,                newLine + paddingLeft+topRectWidth/2, topRectHeight + triangle_Height_width + progressToTeiangle + paddingTop,                progress_Paint)    }    //开启动画    fun start() {        val ofInt = ObjectAnimator.ofInt(this, "progress", 0, endProgress)        ofInt.duration = 1000        ofInt.start()    }}复制代码

源码地址:

转载地址:http://eqkta.baihongyu.com/

你可能感兴趣的文章
js 面试题
查看>>
sqoop数据迁移(基于Hadoop和关系数据库服务器之间传送数据)
查看>>
腾讯云下安装 nodejs + 实现 Nginx 反向代理
查看>>
Javascript 中的 Array 操作
查看>>
java中包容易出现的错误及权限问题
查看>>
AngularJS之初级Route【一】(六)
查看>>
服务器硬件问题整理的一点总结
查看>>
SAP S/4HANA Cloud: Revolutionizing the Next Generation of Cloud ERP
查看>>
Mellanox公司计划利用系统芯片提升存储产品速度
查看>>
白帽子守护网络安全,高薪酬成大学生就业首选!
查看>>
ARM想将芯片装进人类大脑 降低能耗是一大挑战
查看>>
Oracle数据库的备份方法
查看>>
Selenium 自动登录考勤系统
查看>>
关于如何以编程的方式执行TestNG
查看>>
智能照明造福千家万户 家居智能不再是梦
查看>>
物联网如何跳出“看起来很美”?
查看>>
浅谈MySQL 数据库性能优化
查看>>
《UNIX/Linux 系统管理技术手册(第四版)》——1.10 其他的权威文档
查看>>
灵动空间 创享生活
查看>>
《UNIX网络编程 卷1:套接字联网API(第3版)》——8.6 UDP回射客户程序:dg_cli函数...
查看>>