第二章(創(chuàng)建自定義控件)

創(chuàng)建自定義控件

看一下控件和布局的繼承結(jié)構(gòu):


image

引入布局

  1. 先新建一個布局title.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/title_back"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:background="@drawable/back"
        android:backgroundTint="@android:color/darker_gray" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Title Text"
        android:textSize="24sp" />

    <Button
        android:id="@+id/title_edit"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:background="@drawable/edit"
        android:backgroundTint="@android:color/darker_gray"
        android:gravity="center" />
</LinearLayout>

左右兩邊一邊一個Button并設(shè)置了背景圖,中間是一個TextView為標(biāo)題欄

  1. 在Activity中將系統(tǒng)自帶的標(biāo)題欄隱藏掉:
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActionBar actionBar=getSupportActionBar();
        if(actionBar!=null){
            actionBar.hide();
        }
    }
}
  1. 在activity_main.xml中將title布局引入進(jìn)去:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.uicustomviews.MainActivity">

    <include layout="@layout/title"/>

</LinearLayout>

這樣就將布局引入進(jìn)去了,使用這種方法不管多少布局需要添加標(biāo)題欄只需一行include語句就行了,這確實(shí)解決了重復(fù)編寫布局代碼的問題,但是如果布局中有一些控件要能夠響應(yīng)事件,我們還是需要在每個活動為這些控件單獨(dú)編寫一次事件注冊的代碼,這樣無疑增加了很多重復(fù)的代碼,所以這種情況最好的方式是用自定義控件來解決

自定義控件

  1. 新建TitleLayout繼承LinearLayout

public class TitleLayout extends LinearLayout{
 //LinearLayout繼承ViewGroup
    public TitleLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater inflater=LayoutInflater.from(context);
        inflater.inflate(R.layout.title,this);
        Button back=(Button)findViewById(R.id.title_back);
        Button edit=(Button)findViewById(R.id.title_edit);
        back.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                ((Activity)getContext()).finish();
            }//getContext返回的是這個view所在的Context
        });
        edit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(),"你點(diǎn)擊了edit",Toast.LENGTH_SHORT).show();
            }
        });
    }


}

這里重寫了LinearLayout的帶兩個構(gòu)造參數(shù)的構(gòu)造函數(shù),在布局中引入TitleLayout控件就會調(diào)用這個構(gòu)造函數(shù),然后在構(gòu)造函數(shù)中需要對標(biāo)題欄進(jìn)行動態(tài)加載,這就要LayoutInflater來實(shí)現(xiàn)了。
首先通過LayoutInflater.from(context)從上下文獲取一個LayoutInflater對象,然后調(diào)用該對象的inflate方法傳入兩個參數(shù),第一個參數(shù)是要加載的布局id,所以傳入R.layout.title,第二個參數(shù)是要給加載好的布局再添加一個父布局,這里就指定TitleLayout。為什么要指定一個父布局?
這里涉及到一個問題:
我們在開發(fā)過程中給控件鎖指定的layout_width和layout_height屬性表示一個控件在容器中的大小,就是說這個控件必須在容器中這些指定的屬性才有意義,否則這些屬性就會失效,這就意味著如果我們直接將title加載進(jìn)來而不給他指定一個父布局,那么inflate的布局的根節(jié)點(diǎn)(LinearLayout)的layout_width和layout_height就會失效,所以想讓title的跟結(jié)點(diǎn)的寬高屬性有效,所以就必須給他指定一個父布局

  1. 添加title布局中Button的點(diǎn)擊事件
  2. 將自定義控件引入進(jìn)去:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.uicustomviews.MainActivity">

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


</LinearLayout>

注意的是在添加自定義控件的時候我們需要指明控件的完整類名,這里包名是不可以省略的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容