在学习之前要强调一下理论知识,但是学校的老师并没有给我讲得很具体
所以我自己去翻书了
在郭霖老师得《第一行代码》中讲得很具体,我也记录下来了


可以看到所有得控件都是直接或者间接继承于View的,而所用的所有布局都是直接或间接继承自ViewGroup的。

View 是Android 中一种最基本的UI 组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件,
因此,我们使用的各种控件其实就是在View的基础之上又添加了各自特有的功能。

ViewGroup 则是一种特殊的View,它可以包含很多的子View 和子ViewGroup,是一个用于放置控件和布局的容器。
如果系统自带的控件不够我们使用的话,我们可以通过继承上面的结构来创建自定义控件

View可以说是android中成功的爹了,Object无奈笑笑

引入布局

很多时候,我们写的软件有可能都会有一个共同的标题栏(其实2019年了,这个应该很少了
但是也必须学习一下怎么引入一个布局
引入布局其实就是,我们先编写好一个很多布局都会有的一个共同点,比如标题栏之类的,然后再通过引入的方式写入
比如编写好一个标题栏:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@drawable/title_bg">

    <Button
        android:id="@+id/title_buttom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/back_bg"
        android:text="Back"
        android:textColor="#fff"
        />
    <TextView
        android:id="@+id/title_text"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="Title Text"
        android:textColor="#FFF"
        android:textSize="24sp"
        />
    <Button
        android:id="@+id/title_edit"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/edit_bg"
        android:text="Edit"
        android:textColor="#FFF"
        />
</LinearLayout>


然后通过iclude导入这个布局

<include layout="@layout_title">

标题就成功导入了,接下来还要隐藏系统原来的标题栏

ActionBar actionbar = getSupportActionBar();
if(actionbar != null){
    actionbar.hide();
}

通过getSupportActionBar来获取ActionBar实例,然后调用ActionBar的hide()隐藏,现在可能不太清楚ActionBar的用法,先知道就这样隐藏就行了

创建自定义控件

在创建了一个每个布局都能用的标题栏之后,如果我需要给标题栏加入一点功能,比如两个按键能的触发等等,那我就必须每页都去注册
那就太麻烦了
所以我们可以通过自定义控件这个方式解决
首先新建一个TitleLayout类,并继承与LinearLayout

public class TitleLayout extends LinearLayout{
    //首先重写LinearLayout两个带参数的构造函数,因为等下需要用到这两个函数
    public TitleLayout(Context context,AttributeSet attrs){
        super(context,attrs);
        //对标题栏布局进行动态加载
        //通过LayoutInflater.from()方法构造出一个LayoutInflater对象
        //然后用inflate()方法动态加载一个布局
        //inflate接两个参数,第一个数加载的布局,第二个是给加载好的布局再添加一个父布局
        LayoutInflater.from(context).inflate(R.layout.title,this);
    }
}

然后给布局添加这个自定义控件,往你想要添加这个title的布局中添加

<com.example.uicustomviews.TitleLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

添加自定义的控件方法和添加普通控件的方法一样,只不过需要我们写出完整的包名,不可省略
这和上面的include是一样的效果,然后再修改TitleLayout的代码,让两个按钮都有作用

public class TitleLayout extends LinearLayout{
    //首先重写LinearLayout两个带参数的构造函数,因为等下需要用到这两个函数
    public TitleLayout(Context context,AttributeSet attrs){
        super(context,attrs);
        //对标题栏布局进行动态加载
        //通过LayoutInflater.from()方法构造出一个LayoutInflater对象
        //然后用inflate()方法动态加载一个布局
        //inflate接两个参数,第一个数加载的布局,第二个是给加载好的布局再添加一个父布局
        LayoutInflater.from(context).inflate(R.layout.title,this);

        //添加按钮功能
        Button titleBack = (Button) findViewById(R.id.title_back);
        Button titleEdit = (Button) findViewById(R.id.title_edit);

        titleBack.setOnclickListener(new OnClickListener(){

            public void onClick(View v){
                ((Activity)getContext().finish());
            }
        });

        titleEdit.setOnclickListener(new OnClickListener(){

            public void onClick(View v){
                Toast.makeText(getContext(),"You clicked Edit button.",Toast.LENGTH_SHORT).show();
            }
        });
    }
}

这样的话,当我们引入TitleLayout的时候,放回和修改的按钮都注册好了,就省很多工作了


一只蠢莫