自定义View深入了解(一)

本文探讨了自定义View中wrap_content的实现方式,解释了MeasureSpec在不同情况下的工作原理,并提供了一个具体的解决方案。

自定义View(基础)以及自定义(加载动画)中,有人肯定会遇到这样的问题:

1.在布局xml中,设置控件layout_width、layout_height 的值为warp_content时,如:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <pw.onlyou.testapplication.ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        custom:firstColor="#F08080"
        custom:secondColor="#7B68EE"
        android:background="#aaa"
        android:layout_centerInParent="true"
        android:padding="20dp"
        custom:circleWidth="10dp"
        custom:speed="10"/>
</RelativeLayout>
但是呢,人生道路并不是一帆风顺的,看看运行效果图


are you kidding me??

砸门把布局文件修改一下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <pw.onlyou.testapplication.ProgressBar
        android:layout_width="200dp"
        android:layout_height="200dp"
        custom:firstColor="#F08080"
        custom:secondColor="#7B68EE"
        android:layout_centerInParent="true"
        android:padding="20dp"
        custom:circleWidth="10dp"
        custom:speed="10"/>
</RelativeLayout>
定死宽高,看运行效果:



一切正常,但是我是个有追求的人,绝不放过一丁点问题

通过查阅资料(android 开发艺术探索 是一本好书,建议大家看看),原来如此。先看一张图:


这图啥意思??

1.当 View 采用固定宽高时,不管父容器的 MeasureSpec 是什么,View 的 MeasureSpec 都是精确模式,并且大小是LayoutParams 中的大小。
2.当 View 的宽高是 match_parent 时,如果父容器的模式是精确模式,那么 View 也是精确模式,并且大小是父容器的剩余空间;如果父容器是最大模式,那么 View 也是最大模式,并且大小是不会超过父容器的剩余空间。
3.当 View 的宽高是 wrap_content 时,不管父容器的模式是精确模式还是最大模式,View 的模式总是最大模式,并且大小不超过父容器的剩余空间


缩的思内~我们来修改代码

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int WspecMode = MeasureSpec.getMode(widthMeasureSpec);
        int HspecMode = MeasureSpec.getMode(heightMeasureSpec);

        if(HspecMode==MeasureSpec.EXACTLY&&WspecMode==MeasureSpec.EXACTLY){
            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
        }else if(WspecMode==MeasureSpec.AT_MOST){
            setMeasuredDimension(Width, MeasureSpec.getSize(heightMeasureSpec));
        }else if(HspecMode==MeasureSpec.AT_MOST){
            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), Height);
        }
    }
    

Width和Height 分别是我定义的默认大小,当布局控件 大小为warp_content的时候,控件大小分别为Width、Height。

现在我们布局文件大小都是warp_content,看看运行效果:


good,成功了!

还有padding也是要注意的,有时间补上。

文章目前仍在更新中,如果你觉得我的文章有错误或者纰漏,欢迎指正,另外,如果你觉得有用的话,点个赞呗。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值