Android的onLayout、layout方法讲解

http://www.2cto.com/kf/201404/291740.html

onLayout方法是ViewGroup中子View的布局方法,用于放置子View的位置。放置子View很简单,只需在重写onLayout方法, 然后获取子View的实例,调用子View的layout方法实现布局。在实际开发中,一般要配合onMeasure测量方法一起使用。

onLayout方法:

?


1

2

3

@Override

protected abstract void onLayout(boolean changed,

            int l, int t, int r, int b);

该方法在ViewGroup中定义是抽象函数,继承该类必须实现onLayout方法,而ViewGroup的onMeasure并非必须重写的。
View的放置都是根据一个矩形空间放置的,onLayout传下来的l,t,r,b分别是放置父控件的矩形可用空间(除去margin和padding
的空间)的左上角的left、top以及右下角right、bottom值。

layout方法:

?


1

public void layout(int l, int t, int r, int b);

该方法是View的放置方法,在View类实现。调用该方法需要传入放置View的矩形空间左上角left、top值和右下角right、bottom
值。这四个值是相对于父控件而言的。例如传入的是(10, 10, 100, 100),则该View在距离父控件的左上角位置(10,
10)处显示,显示的大小是宽高是90(参数r,b是相对左上角的),这有点像绝对布局。

平常开发所用到RelativeLayout、LinearLayout、FrameLayout...这些都是继承ViewGroup的布局。这些布局的实现都是通过都实现ViewGroup的onLayout方法,只是实现方法不一样而已。

下面是一个自定义ViewGroup的Demo,用onLayout和layout实现子View的水平放置,间隔是20px

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class MyViewGroup extends ViewGroup {

    // 子View的水平间隔

    private final static int padding = 20;

    

    public MyViewGroup(Context context, AttributeSet attrs) {

        super(context, attrs);

        // TODO Auto-generated constructor stub

    }

    @Override

    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        // TODO Auto-generated method stub

        

        // 动态获取子View实例

        for (int i = 0, size = getChildCount(); i < size; i++) {

            View view = getChildAt(i);

            // 放置子View,宽高都是100

            view.layout(l, t, l + 100, t + 100);

            l += 100 + padding;

        }

        

    }

    

}

Activity的XML布局:

?


1

2

3

4

5

6

7

8

9

10

<relativelayout 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:padding="10dp">

    <com.example.layout.myviewgroup android:layout_width="match_parent" android:layout_height="100dp" android:background="#0000ff">

        

        <view android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff0000">

        <view android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00ff00">

        

    </view></view></com.example.layout.myviewgroup>

</relativelayout>

效果如图所示:

上图MyViewGroup是蓝色,两个子View分别为红色和绿色。

在自定义View中,onLayout配合onMeasure方法一起使用,可以实现自定义View的复杂布局。自定义View首先调用
onMeasure进行测量,然后调用onLayout方法,动态获取子View和子View的测量大小,然后进行layout布局。

时间: 2024-08-23 19:21:22

Android的onLayout、layout方法讲解的相关文章

Android Paint之 setXfermode PorterDuffXfermode 讲解

setXfermodePorterDuffXfermode图层混合模式android图像混合模式AvoidXfermode 尊重原创,欢迎转载,转载请注明: FROM  GA_studio   http://blog.csdn.net/tianjian4592 前面关于paint的方法讲解里,讲到 setXfermode 就截止了,原因有两个: 1. 那篇文章已经太长了,我自己都看不下去了: 2. setXfermode 在paint 里占有至关重要的地位: 基于以上两个原因,我们一起来看看这个

【Android进阶】Android面试题目整理与讲解

这一篇文章专门整理一下研究过的Android面试题,内容会随着学习不断的增加,如果答案有错误,希望大家可以指正 1.简述Activity的生命周期 当Activity开始启动的时候,首先调用onCreate(),onStart(),onResume()方法,此时Activity对用户来说,是可见的状态 当Activity从可见状态变为被Dialog遮挡的状态的时候,会调用onPause()方法,此时的Activity对用户可见,但是不能相 应用户的点击事件 当Activity从可见状态变为被其他

android Intent的startActivityForResult()方法

startActivityForResult() 之前学习了利用Intent跳转页面的同时传值,但有的时候需要从跳转到的页面返回所需要的值(如修改了用户信息,需要返回修改的信息),通俗的意思就是A.Activity跳转到B.Activity,在A.Activity中要自动获取到B.Activity返回的数据. 1.介绍几个主要的方法: 1 MainActivity.this.startActivityForResult(intent1, 1); 第一个参数intent1就不介绍了,第二个参数的值

Android自定义相机超详细讲解

Android自定义相机超详细讲解 转载请标明出处: http://blog.csdn.net/vinicolor/article/details/49642861: 由于网上关于Android自定义相机的文章写得不是太详细,Google官方的文档又说得不太容易理解,所以今天我来详细讲解一下Android自定义相机. 这篇文章主要写给一些刚刚接触Android的那些看官方API困难以及不太了解Android机制的同学们,所以熟练开发者可以绕道了. 最近在使用Camera类的时候发现居然被弃用了,

安卓开发解决android.os.NetworkOnMainThreadException异常方法(主线程不能直接调用webservice)

安卓开发解决android.os.NetworkOnMainThreadException异常方法 2013-01-07 14:01:04|  分类: 技术 |  标签:安卓  技术  java  |举报|字号 订阅 在android 2.3上访问网络的方法,在android 4.0上运行时报android.os.NetworkOnMainThreadException异常,主要问题在于4.0中访问网络不能在主线程中进行,有两个方法可以解决.第一种是在主线程中增加如下代码[不推荐]: // 详见

Android基类设计方法详解

1 为什么要设计基类 为什么要给程序设计基类呢?主要是出于2个原因,一是方便代码编写,减少重复代码和冗余逻辑,优化代码:二是优化程序架构,降低耦合度,方便拓展.修改. ok,编写代码是程序员的第一步,那么第二步就是要编写高质量的代码,代码能实现功能是一方面,写的优美则是另一方面,这也是我们所有攻城狮们应该追求的境界. 2 设计基类的基本思路 那么,哪些东西我们需要抽象到基类中呢? 2.1 重复的代码:如果一个逻辑是大多数子类都需要使用的 2.2 臭而长的代码:典型的findviewbyid.To

Android measure和layout的一点理解

首先,推荐文章,http://blog.csdn.net/hqdoremi/article/details/9980481,http://www.docin.com/p-571954086.html 我理解measure的作用有2个:一个就是调用子view的measure函数,生成他们的高度和宽度,以便在自己的layout阶段参考:另一个是为父view提供关于自己的测量的width和height(这个宽度和高度往往和子view的测量高度和宽度有关),以便父view在layout阶段参考. lay

Android获取系统时间方法详解

Android获取系统时间方法的方法有很多种,常用的有Calendar.Date.currentTimeMills等方法. (1)Calendar Calendar获取系统时间首先要用Calendar.getInstance()函数获取一个实例,再为该实例设定时区(中国的时区为GMT+8:00),最后使用Calendar.get()函数获取时间的具体信息,如年,月,日,小时,分,秒,星期几. package com.hzhi.time_example; import java.util.Cale

Android系统以及Activity启动讲解

一.Android系统启动 Android框架架构图:(来自网上,我觉得这张图看起来很清晰) Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用.启动的过程如下图所示:(图片来自网上,后面有地址) Android系统整个过程如下: (一) Init进程的启动 init进程,它是一个由内核启动的用户级进程.内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程.init