自定义控件知识储备-LayoutParams的那些事

在上一篇文章里,我总结了一下自定义控件需要了解的基础知识:View的绘制流程——《自定义控件知识储备-View的绘制流程》。其中,在View的测量流程里,View的测量宽高是由父控件的MeasureSpec和View自身的LayoutParams共同决定的。MeasureSpec是什么,上一篇文章里已经说得很清楚了(啥,没看过?快去路克路克,(๑•̀ㅂ•́)و✧)。而LayoutParams呢?是时候在这里做个了断了。

LayoutParams是什么?

LayoutParams,顾名思义,就是Layout Parameters :布局参数。
很久很久以前,我就知道LayoutParams了,并且几乎天天见面。那时候在布局文件XML里,写的最多的肯定是android:layout_width = "match_parent"之类的了。比如:

常见布局文件的栗子

<TextView
    style="@style/text_flag_01"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_marginLeft="10dp"
    android:layout_gravity="center"
    android:gravity="center"
    android:text="英明神武蘑菇君"
    android:textColor="@color/white"
    android:background="@color/colorAccent"/>

我们都知道layout_widthlayout_height这两个属性是为View指定宽度的。不过,当时年轻的我心里一直有个疑问:为什么要加上”layout_”前缀修饰呢?其它的描述属性,如textColorbackground,都很正常啊!讲道理,应该用widthheight描述宽高才对啊?

后来呀,我遇到了LayoutParams,它说layout_width是它的属性而非View的,并且不只是针对这一个,而是所有以”layout_”开头的属性都与它有关!所以,它的东西当然要打上自己的标识”layout_”。(呵呵,嚣张个啥,到头来你自己还不是属于View的一部分( ̄┰ ̄*))

既然layout_width这样的属性是LayoutParams定义的,那为何会出现在描述View的xml属性里呢?View和LayoutParams之间有什么恩怨纠缠呢?

不吹不黑,咱们来看看官方文档是怎么说的:

  1. LayoutParams are used by views to tell their parents how they want to be laid out.
    – LayoutParams是View用来告诉它的父控件如何放置自己的。

  2. The base LayoutParams class just describes how big the view wants to be for both width and height.
    – 基类LayoutParams(也就是ViewGroup.LayoutParams)仅仅描述了这个View想要的宽度和高度。

  3. There are subclasses of LayoutParams for different subclasses of ViewGroup.
    – 不同ViewGroup的继承类对应着不同的ViewGroup.LayoutParams的子类。

