ViewGroup.LayoutParams 和 MeasureSpec

ViewGroup.LayoutParams 和 MeasureSpec1.LayoutParams LayoutParams 是ViewGroup的内部静态类,ViewGroup的子类(如RelativeLayout,LinearLayout,FrameLayout)都有其对应的   ViewGroup.LayoutParams的子类,如RelativeLayoutParams LayoutParams的作用:指定视图View 的高度(heig…

大家好,又见面了,我是你们的朋友全栈君。

1.LayoutParams

 LayoutParams  是ViewGroup的内部静态类 ,ViewGroup的子类(如RelativeLayout,LinearLayout,FrameLayout)都有其对应的     ViewGroup.LayoutParams的子类,如RelativeLayoutParams

 LayoutParams 的作用:指定视图View 的高度(height) 和 宽度(width)等布局参数,具体如下:

参数 解释
具体值 dp / px
fill_parent 强制性使子视图的大小扩展至与父视图大小相等(不含 padding )
match_parent 与fill_parent相同,用于Android 2.3 & 之后版本
wrap_content 自适应大小,强制性地使视图扩展以便显示其全部内容(含 padding )

对应于xml如下:

android:layout_height=”wrap_content”   //自适应大小  
android:layout_height=”match_parent”   //与父视图等高  
android:layout_height=”fill_parent”    //与父视图等高  
android:layout_height=”20dp”         //精确设置高度值为 20dp

下面是一个LinearLayoutParams的使用示例:

ViewGroup.LayoutParams 和 MeasureSpec

布局文件如下,只有一个TextView

<LinearLayout
    android:id="@+id/linear"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView
        android:layout_width="200dp"
        android:layout_height="30dp"
        android:text="第一个TextView"
        android:gravity="center"
        android:background="#6f00"
        />
</LinearLayout>

Activity代码如下:

public class MainActivity extends AppCompatActivity {

    private LinearLayout mRootView;
    private LinearLayout mLinearLayout;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRootView = (LinearLayout) findViewById(R.id.linear);

        // 把 LinearLayout 添加到布局里面
        mLinearLayout = new LinearLayout(MainActivity.this);
        mLinearLayout.setBackgroundColor(Color.parseColor("#00ff00"));

        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
        mLinearLayout.setLayoutParams(layoutParams);
        mRootView.addView(mLinearLayout);

        // 第二步,把TextView 添加到 LinearLayout,以增加一个TextView
        TextView textView = new TextView(MainActivity.this);
        textView.setText("第二个TextView");
        textView.setTextSize(20);
        textView.setBackgroundColor(Color.parseColor("#ff0000"));
        textView.setGravity(Gravity.CENTER);
        mLinearLayout.addView(textView);

        // 设置TextView大小为具体值
        LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(textView.getLayoutParams());
        textParams.width = dip2px(MainActivity.this,200);
        textParams.height = dip2px(MainActivity.this,30);
        textView.setLayoutParams(textParams);

    }

    private int dip2px(Context context, float dipValue)
    {
        Resources r = context.getResources();
        return (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, dipValue, r.getDisplayMetrics());
    }


}

2.MeasureSpec

测量规格(MeasureSpec) = 测量模式(mode) + 测量大小(size)

ViewGroup.LayoutParams 和 MeasureSpec

其中,测量模式(Mode)的类型有3种:UNSPECIFIED、EXACTLY 和 AT_MOST。具体如下:

ViewGroup.LayoutParams 和 MeasureSpec

 

MeasureSpec 被封装在View类中的一个内部类里:MeasureSpec

MeasureSpec类 用1个变量封装了2个数据(size,mode)通过使用二进制,将测量模式(mode) & 测量大小(size)打包成一个int值来,并提供了如下的打包/解包的方法

/** * MeasureSpec类的具体使用 **/ //

   获取测量模式(Mode)                                int specMode = MeasureSpec.getMode(measureSpec)

   获取测量大小(Size)                                  int specSize = MeasureSpec.getSize(measureSpec)

   通过Mode 和 Size 生成新的SpecMode         int measureSpec=MeasureSpec.makeMeasureSpec(size, mode);

 

MeasureSpec值的计算:子View的MeasureSpec值根据子View的布局参数(LayoutParams)和父容器的MeasureSpec值计算得来的,具体计算逻辑封装在getChildMeasureSpec(),即view的大小由父viewMeasureSpec值 和 子viewLayoutParams属性 共同决定。

