Android View體系(十)自定義組合控件

相關(guān)文章
Android View體系(一)視圖坐標(biāo)系
Android View體系(二)實現(xiàn)View滑動的六種方法
Android View體系(三)屬性動畫
Android View體系(四)從源碼解析Scroller
Android View體系(五)從源碼解析View的事件分發(fā)機制
Android View體系(六)從源碼解析Activity的構(gòu)成
Android View體系(七)從源碼解析View的measure流程
Android View體系(八)從源碼解析View的layout和draw流程
Android View體系(九)自定義View

前言

上一篇我們講到了自定義View,接著我們來講講常用的自定義組合控件,自定義組合控件就是多個控件組合起來成為一個新的控件墙贱,主要用來解決多次重復(fù)的使用同一類型的布局蔬啡。比如我們應(yīng)用的頂部的標(biāo)題欄持痰,還有彈出的固定樣式的dialog蚯姆,這些都是常用的硫麻,所以把他們所需要的控件組合起來重新定義成一個新的控件蝇完。

1.組合控件的xml布局

我們現(xiàn)在就自定義一個頂部的標(biāo)題欄官硝,當(dāng)然實現(xiàn)標(biāo)題欄有很多的方法,我們來看看自定義組合控件如何去實現(xiàn)短蜕。首先我們先定義我們組合控件的布局(view_customtitle.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_titlebar_rootlayout"
    android:layout_width="fill_parent"
    android:layout_height="45dp"
    >

    <ImageView
        android:id="@+id/iv_titlebar_left"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_centerInParent="true"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:src="@drawable/ico_return"
       />
    <TextView
        android:id="@+id/tv_titlebar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:maxEms="11"
        android:singleLine="true"
        android:ellipsize="end"
        android:textStyle="bold"/>
    <ImageView
        android:id="@+id/iv_titlebar_right"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:layout_centerInParent="true"
        android:src="@drawable/title_right"
        android:gravity="center"
        android:padding="15dp"
        />
    </RelativeLayout>

很簡單的布局氢架,左右邊各一個圖標(biāo),中間是標(biāo)題文字朋魔。

2.組合控件的Java代碼

接下來我們寫java代碼岖研,因為我們的組合控件整體布局是RelativeLayout,所以我們的組合控件要繼承RelativeLayout:

public class TitleBar extends RelativeLayout {
    private ImageView iv_titlebar_left;
    private ImageView iv_titlebar_right;
    private TextView tv_titlebar_title;
    private RelativeLayout layout_titlebar_rootlayout;
    private int mColor= Color.BLUE;
    private int mTextColor= Color.WHITE;
    public TitleBar(Context context) {
        super(context);
        initView(context);
    }

    public TitleBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    public void initView(Context context){
        LayoutInflater.from(context).inflate(R.layout.view_customtitle, this, true);
        iv_titlebar_left= (ImageView) findViewById(R.id.iv_titlebar_left);
        iv_titlebar_right= (ImageView) findViewById(R.id.iv_titlebar_right);
        tv_titlebar_title= (TextView) findViewById(R.id.tv_titlebar_title);
        layout_titlebar_rootlayout= (RelativeLayout) findViewById(R.id.layout_titlebar_rootlayout);
        //設(shè)置背景顏色
        layout_titlebar_rootlayout.setBackgroundColor(mColor);
        //設(shè)置標(biāo)題文字顏色
        tv_titlebar_title.setTextColor(mTextColor);
    }
    public void setTitle(String titlename){
        if(!TextUtils.isEmpty(titlename)) {
            tv_titlebar_title.setText(titlename);
        }
    }

    public void setLeftListener(OnClickListener onClickListener){
        iv_titlebar_left.setOnClickListener(onClickListener);
    }
    public void setRightListener(OnClickListener onClickListener){
        iv_titlebar_right.setOnClickListener(onClickListener);
    }
}

重寫了三個構(gòu)造方法并在構(gòu)造方法中加載布局文件警检,對外提供了三個方法孙援,分別用來設(shè)置標(biāo)題的名字,和左右按鈕的點擊事件扇雕。

3.自定義屬性

在上一篇文章Android View體系(九)自定義View我們講到的自定義屬性拓售,同樣的我們在values目錄下創(chuàng)建 attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TitleBar">
        <attr name="title_text_color" format="color" />
        <attr name="title_bg" format="color" />
        <attr name="title_text" format="string" />
    </declare-styleable>
</resources>

我們定義了三個屬性,分別用來設(shè)置頂部標(biāo)題欄的背景顏色镶奉、標(biāo)題文字顏色和標(biāo)題文字础淤。為了引入自定義屬性我們需要在TitleBar的構(gòu)造函數(shù)中解析自定義屬性的值:

 public TitleBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray mTypedArray=context.obtainStyledAttributes(attrs,R.styleable.TitleBar);
        mColor=mTypedArray.getColor(R.styleable.TitleBar_title_bg,Color.BLUE);
        mTextColor=mTypedArray.getColor(R.styleable.TitleBar_title_text_color, Color.WHITE);
        titlename=mTypedArray.getString(R.styleable.TitleBar_title_text);
        //獲取資源后要及時回收
        mTypedArray.recycle();
        initView(context);
    }

