Android 自定义View总结 —— LayoutParams

来源:互联网 发布:java小游戏设计 编辑:程序博客网 时间:2024/05/18 03:21

说明:本博客为原创,转载请注明出处 CSDN-ANDROID笔记栈
由于作者水平有限,错误在所难免,请见谅,可以留言,本人会及时改正


索引

  • LayoutParams
    • MarginLayoutParams
      • FrameLayout LayoutParams
      • LinearLayoutParams
  • Demo


<FrameLayout ...>    <TextView         android:layout_width="match_parent"        android:layout_height="48dp"        android:layout_gravity="center"        android:layout_marginLeft="12dp"        .../><FrameLayout/>

上面这段代码想必大家都不陌生,在xml文件中定义了一个TextView标签,并且对TextView期望的大小及对齐方式做了说明:和父视图一样宽,48dp高,居中对齐。
其实这几个属性对应的就是LayoutParams中的width、height、gravity属性。
LayoutParams是View告诉ParentView自己想要多大,想以哪种方式对齐等

下面来看下LayoutParent的源码

LayoutParams

//这是所有的LayoutParams的基类,定义在ViewGroup类中public static class LayoutParams {    @Deprecated    public static final int FILL_PARENT = -1;    public static final int MATCH_PARENT = -1; //和父View一样大    public static final int WRAP_CONTENT = -2; //根据内容自适应大小    public int width; //宽:只能是-1,-2,或者是>0的一个精确值    public int height; //高    public LayoutAnimationController.AnimationParameters layoutAnimationParameters;    public LayoutParams(Context c, AttributeSet attrs) {        // xml中读取属性,设置witdh和height        TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.ViewGroup_Layout);        setBaseAttributes(a,                 R.styleable.ViewGroup_Layout_layout_width,                 R.styleable.ViewGroup_Layout_layout_height);            a.recycle();        }    public LayoutParams(int width, int height) {        this.width = width;        this.height = height;    }}

MarginLayoutParams

// MarginLayoutParams 也定义在ViewGroup中继承LayoutParamspublic static class MarginLayoutParams extends ViewGroup.LayoutParams {    public int leftMargin; //左边距值,对应xml中的layout_marginLeft属性    public int topMargin; //上边距,和leftMargin类似    public int rightMargin;    public int bottomMargin;    private int startMargin = DEFAULT_MARGIN_RELATIVE;    private int endMargin = DEFAULT_MARGIN_RELATIVE;    ...}

FrameLayout LayoutParams

// FrameLayoutParams 定义在FrameLayout类中继承于MarginLayoutParamspublic static class LayoutParams extends MarginLayoutParams{    public static final int UNSPECIFIED_GRAVITY = -1;    public int gravity = UNSPECIFIED_GRAVITY; // 对齐方式    ...}

LinearLayoutParams

// LinearLayoutParams定义在LinearLayout类中继承与MarginLayoutParamspublic static class LayoutParams extends ViewGroup.MarginLayoutParams {    public float weight; // 权重比    public gravity=-1; // 对齐方式    ...}

LayoutParams 有很多分支,一般特殊的ViewGroup都定义特殊的LayoutPrams以实现自己的布局方式,这里只对最常见的几个做了介绍

<FrameLayout ...>    <TextView         android:layout_width="match_parent"        android:layout_height="48dp"        android:layout_gravity="center"        android:layout_marginLeft="12dp"        .../><FrameLayout/>

再次回到这段代码,如果你想在这个TextView中添加android:layout_weight这个属性,你会发现代码提示功能无法完成自动添加,即使你手动添加也没有任何作用。
因为TextView的父亲是FrameLayout,对于layout_weight 这个属性,FrameLayout不认识它!

public class View {    ...    // 在View类中有一个ViewGroup.LayoutParams    protected ViewGroup.LayoutParams mLayoutParams;    // android在解析xml之后会对这个LayoutPrams赋值,在上面的xml中,这个LayoutParams会被赋值成FrameLayout.LayoutParams对象!    // 在FrameLayout和View类中找不到对LayoutParams赋值的代码    // 关于具体如何赋值在哪里赋值可以自己google ^^}

Demo

GitHub地址: GitHub
环境: Windows7+JAVA8
IDE: AndroidStdio2.2.2
compileSdkVersion:24
测试设备:Nexus5(6.0.1)

运行结果截图
CustomViewLayoutParams

Demo中有多段实例,在manifest中更改默认启动项就可以了

// 自定义ViewGroup 支持attrs ‘ignore’,layout支持对于margin属性的支持<com.neulion.android.dl.customviewdemo.widget.DLCustomViewGroup            android:layout_width="match_parent"            android:layout_height="match_parent"            android:background="#888888">        <TextView                android:layout_width="48dp"                android:layout_height="48dp"                android:layout_marginLeft="12dp"                android:layout_marginRight="12dp"                android:background="@color/colorAccent" />        <TextView                android:layout_width="48dp"                android:layout_height="48dp"                android:layout_marginLeft="12dp"                android:layout_marginRight="12dp"                android:background="@color/colorPrimary" />        <TextView                android:layout_width="48dp"                android:layout_height="48dp"                android:layout_marginLeft="12dp"                android:layout_marginRight="12dp"                android:background="#000000"                app:ignore="true" />        <TextView                android:layout_width="48dp"                android:layout_height="48dp"                android:layout_marginLeft="12dp"                android:layout_marginRight="12dp"                android:background="#ffbb00" /> </com.neulion.android.dl.customviewdemo.widget.DLCustomViewGroup>

CustomViewGroup中重载了如下方法

protected boolean checkLayoutParams(ViewGroup.LayoutParams p){    return p instanceof CustomLayoutParams;}protected ViewGroup.LayoutParams generateDefaultLayoutParams(){    return new CustomLayoutParams(CustomLayoutParams.WRAP_CONTENT, CustomLayoutParams.WRAP_CONTENT);}protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p){    if (p instanceof MarginLayoutParams){        return new CustomLayoutParams((MarginLayoutParams) p);    }    return new CustomLayoutParams(p);}

新增了自定义的LayoutParams类

public static class CustomLayoutParams extends MarginLayoutParams{    public boolean ignore = false;    public CustomLayoutParams(Context c, AttributeSet attrs){        super(c, attrs);        TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.DLCustomViewGroup);        ignore = a.getBoolean(R.styleable.DLCustomViewGroup_ignore, false);        a.recycle();    }    public CustomLayoutParams(int width, int height){        super(width, height);    }    public CustomLayoutParams(MarginLayoutParams source){        super(source);    }    public CustomLayoutParams(ViewGroup.LayoutParams source){        super(source);    }}

0 0
原创粉丝点击