1.MeasureSpec含义

其实可以去看MeasureSpec的文档,里面对MeasureSpec的作用介绍得很清楚.MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。

2.MeasureSpec的三个模式详解不定的,恰恰和AT_MOST

视图大小的基本定义如下:
MeasureSpec.EXACTLY - 视图应该是这么多像素,无论它实际上有多大。
MeasureSpec.AT_MOST - 如果视图的尺寸较小,则视图可以是此尺寸或更小。
MeasureSpec.UNSPECIFIED - 视图可以是它需要的任何大小,以显示它需要显示的内容。
如果父视图的大小绑定,MeasureSpec.AT_MOST将应用于已设置为WRAP_CONTENT的视图。例如,您的父视图可能绑定到屏幕大小。它的孩子也会受到这种规模的束缚,但它可能不会那么大。因此,父视图将MeasureSpec设置为AT_MOST,告诉孩子它可以是0到屏幕大小之间的任何位置。孩子必须做出调整,以确保它符合所提供的范围。
在特殊情况下,界限无关紧要。例如,ScrollView。对于ScrollView,子视图的高度无关紧要。因此,它将为孩子们提供一个未知的视图,告诉孩子他们可以达到他们需要的高度。ScrollView将处理它们的绘图和放置。

翻译一下(直接用软件翻译过来的,不明白的话,下面会通过例子说明):

查看的大小基本定义如下:
MeasureSpec.EXACTLY - 表示父控件已经确切的指定了子查看的大小.MeasureSpec.AT_MOST
- 表示子查看具体大小没有尺寸限制,但是存在上限,上限一般为父查看大小.MeasureSpec
。未知 - 父控件没有给子视任何限制,子查看可以设置为任意大小。
如果父视图的大小已经指定则MeasureSpec.AT_MOST将应用于已设置为WRAP_CONTENT的子视图。例如,你的父视图可能绑定到屏幕大小。它的孩子也会绑定到这个大小,但它可能不是那么大。因此,父视图将MeasureSpec设置为AT_MOST,它告诉孩子它可以在0和屏幕之间的任何地方。孩子必须进行调整,以确保它符合提供的界限。
在特殊情况下,界限无关紧要。例如,一个ScrollView。在ScrollView的情况下,子视图的高度是不相关的。因此,它将向孩子提供一个未知视图,告诉孩子他们可以像他们需要的一样高 .ScrollView将处理它们的绘图和放置。

模式 数值 描述
UNSPECIFIED 0(0x00000000) 父控件没有给子视图任何限制,子视图可以设置为任意大小。
究竟 1073741824(0x40000000) 表示父控件已经确切的指定了子视图的大小。
最多 -2147483648(0x80000000) 表示子查看具体大小没有尺寸限制,但是存在上限,上限一般为父视图大小。

3.例子解析

这里分为两个部分例子,例子一是父布局是LinearLayout中,子布局是LinearLayout中,例子二是是父布局是滚动型,子布局是LinearLayout中。

1)例子一解释EXACTLY和AT_MOST

布局文件

<?xml version="1.0" encoding="utf-8"?>
<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" > <com.example.transdotnavi.widget.NormalDot
android:id="@+id/dot1"
android:layout_width="20dp"
android:layout_height="match_parent"
android:background="#F7F6F5" >
</com.example.transdotnavi.widget.NormalDot> </LinearLayout>

子控件,对于具体解释可以看下面代码里的注释

