知识点整理

  • 1. LayoutParams
  • 2. MarginLayoutParams
  • 3 LayoutParams与View如何建立联系
  • 4 自定义LayoutParams
    • 4.1 创建自定义属性
    • 4.2 继承MarginLayout
    • 4.3 重写ViewGroup中几个与LayoutParams相关的方法
  • 5 LayoutParams常见的子类

1. LayoutParams

LayoutParams翻译过来就是布局参数,子View通过LayoutParams告诉父容器(ViewGroup)应该如何放置自己。
从这个定义中也可以看出来LayoutParams与ViewGroup是息息相关的,因此脱离ViewGroup谈LayoutParams是没
有意义的。
事实上,每个ViewGroup的子类都有自己对应的LayoutParams类,典型的如LinearLayout.LayoutParams和
FrameLayout.LayoutParams等,可以看出来LayoutParams都是对应ViewGroup子类的内部类。

2. MarginLayoutParams

MarginLayoutParams
MarginLayoutParams是和外间距有关的。事实也确实如此,和LayoutParams相比,MarginLayoutParams只是增加了对上下左右外间距的支持。实际上大部分LayoutParams的实现类都是继承自MarginLayoutParams,因为基本所有的父容器都是支持子View设置外间距的

  • 属性优先级问题 MarginLayoutParams主要就是增加了上下左右4种外间距。在构造方法中,先是获取了margin属性;如果该值不合法,就获取horizontalMargin;如果该值不合法,再去获取leftMargin和rightMargin属性(verticalMargin、topMargin和bottomMargin同理)。我们可以据此总结出这几种属性的优先级.
margin > horizontalMargin和verticalMargin > leftMargin和RightMargin、topMargin和bottomMargin
  • 属性覆盖问题 优先级更高的属性会覆盖掉优先级较低的属性。此外,还要注意一下这几种属性上的注释
Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value

3 LayoutParams与View如何建立联系

  • 在XML中定义View
  • 在Java代码中直接生成View对应的实例对象
    addView
/**
* 重载方法1:添加一个子View
* 如果这个子View还没有LayoutParams,就为子View设置当前ViewGroup默认的LayoutParams
*/
public void addView(View child) {addView(child, -1);
}
/**
* 重载方法2:在指定位置添加一个子View
* 如果这个子View还没有LayoutParams,就为子View设置当前ViewGroup默认的LayoutParams
* @param index View将在ViewGroup中被添加的位置(-1代表添加到末尾)
*/
public void addView(View child, int index) {if (child == null) {throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");}LayoutParams params = child.getLayoutParams();if (params == null) {params = generateDefaultLayoutParams();// 生成当前ViewGroup默认的LayoutParamsif (params == null) {throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return
null");}}addView(child, index, params);
}
/**
* 重载方法3:添加一个子View
* 使用当前ViewGroup默认的LayoutParams,并以传入参数作为LayoutParams的width和height
*/
public void addView(View child, int width, int height) {final LayoutParams params = generateDefaultLayoutParams();  // 生成当前ViewGroup默认的
LayoutParamsparams.width = width;params.height = height;addView(child, -1, params);
}
/**
* 重载方法4:添加一个子View,并使用传入的LayoutParams
*/
@Override
public void addView(View child, LayoutParams params) {addView(child, -1, params);
}
/**
* 重载方法4:在指定位置添加一个子View,并使用传入的LayoutParams
*/
public void addView(View child, int index, LayoutParams params) {if (child == null) {throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");}// addViewInner() will call child.requestLayout() when setting the new LayoutParams// therefore, we call requestLayout() on ourselves before, so that the child's request// will be blocked at our levelrequestLayout();invalidate(true);addViewInner(child, index, params, false);
}
private void addViewInner(View child, int index, LayoutParams params,boolean preventRequestLayout) {.....if (mTransition != null) {mTransition.addChild(this, child);}if (!checkLayoutParams(params)) { // ① 检查传入的LayoutParams是否合法params = generateLayoutParams(params); // 如果传入的LayoutParams不合法,将进行转化操作}if (preventRequestLayout) { // ② 是否需要阻止重新执行布局流程child.mLayoutParams = params; // 这不会引起子View重新布局(onMeasure->onLayout-
>onDraw)} else {child.setLayoutParams(params); // 这会引起子View重新布局(onMeasure->onLayout-
>onDraw)}if (index < 0) {index = mChildrenCount;}addInArray(child, index);// tell our childrenif (preventRequestLayout) {child.assignParent(this);} else {child.mParent = this;}.....
}

4 自定义LayoutParams

4.1 创建自定义属性

<resources><declare-styleable name="xxxViewGroup_Layout"><!-- 自定义的属性 --><attr name="layout_simple_attr" format="integer"/><!-- 使用系统预置的属性 --><attr name="android:layout_gravity"/></declare-styleable>
</resources>

4.2 继承MarginLayout

public static class LayoutParams extends ViewGroup.MarginLayoutParams {public int simpleAttr;public int gravity;public LayoutParams(Context c, AttributeSet attrs) {super(c, attrs);// 解析布局属性TypedArray typedArray = c.obtainStyledAttributes(attrs,
R.styleable.SimpleViewGroup_Layout);simpleAttr =
typedArray.getInteger(R.styleable.SimpleViewGroup_Layout_layout_simple_attr, 0);gravity=typedArray.getInteger(R.styleable.SimpleViewGroup_Layout_android_layout_gravity,
-1);typedArray.recycle();//释放资源}public LayoutParams(int width, int height) {super(width, height);}public LayoutParams(MarginLayoutParams source) {super(source);}public LayoutParams(ViewGroup.LayoutParams source) {super(source);}
}