/**

  * 源码分析:getChildMeasureSpec()

  * 作用:根据父视图的MeasureSpec & 布局参数LayoutParams,计算单个子ViewMeasureSpec

  * 注:子view的大小由父viewMeasureSpec viewLayoutParams属性 共同决定

  **/

 

    public static int getChildMeasureSpec(int spec, int padding, int childDimension) { 

         //参数说明

         * @param spec view的详细测量值(MeasureSpec)

         * @param padding view当前尺寸的的内边距和外边距(padding,margin)

         * @param childDimension 子视图的布局参数(宽/高)

            //view的测量模式

            int specMode = MeasureSpec.getMode(spec);    

            //view的大小

            int specSize = MeasureSpec.getSize(spec);    

            //通过父view计算出的子view = 父大小边距(父要求的大小,但子view不一定用这个值)  

            int size = Math.max(0, specSize – padding); 

            //view想要的实际大小和模式(需要计算) 

            int resultSize = 0

            int resultMode = 0;  

            //通过父viewMeasureSpec和子viewLayoutParams确定子view的大小 

            // 当父view的模式为EXACITY时,父view强加给子view确切的值

           //一般是父view设置为match_parent或者固定值的ViewGroup

            switch (specMode) { 

            case MeasureSpec.EXACTLY: 

                // 当子viewLayoutParams>0,即有确切的值 

                if (childDimension >= 0) { 

                    //view大小为子自身所赋的值,模式大小为EXACTLY 

                    resultSize = childDimension; 

                    resultMode = MeasureSpec.EXACTLY; 

                // 当子viewLayoutParamsMATCH_PARENT(-1) 

                } else if (childDimension == LayoutParams.MATCH_PARENT) { 

                    //view大小为父view大小,模式为EXACTLY 

                    resultSize = size; 

                    resultMode = MeasureSpec.EXACTLY; 

                // 当子viewLayoutParamsWRAP_CONTENT(-2)     

                } else if (childDimension == LayoutParams.WRAP_CONTENT) { 

                    //view决定自己的大小,但最大不能超过父view,模式为AT_MOST 

                    resultSize = size; 

                    resultMode = MeasureSpec.AT_MOST; 

                } 

                break

            // 当父view的模式为AT_MOST时,父view强加给子view一个最大的值。(一般是父view设置为wrap_content 

            case MeasureSpec.AT_MOST: 

                // 道理同上 

                if (childDimension >= 0) { 

                    resultSize = childDimension; 

                    resultMode = MeasureSpec.EXACTLY; 

                } else if (childDimension == LayoutParams.MATCH_PARENT) { 

                    resultSize = size; 

                    resultMode = MeasureSpec.AT_MOST; 

                } else if (childDimension == LayoutParams.WRAP_CONTENT) { 

                    resultSize = size; 

                    resultMode = MeasureSpec.AT_MOST; 

                } 

                break

            // 当父view的模式为UNSPECIFIED时,父容器不对view有任何限制,要多大给多大

            // 多见于ListViewGridView 

            case MeasureSpec.UNSPECIFIED: 

                if (childDimension >= 0) { 

                    // view大小为子自身所赋的值 

                    resultSize = childDimension; 

                    resultMode = MeasureSpec.EXACTLY; 

                } else if (childDimension == LayoutParams.MATCH_PARENT) { 

                    // 因为父viewUNSPECIFIED,所以MATCH_PARENT的话子类大小为

                    resultSize = 0

                    resultMode = MeasureSpec.UNSPECIFIED; 

                } else if (childDimension == LayoutParams.WRAP_CONTENT) { 

                    // 因为父viewUNSPECIFIED,所以WRAP_CONTENT的话子类大小为0  

                    resultSize = 0

                    resultMode = MeasureSpec.UNSPECIFIED; 

                } 

                break

            } 

            return MeasureSpec.makeMeasureSpec(resultSize, resultMode); 

        }

ViewGroup.LayoutParams 和 MeasureSpec

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/160854.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • PLSQL基本操作手册

    PLSQL基本操作手册公众号:池哥搬砖QQ1群:745460286个人WX公号:目录第1章用PLSQL连接Oracle数据库§1.2登录信息保存功能设置:§1.3进入PLSQL后切换数据库连接:第2章PLSQL中编写SQL语句并执行第3章PLSQL中查看数据库表结构§3.1查看表结构:§3.2表结构窗口和SQL编写窗口切换:第4章…

  • freemarker生成java代码_freemarker生成word文档

    freemarker生成java代码_freemarker生成word文档java用freemarker生成word文档.    步骤如下:1,新建一个word文档,另存为test.xml格式的.2,新建java类.(使用freemarker-2.3.10.jar包.请自行下载.)3,把里面需要替换的换成${name}这种. 对应语法参考freemarkerapi.包结构如下:java类:packa

    2022年10月10日
  • NP-Hard问题浅谈

    NP-Hard问题浅谈看相关算法的paper的时候,经常会出现NP-Hard这个词。本博主也不是纯数学系出身,对于这么高深的问题自然没有特别深入独到的理解。但是本博主的习惯就是看到一个东西老在眼前晃来晃去但自己还不是很明白,就有强迫症一定要搞明白这到底是个什么玩意。so,咱们就来看看这个NP-Hard问题,怎么用最简单的方式去了解。1.世界七大数学难题之首2000年,美国克莱数学研究所公布了世界七大数学难题,又称千禧年大

  • 大J_gh5延时摄影怎么设置

    大J_gh5延时摄影怎么设置Jboot v2.0-rc.9 发布,优化细节问题

  • 快速阶乘算法python_【最全】阶乘算法!(python和C语言)

    快速阶乘算法python_【最全】阶乘算法!(python和C语言)阶乘的计算叁岁学编程:用最简单的大白话理解编程,欢迎大家关注,留言,提问,希望和大家一起提升!文章目录阶乘的计算阶乘定义:解析方法一:for循环计算方法二:定义for循环的函数计算方法三:定义递归函数计算小知识:C语言代码方法一:for函数方法二:递归函数总结:阶乘定义:阶乘指从1乘以2乘以3乘以4一直乘到所要求的数。例如所要求的数是4,则阶乘式是1×2×3×4,得到的积是24。24就是4的阶乘。…

  • 2021年最新Java学习路线图指南

    2021年最新Java学习路线图指南Java在编程语言排行榜中一直牢牢占据榜首位置,几乎所有的大中型互联网的应用系统在服务器端开发首选都是Java编程,正因如何吸引这不少年轻人投入该行业,Java虽不想其它编程语言那么复杂,但是知识体系还是很庞大的,因此想要学好并非容易之事,不少想要跨入Java编程行业的同学们通过网络搜索各式各样的学习资料,却往往缺乏系统而全面的学习路线。动力节点深知同学们的学习困难,为此整理了一套最新的2021年新版学习路线图,增加了目前企业最新应用技术,这套学习路线图,只要你完成一半基本就可以找到很不错的…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号