/**
* @author Administrator
* 2016-10-22
*
* 普通的圆点导航器
* 用于测试父控件是layout,子控件是layout的情况
* 具体可以看layout.xml,里面定义了一个LinearLayout父布局,和一个NormalDot子布局
* 测试机器:160dpi 480*800
*/
public class NormalDot extends LinearLayout
{
public NormalDot(Context context)
{
super(context);
}
@SuppressLint("NewApi")
public NormalDot(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public NormalDot(Context context, AttributeSet attrs)
{
super(context, attrs);
} // MeasureSpec.AT_MOST = -2147483648 [0x80000000];
// MeasureSpec.EXACTLY = 1073741824 [0x40000000];
// MeasureSpec.UNSPECIFIED = 0 [0x0]; // 父布局LinearLayout固定width,height是match_parent(其实如果设置为wrap_content它的宽高也是等于屏幕宽高)
// 情况一:
// 当宽或高设为确定值时:即width=20dp,height=30dp,或者为match_parent。它会使用MeasureSpec.EXACTLY测量模式(表示父控件已经确切的指定了子View的大小)
// 情况二:
// 当宽或高设为wrap_content时,它会使用MeasureSpec.AT_MOST测量模式(表示子View具体大小没有尺寸限制,但是存在上限,上限一般为父View大小)
// 情况三:
// MeasureSpec.UNSPECIFIED,一般是在特殊情况下出现,如在父布局是ScrollView中才会出现这种测量模式
// 注意:
// 父视图可能绑定到屏幕大小。 它的孩子也会绑定到这个大小,但它可能不是那么大。
// 因此,父视图将MeasureSpec设置为AT_MOST ,
// 它告诉孩子它可以在0和屏幕之间的任何地方。 孩子必须进行调整,以确保它符合提供的界限。
// 通过一个例子解释上面面这句化的意思
// 父布局宽高都设置为match_parent,这时候父布局大小就是屏幕大小,这时候,他的子视图设置为width=20dp,height=wrap_content
// 看打出了的日志可以看到宽是20,高是800,这样的话我们应该能在屏幕的左边看到一条白色的宽为20的竖线,
// 但是事实上,我们在界面是没有看到这条竖线的,这是因为子布局可以占据0到屏幕大小这个范围,但是子布局通过调整,将height设置为0了,所以
// 我们看不到任何图像
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int mode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int mode2 = MeasureSpec.getMode(heightMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
Log.i("lgy", "mode:"+mode+" width:"+width);
Log.i("lgy", "mode2:"+mode2+" height:"+height);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

2)例子二解析的评论模式

布局文件

<?xml version="1.0" encoding="utf-8"?>
<com.example.transdotnavi.widget.LScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" > <com.example.transdotnavi.widget.NormalDot2
android:id="@+id/dot2"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#F7F6F5" >
<!--
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
-->
</com.example.transdotnavi.widget.NormalDot2> </com.example.transdotnavi.widget.LScrollView>

子控件

/**
* @author Administrator
* 2016-10-22
*
* 普通的圆点导航器
* 用于测试父控件是ScrollView,子控件是layout的情况
* 具体可以看layout2.xml,里面定义了一个ScrollView父布局,和一个NormalDot2子布局
* 测试机器:160dpi 480*800
*/
public class NormalDot2 extends LinearLayout
{ public NormalDot2(Context context)
{
super(context);
} /**
* @param context
* @param attrs
* @param defStyleAttr
*/
@SuppressLint("NewApi")
public NormalDot2(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
} /**
* @param context
* @param attrs
*/
public NormalDot2(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
} // MeasureSpec.AT_MOST = -2147483648 [0x80000000];
// MeasureSpec.EXACTLY = 1073741824 [0x40000000];
// MeasureSpec.UNSPECIFIED = 0 [0x0]; // 这里主要展示的是MeasureSpec.UNSPECIFIED测量模式
// 情况一:垂直的ScrollView
// 父布局ScrollView宽高都是match_parent,子布局是一个NormalDot2设置宽高都是50dp
// 从打出的日志可以看到,宽是以MeasureSpec.EXACTLY模式测量的,width=50,
// 而高是以MeasureSpec.UNSPECIFIED模式测量的,height=0
// 这时候如果NormalDot2布局里没有任何控件,那么就不会显示任何东西
// 但如果在里面加个TextView,那么这个textView就会显示出来(当然这个textView是有内容的,否则也不会显示出来),
// 但这时候height还是以MeasureSpec.UNSPECIFIED模式测量,height=0 // 情况二:水平的ScrollView
// 父布局HorizontalScrollView宽高都是match_parent,子布局是一个NormalDot2设置宽高都是50dp
// 从打出的日志可以看到,宽是MeasureSpec.UNSPECIFIED模式测量的,width=0,
// 而高是以MeasureSpec.EXACTLY模式测量的,height=50
// 这时候如果NormalDot2布局里没有任何控件,那么就不会显示任何东西
// 但如果在里面加个TextView,那么这个textView就会显示出来(当然这个textView是有内容的,否则也不会显示出来),
// 但这时候width还是以MeasureSpec.UNSPECIFIED模式测量,width=0
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int mode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int mode2 = MeasureSpec.getMode(heightMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
Log.i("lgy", "============mode:"+mode+" width:"+width);
Log.i("lgy", "=============mode2:"+mode2+" height:"+height);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

父控件(滚动型)

/**
* @author LGY
* @time 2016-10-23
* @action
*/
public class LScrollView extends
HorizontalScrollView
//ScrollView
{ /**
* @param context
*/
public LScrollView(Context context)
{
super(context);
// TODO Auto-generated constructor stub
} /**
* @param context
* @param attrs
* @param defStyleAttr
*/
public LScrollView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
} /**
* @param context
* @param attrs
*/
public LScrollView(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
} /* (non-Javadoc)
* @see android.widget.ScrollView#onMeasure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int mode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int mode2 = MeasureSpec.getMode(heightMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
Log.i("lgy", "ScrollViewmode:"+mode+" width:"+width);
Log.i("lgy", "ScrollViewmode2:"+mode2+" height:"+height);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

android MeasureSpec的三个测量模式的更多相关文章

  1. <Android 基础(三)> MVP模式

    前言 MVP,这里指的并不是篮球比赛中的MVP(最有价值球员),而是一种代码框架和设计思想,它是由MVC演变而来的. MVP模式(Model-View-Presenter) 是MVC模式的一个衍生.主 ...

  2. Android:ScrollView和SwipeRefreshLayout高度测量

    今天组里的同事要做一个奇葩的效果,要求在ScrollView里嵌套一个RefreshLayout.类似代码如下: <?xml version="1.0" encoding=& ...

  3. android自定义控件(8)-利用onMeasure测量使图片拉伸永不变形,解决屏幕适配问题

    使用ImageView会遇到的问题 在Android应用中,都少不了图片的显示,ImageView,轮播图,ViewPager等等,很多都是来显示图片的,很多时候,我们都希望图片能够在宽度上填充父窗体 ...

  4. Android -- MeasureSpec

    自定义控件都会去重写View的onMeasure方法,因为该方法指定该控件在屏幕上的大小. protected void onMeasure (int widthMeasureSpec, int he ...

  5. Android中Activity的四大启动模式实验简述

    作为Android四大组件之一,Activity可以说是最基本也是最常见的组件,它提供了一个显示界面,从而实现与用户的交互,作为初学者,必须熟练掌握.今天我们就来通过实验演示,来帮助大家理解Activ ...

  6. Android源码学习之模板方法模式应用

    一.模板方法模式定义 模板方法模式定义: defines the skeleton of an algorithm in a method, deferring some steps to subcl ...

  7. 【转】android 电池(三):android电池系统

    关键词:android电池系统电池系统架构 uevent power_supply驱动 平台信息: 内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV3 ...

  8. Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式。

    原文:Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags();singleTask的两种启动方式. Android Activity 的四种启动模 ...

  9. 微信5.0 Android版飞机大战破解无敌模式手记

    微信5.0 Android版飞机大战破解无敌模式手记 转载: http://www.blogjava.net/zh-weir/archive/2013/08/14/402821.html 微信5.0 ...

随机推荐

  1. 团队作业Week5

    每个团队开一个讨论会,协商讨论团队贡献分的分配方式.每个团队的团队贡献分为50分/人.每个人分数不能相同,请详细说明分数的分配规则. 可参考这个博客. 截止时间:2014-10-27

  2. 12.23daily_scrum

    今天大家的工作重心在调试过程中,以便及时地发现和解决在调试过程中出现的问题和漏洞,悬浮窗测试工作也已经展开,主要集中在边缘设计代码的测试部分,具体工作如下: 具体工作: 小组成员 今日任务 明日任务 ...

  3. BlogPublishTool - 博客发布工具

    BlogPublishTool - 博客发布工具 这是一个发布博客的工具.本博客使用本工具发布. 本工具源码已上传至github:https://github.com/ChildishChange/B ...

  4. LeetCode 638 Shopping Offers

    题目链接: LeetCode 638 Shopping Offers 题解 dynamic programing 需要用到进制转换来表示状态,或者可以直接用一个vector来保存状态. 代码 1.未优 ...

  5. Daily Scrum - 11/23

    今天更新blog时发现了老师对我们daily scrum提的要求,从明天起除了简要记录组会的主要内容之外,还会总结上一个工作日每个组员的工作进度.代码提交情况和燃尽图. 今天会议内容主要是人千.章玮同 ...

  6. OVS 精确删除流表

    OVS 精确删除流表 前言 今天看了sdnlab小姐姐的mininet教程之后,看到有一个下流表的操作,优先级没能下成功,然后回来实验一下,这个问题是解决了,不过遇到了一个小问题,ovs如何精确删除流 ...

  7. [搜狐科技]由浅入深理解Raft协议

    由浅入深理解Raft协议 2017-10-16 12:12操作系统/设计 0 - Raft协议和Paxos的因缘 读过Raft论文<In Search of an Understandable ...

  8. k8s kubectl edit 方式修改 nodeport 的端口

    0. 买了一本 每天五分钟玩转 k8s 还有 刚才转帖的blog 里面有一个 kubectl edit 的语法能够在线更改端口号 ,之前一直没弄明白. 刚才做了下实验.发现很好用 这里记录一下. 1. ...

  9. 使用alpine的docker镜像下 dind 的方式安装dotnet core 的一个非dockerfile的方法

    1. 下载dind的镜像 docker pull docker:dind 2. 执行该镜像 docker run -it --privileged --name some-docker -d dock ...

  10. OneZero第四次站立会议(2016.3.24)

    会议时间:2016年3月24日 15:30~15:47 会议成员:冉华,张敏,王巍,夏一鸣. 会议目的:汇报前一天工作,全体成员评论,确定会后修改内容. 会议内容:以下为会议插图 1.界面原型方面,在 ...