下面是控件和布局的继承关系:

从上面我们看到:

  1、所有控件都是直接或间接继承View,所有的布局都是直接或间接继承ViewGroup

  2、View是Android中最基本的UI组件,各种组件其实就是在View的基础上又添加了各自特有的功能。

  3、ViewGroup是一种特殊的View,它可以包含很多子View和子ViewGroup,是一个用于放置控件和布局的容器。

 一、引入布局

       问题引入:在一个项目中存在一个标题栏,该项目中的许多活动都使用了该标题栏,如果在每个活动中都写一遍标题栏的代码,会导致代码的大量重复。

  问题解决:把标题栏布局代码单独写出来,然后在每个活动的布局中引入标题栏布局即可

第一步:创建一个新项目:UICustomViews,创建标题栏布局:title.xml

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="wrap_content"
 5     android:background="@color/colorPrimary">
 6 
 7     <Button
 8         android:id="@+id/title_back"
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:layout_gravity="center"
12         android:layout_margin="5dp"
13         android:text="Back" />
14     <TextView
15         android:id="@+id/title_text"
16         android:layout_width="0dp"
17         android:layout_height="wrap_content"
18         android:layout_weight="1"
19         android:gravity="center"
20         android:layout_gravity="center"
21         android:text="Text View"
22         android:textSize="24sp"/>
23     <Button
24         android:id="@+id/title_edit"
25         android:layout_width="wrap_content"
26         android:layout_height="wrap_content"
27         android:layout_gravity="center"
28         android:layout_margin="5dp"
29         android:text="Edit" />
30 </LinearLayout>

第二步:在activity_main.xml中引入title布局:

第三步:在MainActivity活动中隐藏系统自带的标题栏

第五步:运行结果

 

代码分析:

  android:background属性:为布局或控件指定一个背景

  android:margin属性:指定控件在上下左右方向上偏移的距离,也可以使用android:layout_marginLeft或android:layout_marginTop等属性来单独指定控件在某个方向上偏移的距离

  <include layout="@layout/title"/>:引入title布局

  getSupportActionBar()方法:获取ActionBar的实例,然后调用:hide()方法将标题栏隐藏起来。

 二、创建自定义控件

  创建自定义控件过后,与普通控件的用法一样

第一步:创建TitleLayout控件类,继承LinearLayout

第二步:在布局文件中添加自定义控件

 

第三步:在TitleLayout控件中添加按钮点击事件:点击Back,退出程序,点击Edit,弹出一个提示信息

第四步:运行程序,点击Back,退出程序;点击Edit,弹出提示信息

代码分析:

  1、TitleLayout控件继承LinearLayout布局后,重写LinearLayout中带有两个参数的构造函数TitleLayout,在布局中引入TitleLayout控件时就会调用该构造函数。

  2、借助LayoutInflater来实现对标题栏布局的动态加载:

    通过LayoutInflater的:from()方法来构建一个LayoutInflater的对象。然后通过调用:inflater()方法就可以动态加载一个布局文件,在inflater()方法中传入两个参数,一个是要加载的布局文件的id,这里我们要加载的是title这个布局文件,所以这里传入的就是:R.layout.title;另外一个参数是给加载好的布局添加一个父布局,这里我们想要指定为TitleLayout,于是就传入this.

  3、添加自定义控件时,需要指定控件的完整类名,包名在这里是不可以省略的:com.workspace.hh.uicustomviews.TitleLayout