看着我妙到巅峰的翻译,想必大家都看懂了<( ̄▽ ̄)/。看不懂?那我再来画蛇添足稍微解释一下:

  1. 上面我们提到过,描述View直接用它们自己的属性就好了,如textColorbackground等等,为什么还需要引入LayoutParams呢?在我看来,textColorbackground这样的属性都是只与TextView自身有关的,无论这个TextView处于什么环境,这些属性都是不变的。而layout_widthlayout_marginLeft这样的属性是与它的父控件息息相关的,是父控件通过LayoutParams提供这些”layout_”属性给孩子们用的;是父控件根据孩子们的要求(LayoutParams)来决定怎么测量,怎么安放孩子们的;是父控件……(写不下去了,我都快被父控件感动了,不得不再感慨一句,当父母的都不容易啊(′⌒`)) )。所以,View的LayoutParams离开了父控件,就没有意义了。

  2. 基类LayoutParams是ViewGroup类里的一个静态内部类(看吧,这就证明了LayoutParams是与父控件直接相关的),它的功能很简单,只提供了widthheight两个属性,对应于xml里的layout_widthlayout_height。所以,对任意系统提供的容器控件或者是自定义的ViewGroup,其chid view总是能写layout_widthlayout_height属性的。

  3. 自从有了ViewGroup.LayoutParams后,我们就可以在自定义ViewGroup时,根据自己的逻辑实现自己的LayoutParams,为孩子们提供更多的布局属性。不用说,系统里提供给我们的容器控件辣么多,肯定也有很多LayoutParams的子类啦。let us see see:

ViewGroup.LayoutParams的截图

果然,我们看到了很多ViewGroup.LayoutParams的子类,里面大部分我们应该都比较熟悉。如果你觉得和它们不熟,那就是你一厢情愿啦,你早就“偷偷摸摸”的用过它们好多次了→_→

ViewGroup.MarginLayoutParams

我们首先来看看ViewGroup.MarginLayoutParams,看名字我们也能猜到,它是用来提供margin属性滴。margin属性也是我们在布局时经常用到的。看看这个类里面的属性:

public static class MarginLayoutParams extends ViewGroup.LayoutParams {
   

        public int leftMargin;

        public int topMargin;

        public int rightMargin;

        public int bottomMargin;

        private int startMargin = DEFAULT_MARGIN_RELATIVE;

        private int endMargin = DEFAULT_MARGIN_RELATIVE;

        ...
    }    

前面4个属性是我们以前在布局文件里常用的,而后面的startMarginendMargin是为了支持RTL设计出来代替leftMarginrightMargin的。

一般情况下,View开始部分就是左边,但是有的语言目前为止还是按照从右往左的顺序来书写的,例如阿拉伯语。在Android 4.2系统之后,Google在Android中引入了RTL布局,更好的支持了从右往左文字布局的显示。为了更好的兼容RTL布局ÿ

  • 42
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
### 回答1: 要设置自定义控件布局,可以在自定义控件的构造函数中调用 `setLayout()` 方法,将布局设置为您想要的布局。例如,如果您想要使用垂直布局,则可以使用以下代码: ```java public class MyCustomView extends View { public MyCustomView(Context context) { super(context); // 创建一个垂直布局 LinearLayout layout = new LinearLayout(context); layout.setOrientation(LinearLayout.VERTICAL); // 在布局中添加其他控件,如 TextView、Button 等 TextView textView = new TextView(context); textView.setText("Hello, world!"); layout.addView(textView); // 将布局设置为自定义控件布局 setLayout(layout); } } ``` 请注意,`setLayout()` 方法是自定义控件类中的一个自定义方法,您需要根据自己的需求来实现它。在 `setLayout()` 方法中,您可以使用各种布局类(如 LinearLayout、RelativeLayout 等)来创建您想要的布局,并将其设置为自定义控件布局。 ### 回答2: 自定义控件是在原有控件的基础上进行扩展或改造,使其具备特定的功能和样式。设置布局是指对自定义控件布局进行定制,使其具备不同的排列方式和样式。 在自定义控件中设置布局可以通过以下步骤实现: 1. 在自定义控件布局文件中定义布局容器,例如使用LinearLayout、RelativeLayout等。可以根据需要进行嵌套,构建复杂的布局结构。 2. 在自定义控件的构造方法中引入布局文件,通过LayoutInflater的inflate()方法将布局文件解析为View对象。 3. 通过findViewById()方法获取布局文件中定义的各个组件的引用,以便进行后续的操作。 4. 可以在自定义控件中添加自定义属性,通过在attrs.xml文件中定义属性,在布局文件中引用并在控件的构造方法中获取属性值。例如可以定义属性设置文本大小、颜色等。 5. 在代码中对布局进行动态操作,例如设置组件的大小、位置、背景色等。可以通过LayoutParams来设置布局参数,例如设置宽高、边距等。 6. 在自定义控件的代码中实现各种件的监听和响应,例如点击件、长按件等。可以通过setXXXListener()方法来设置件监听器,并在监听器中编写对应的逻辑代码。 通过以上步骤,我们可以灵活地设置自定义控件布局,并且根据需要进行各种样式的定制。这样可以大大提高了控件的灵活性和可重用性,并且使得界面布局更加符合需求。这对于开发中复杂的UI界面和特定的功能需求都是非常有帮助的。 ### 回答3: 自定义控件是Android开发中常用的一种技术,通过自定义控件,我们可以实现更加丰富多样的布局效果。设置布局自定义控件中的一个重要部分,可以通过设置不同的布局来达到不同的展示效果。 首先,要实现自定义控件布局设置,我们需要在自定义控件的类中添加相应的方法和属性。常用的方法有onMeasure()和onLayout()。onMeasure()方法用于测量布局的宽高,通过setMeasuredDimension()方法设置测量结果;onLayout()方法用于定义布局中各个子控件的位置和大小。 在布局的设置过程中,我们可以使用常见的布局管理器,如LinearLayout、RelativeLayout等,对子控件进行排列和布局。在使用这些布局管理器时,可以通过LayoutParams属性来设置子控件的位置和大小,如设置权重、边距等。 在自定义控件中,我们还可以使用自定义的布局管理器,通过继承ViewGroup类来实现。在自定义布局管理器中,我们可以根据实际需求来定义子控件的排列规则,例如可以实现一个流式布局、网格布局等。 除了传统的布局管理器,我们还可以通过自定义xml布局文件,使用LayoutInflater来加载布局。在加载布局时,可以通过findViewById()方法来获取布局中的子控件,然后进行相应的设置和操作。 总之,自定义控件布局设置是一个灵活多样的过程,通过灵活运用布局管理器和自定义xml布局文件,结合自定义的测量和排列方法,我们可以实现各种各样独特的布局效果,提升用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值