Android View如何测量

作者:laozhu1124 时间:2023-12-06 14:53:53 

        对于Android View的测量,我们一句话总结为:"给我位置和大小,我就知道您长到那里"。

为了让大家更好的理解这个结论,我这里先讲一个日常生活中的小故事:不知道大家玩过"瞎子画画"的游戏没,一个人蒙上眼睛,拿笔去画板上画一些指定的图案,另外一个人则充当他的"眼睛",通过语言告诉他在画板那个位置画一个多大的图案。倘若,这个人不告诉那个蒙着眼睛的人,在那个画一个多大的图案。那么这个蒙着眼睛的人此时真是"河里赶大车----------没辙"。其实,Android就是这个蒙着眼睛的人,我们必须精确地告诉他如何去画,它才能画出你所想要的图形。

大家是不是对Android布局的测量进行现实世界进行类比了。为了实现View具体布局在哪儿,Android设计了一个短小精悍又功能强大的类——measureSpec类。这样妈妈再也不用担心我不会测量View了。那么,MeasureSpec到底是个什么鬼了。MeasureSpec,归根结底是一个32位的int值。其中高2位表示测量的模式,低30位表示测量View的大小。这样做有什么好处。这样做通过位运算来提高运行效率。

要了解MeasureSpec这个类的来弄去脉的话,务必要对测量的三种模式了解。

1.EXACTLY(精准的)

当您设置View的layout_height属性或layout_width属性为确定的值或者为match_parent(填充父容器)时候,系统就将View测量模式设置为EXACTLY模式。

2.AT_MOST(最大值)

即布局为最大值模式,那么什么时候系统会将View调整为AT_MOST模式了,即当您设置View的layout_height属性或layout_width属性为wrap_content(包裹内容)时候。

3.UNSPECIFIED(未确定)

即没有确定,没有指定大小测量模式,view即“心有多大,舞台就有多大"。这个方法,一般在自定义控件中才能用到。

View测量的时候,默认是EXACTLY模式,也许你会感到纳闷,TextView,EditText这些控件,他怎么就支持wrap_content属性了,难道他重写OnMeasure方法,是的,他们都重写OnMeasure方法。这就是为什么我们在自定义控件的时候,如果要布局支持wrap_content属性,就需要重写onMeasure方法,来指定wrap_content为确切的大小。

这个关于测量模式的思维导图应该是这样的:

Android View如何测量

我们知道这么多理论的知识,是不是觉得即枯燥乏味又觉得然并卵。好吧,我们就直接上代码,在代码中解释MeasureSpec如何获取测量模式和测量的大小。源代码如下:

 Java代码如下:


public class MyView extends View {
 public MyView(Context context, AttributeSet attrs) {
   super(context, attrs);
 }

}

xml代码如下:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >

<com.example.test.MyView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:background="#00ff00"
     />
</LinearLayout>

运行效果如下所示:

Android View如何测量

通过这个短小精悍的例子,充分证明这样一个结论:View测量的时候,默认是EXACTLY模式,你不重写OnMeasure方法,即使设置wrap_content属性,他也是填充父容器。

那么,就通过MeasureSpec这个万金油类来重写一下OnMeasure方法。相应源代码如下:


 public MyView(Context context, AttributeSet attrs) {
   super(context, attrs);
 }
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   setMeasuredDimension(measureWidth(widthMeasureSpec),
       measureWidth(heightMeasureSpec));
 }
 public int measureWidth(int measureSpec) {
   int result = 0;
   int specMode = MeasureSpec.getMode(measureSpec);
   int specSize = MeasureSpec.getSize(measureSpec);
   if (specMode == MeasureSpec.EXACTLY) {
     result = specSize;
   } else {
     result = 200;
     if (specMode == MeasureSpec.AT_MOST) {
       result = Math.min(specSize, result);
     }
   }
   return result;
 }

运行效果如下:

Android View如何测量

同样的例子,我们只不过是重写了OnMeasure方法,通过MeasureSpec.getMode(measureSpec)获取测量模式的时候,通过MeasureSpec.getSize(measureSpec)获取控件尺寸。判断当布局属性为wrap_content,指定为一确切值,这时,控件就符合wrap_content属性。

标签:Android,View,测量
0
投稿

猜你喜欢

  • Android实现简易计算功能

    2022-01-10 20:42:59
  • Android中一种巧妙的drawable.xml替代方案分享

    2021-12-06 04:18:35
  • IDEA设置生成带注释的getter和setter的图文教程

    2023-06-28 00:49:36
  • Java中Map与JSON数据之间的互相转化

    2021-10-26 01:56:19
  • Android贝塞尔曲线初步学习第二课 仿QQ未读消息气泡拖拽黏连效果

    2023-08-18 10:18:20
  • C#如何消除验证码图片的锯齿效果

    2023-11-05 04:49:14
  • Spring中的事务隔离级别和传播行为

    2022-07-21 18:18:24
  • Ubuntu16.04 LTS 下安装 Android Studio 2.2.2 的详细步骤

    2022-08-11 09:59:22
  • 深入c# Func委托的详解

    2022-02-15 05:44:51
  • 提权函数之RtlAdjustPrivilege()使用说明

    2021-08-27 04:16:49
  • Android 属性动画ValueAnimator与插值器详解

    2023-04-12 19:05:33
  • Java调用Shell命令的方法

    2022-01-06 20:01:34
  • Android使用AudioManager修改系统音量的方法

    2023-11-20 09:10:00
  • java图片识别文字的方法

    2021-11-11 02:43:03
  • C#中static的详细用法实例

    2021-05-27 21:37:00
  • Flowable执行完毕的流程查找方法

    2023-01-30 08:53:36
  • C#中new操作符的工作机制

    2023-12-08 13:57:20
  • java导出大批量(百万以上)数据的excel文件

    2023-11-16 13:13:22
  • Maven项目部署到服务器设置访问路径以及配置虚拟目录的方法

    2023-12-04 02:12:12
  • ssm框架下web项目,web.xml配置文件的作用(详解)

    2021-07-31 14:42:11
  • asp之家 软件编程 m.aspxhome.com