4.3 重写ViewGroup中几个与LayoutParams相关的方法

// 检查LayoutParams是否合法
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {return p instanceof SimpleViewGroup.LayoutParams;
}
// 生成默认的LayoutParams
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {return new SimpleViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
}
// 对传入的LayoutParams进行转化
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {return new SimpleViewGroup.LayoutParams(p);
}
// 对传入的LayoutParams进行转化
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {return new SimpleViewGroup.LayoutParams(getContext(), attrs);
}

5 LayoutParams常见的子类

在为View设置LayoutParams的时候需要根据它的父容器选择对应的LayoutParams,否则结果可能与预期不一致,
这里简单罗列一些常见的LayoutParams子类:

  • ViewGroup.MarginLayoutParams
  • FrameLayout.LayoutParams
  • LinearLayout.LayoutParams
  • RelativeLayout.LayoutParams
  • RecyclerView.LayoutParams
  • GridLayoutManager.LayoutParams
  • StaggeredGridLayoutManager.LayoutParams
  • ViewPager.LayoutParams
  • WindowManager.LayoutParams

五 自定义View LayoutParams相关推荐

  1. 【安卓开发 】Android初级开发(五)自定义View

    1.自定义View的构造函数调用的场景 package com.sina.myapplication;import android.content.Context; import android.ut ...

  2. View (五)自定义View的实现方法

    一些接触Android不久的朋友对自定义View都有一丝畏惧感,总感觉这是一个比较高级的技术,但其实自定义View并不复杂,有时候只需要简单几行代码就可以完成了. 如果说要按类型来划分的话,自定义Vi ...

  3. android多行文字正中间显示,Android自定义View五(绘制文本大小、多行多列居中)...

    一.绘制文本 在Canvas中绘制文本,使用前面文章的坐标系 1.drawText的几种方法 public void drawText (String text, float x, float y, ...

  4. android 自定义view仿支付宝写五褔及播放

    本文记录一下实现仿支付宝写五褔及回放的过程. 先看效果如下,没有找到相关的背景图,只能以田字格当作背景. 整个过程分为两部分,一部分是写字,一部份是回放. 该过程主要使用了path和pathmeasu ...

  5. 精通Android自定义View(五)自定义属性值使用详情

    1 可查看Android自定义View的基本使用 1 精通Android自定义View(一)自定义控的基本使用 2 精通Android自定义View(二)自定义属性使用详解 2 string 字符串 ...

  6. 60.自定义View练习(五)高仿小米时钟 - 使用Camera和Matrix实现3D效果

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 本文出自:猴菇先生的博客 http://blog.csdn.net/qq_31715429/article/details/546 ...

  7. Android自定义View,滑动,事件传递小结

    本文只总结知识点 欢迎补充,欢迎纠正.谢谢! #预备知识 Android控件框架 ####1. View树状图 Android的View树结构总是以一个ViewGroup开始,包含多个View或Vie ...

  8. 【Android 修炼手册】常用技术篇 -- Android 自定义 View

    这是[Android 修炼手册]系列第 9 篇文章,如果还没有看过前面系列文章,欢迎点击 这里 查看- 预备知识 了解 android 基本开发 看完本文可以达到什么程度 学会自定义 View 以及其 ...

  9. Android自定义view之measure、layout、draw三大流程

    自定义view之measure.layout.draw三大流程 一个view要显示出来,需要经过测量.布局和绘制这三个过程,本章就这三个流程详细探讨一下.View的三大流程具体分析起来比较复杂,本文不 ...

最新文章

  1. 视频动作识别--Temporal Segment Networks: Towards Good Practices for Deep Action Recognition
  2. 一场稳定、高清、流畅的大型活动直播是怎么炼成的?
  3. Word画线条5大技巧,简单实用!
  4. 悼念512汶川大地震遇难同胞——老人是真饿了
  5. 2.1 数个常用的网络命令
  6. android listview设置选中时的item的背景色
  7. 深度学习(三)——Autoencoder, 词向量
  8. jdk8 参数为方法_JDK 8中的几乎命名的方法参数
  9. ECCV2020 Oral | 图像修复之再思考
  10. w ndows8系统没有声音怎么,Windows 8.1 系统新装没有声音
  11. php mvc 实现,php mvc的简单实现
  12. Kafka数据迁移MaxCompute最佳实践
  13. elasticsearch搜索推荐系列(二)之 java实现中文转化为拼音与简称
  14. Java随笔记 - 实现一个自定义的BitMap
  15. 这可能是你能找到最全面的数据预处理介绍
  16. 宇视网络视频录像机通道名称如何设置
  17. App设计者开发APP要注意的21个雷区(上)
  18. audio实现歌词同步
  19. 【详细搭建教程】在线客服系统源码3.0防黑版,即时聊天通讯源码 带机器人,防注入 无后门
  20. python网络爬虫网易云音乐下载_python网络爬虫爬取网易云音乐

热门文章

  1. 日常记录生活中的那些小小事01
  2. Intent的七大属性, ComponentName、  Action 、 Category 、 Data  、Type、  Extra  、Flags。
  3. 指数平滑法 Exponential Smoothing
  4. 指派问题数学规划matlab,数学建模(一)线性规划
  5. 组合数据类型——字典(dict)
  6. 为什么说网络安全行业是IT行业最后的红利?
  7. CSDN中如何将图片缩小
  8. 秀米新技能:如何在秀米推文中上传附件?如Word、Excel、PPT、PDF等
  9. 如何将excel表格的.csv(逗号分隔值文件)转换成.xls文件
  10. php hr样式虚线,CSS的虚线样式怎么实现