貼上修改后TitleBar的完整的代碼:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class TitleBar extends RelativeLayout {
    private ImageView iv_titlebar_left;
    private ImageView iv_titlebar_right;
    private TextView tv_titlebar_title;
    private RelativeLayout layout_titlebar_rootlayout;
    private int mColor = Color.BLUE;
    private int mTextColor = Color.WHITE;
    private String titlename;

    public TitleBar(Context context) {
        super(context);
        initView(context);
    }

    public TitleBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        initTypedArray(context, attrs);
        initView(context);
    }
    

    public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initTypedArray(context, attrs);
        initView(context);
    }

    private void initTypedArray(Context context, AttributeSet attrs) {
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleBar);
        mColor = mTypedArray.getColor(R.styleable.TitleBar_title_bg, Color.BLUE);
        mTextColor = mTypedArray.getColor(R.styleable.TitleBar_title_text_color, Color.WHITE);
        titlename = mTypedArray.getString(R.styleable.TitleBar_title_text);
        //獲取資源后要及時回收
        mTypedArray.recycle();
    }

    private void initView(Context context) {
        LayoutInflater.from(context).inflate(R.layout.view_customtitle, this, true);
        iv_titlebar_left = (ImageView) findViewById(R.id.iv_titlebar_left);
        iv_titlebar_right = (ImageView) findViewById(R.id.iv_titlebar_right);
        tv_titlebar_title = (TextView) findViewById(R.id.tv_titlebar_title);
        layout_titlebar_rootlayout = (RelativeLayout) findViewById(R.id.layout_titlebar_rootlayout);
        //設(shè)置背景顏色
        layout_titlebar_rootlayout.setBackgroundColor(mColor);
        //設(shè)置標(biāo)題文字顏色
        tv_titlebar_title.setTextColor(mTextColor);
        setTitle(titlename);
    }

    public void setTitle(String titlename) {
        if (!TextUtils.isEmpty(titlename)) {
            tv_titlebar_title.setText(titlename);
        }
    }

    public void setLeftListener(OnClickListener onClickListener) {
        iv_titlebar_left.setOnClickListener(onClickListener);
    }

    public void setRightListener(OnClickListener onClickListener) {
        iv_titlebar_right.setOnClickListener(onClickListener);
    }
}

4.xml中引用組合控件

接下來在我們引用組合控件的布局,使用自定義屬性需要添加schemas: xmlns:app=”http://schemas.android.com/apk/res-auto”哨苛,其中app是 我們自定義的名字鸽凶,當(dāng)然我們也可以取其他的名字:

<?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="match_parent"
android:orientation="vertical">

<com.example.liuwangshu.mooncustomgroup.TitleBar
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/title"
    android:layout_width="match_parent"
    android:layout_height="45dp"
    app:title_text="自定義組合控件"
    app:title_bg="@android:color/holo_orange_dark"
    app:title_text_color="@android:color/holo_blue_dark">
</com.example.liuwangshu.mooncustomgroup.TitleBar>
</LinearLayout>

4.調(diào)用組合控件

在主界面調(diào)用我們自定義的TitleBar,并設(shè)置了左右兩遍按鈕的點擊事件:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {
    private TitleBar mTitleBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTitleBar= (TitleBar) this.findViewById(R.id.title);
//      mTitleBar.setTitle("自定義組合控件");

        mTitleBar.setLeftListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "點擊左鍵", Toast.LENGTH_SHORT).show();
            }
        });

        mTitleBar.setRightListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "點擊右鍵", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

運行程序查看效果:


這里寫圖片描述

github源碼下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末建峭,一起剝皮案震驚了整個濱河市玻侥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亿蒸,老刑警劉巖凑兰,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異祝懂,居然都是意外死亡票摇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門砚蓬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來矢门,“玉大人,你說我怎么就攤上這事∷钐蓿” “怎么了隔躲?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長物延。 經(jīng)常有香客問我宣旱,道長,這世上最難降的妖魔是什么叛薯? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任浑吟,我火速辦了婚禮,結(jié)果婚禮上耗溜,老公的妹妹穿的比我還像新娘组力。我一直安慰自己,他們只是感情好抖拴,可當(dāng)我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布燎字。 她就那樣靜靜地躺著,像睡著了一般阿宅。 火紅的嫁衣襯著肌膚如雪候衍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天洒放,我揣著相機與錄音蛉鹿,去河邊找鬼。 笑死拉馋,一個胖子當(dāng)著我的面吹牛榨为,可吹牛的內(nèi)容都是我干的惨好。 我是一名探鬼主播煌茴,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼日川!你這毒婦竟也來了蔓腐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤龄句,失蹤者是張志新(化名)和其女友劉穎回论,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體分歇,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡傀蓉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年宙地,在試婚紗的時候發(fā)現(xiàn)自己被綠了蹬叭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片龙屉。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡象迎,死狀恐怖环壤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情榨惰,我是刑警寧澤噪舀,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站壕探,受9級特大地震影響冈钦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜李请,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一瞧筛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧导盅,春花似錦驾窟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘁字,卻和暖如春恩急,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纪蜒。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工衷恭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纯续。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓随珠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親猬错。 傳聞我的和親對象是個殘疾皇子窗看,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容