相關(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();
}
});
}
}
運行程序查看效果: