在Android中,复合控件是非常常见的,下面以创建一个标题栏为例,讲解创建自定义复合控件的过程。
以下图为例:我们要创建一个标题栏,这个标题栏是由左边的Button、右边的Button以及中间的TextView复合而成的,而我们希望能够直接在这个自定义标题栏设置里面的Button和TextView的属性信息。
具体实现过程如下:
1、首先在res资源目录的values目录新建一个attrs.xml的属性定义文件,并在该文件中定义相应的属性。代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TopBar">
<attr name="titleText" format="string" />
<attr name="titleTextSize" format="dimension" />
<attr name="titleTextColor" format="color" />
<attr name="leftText" format="string" />
<attr name="leftTextSize" format="dimension" />
<attr name="leftTextColor" format="color" />
<attr name="leftBackground" format="reference|color" />
<attr name="rightText" format="string" />
<attr name="rightTextSize" format="dimension" />
<attr name="rightTextColor" format="color" />
<attr name="rightBackground" format="reference|color" />
</declare-styleable>
</resources>
这里定义了标题文字的内容、大小、颜色,左边按钮的文字内容、大小、颜色以及按钮的背景,右边按钮的文字内容、大小、颜色以及按钮的背景,值得一提的是,这里的背景属性既可以是颜色属性,也可以是引用属性,如引用一张图片,故这里使用了“|”来分隔不同的属性——“reference|color”。
2、自定义的ComplexView代码如下:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ComplexView extends LinearLayout {
private String titleText;//标题文字
private float titleTextSize;//标题文字大小
private int titleTextColor;//标题文字颜色
private String leftText;//左边按钮文字
private float leftTextSize;//左边按钮文字大小
private int leftTextColor;//左边按钮文字颜色
private Drawable leftBackground;//左边按钮背景
private String rightText;//右边按钮文字
private float rightTextSize;//右边按钮文字大小
private int rightTextColor;//右边按钮文字颜色
private Drawable rightBackground;//右边按钮背景
private Button leftBtn;
private TextView titleTv;
private Button rightBtn;
public ComplexView(Context context) {
super(context);
}
public ComplexView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context.obtainStyledAttributes(attrs, R.styleable.TopBar));
View view = LayoutInflater.from(context).inflate(R.layout.complex_view, this);
leftBtn = (Button) view.findViewById(R.id.left_btn);
rightBtn = (Button) view.findViewById(R.id.right_btn);
titleTv = (TextView) view.findViewById(R.id.title_tv);
//设置标题属性
titleTv.setText(titleText);
titleTv.setTextSize(titleTextSize);
titleTv.setTextColor(titleTextColor);
//设置左边按钮属性
leftBtn.setText(leftText);
leftBtn.setTextSize(leftTextSize);
leftBtn.setTextColor(leftTextColor);
leftBtn.setBackgroundDrawable(leftBackground);
//设置右边按钮属性
rightBtn.setText(rightText);
rightBtn.setTextSize(rightTextSize);
rightBtn.setTextColor(rightTextColor);
rightBtn.setBackgroundDrawable(rightBackground);
//左右按钮点击事件
leftBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
onTopBarClickListener.leftClick();
}
});
rightBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
onTopBarClickListener.rightClick();
}
});
}
//获取自定义属性集
private void parseAttributes(TypedArray ta) {
titleText = ta.getString(R.styleable.TopBar_titleText);
titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 25);
titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0);
leftText = ta.getString(R.styleable.TopBar_leftText);
leftTextSize = ta.getDimension(R.styleable.TopBar_leftTextSize, 16);
leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0);
leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);
rightText = ta.getString(R.styleable.TopBar_rightText);
rightTextSize = ta.getDimension(R.styleable.TopBar_rightTextSize, 16);
rightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, 0);
rightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);
ta.recycle();
}
//为左右按钮设置点击事件,使用接口回调方法
public interface onTopBarClickListener {
void leftClick();
void rightClick();
}
onTopBarClickListener onTopBarClickListener = null;
public void setOnTopBarClickListener(onTopBarClickListener onTopBarClickListener) {
this.onTopBarClickListener = onTopBarClickListener;
}
}
其中complex_view布局文件如下:
<?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/left_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dp" />
<TextView
android:id="@+id/title_tv"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center" />
<Button
android:id="@+id/right_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dp" />
</LinearLayout>
3、在activity_main中引入ComplexView,为了引用自定义控件的属性,需要在activity_main布局文件中加入下面一句:
xmlns:app="http://schemas.android.com/apk/res-auto"
<?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=".MainActivity">
<com.exam.myapplication.ComplexView
android:id="@+id/top_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#008577"
app:leftBackground="@drawable/btn_shape"
app:leftText="返回"
app:leftTextColor="#ffffff"
app:leftTextSize="8sp"
app:rightBackground="@drawable/btn_shape"
app:rightText="更多"
app:rightTextColor="#ffffff"
app:rightTextSize="8sp"
app:titleText="标题"
app:titleTextColor="#ffffff"
app:titleTextSize="10sp" />
</LinearLayout>
上面的btn_shape其实是按钮的背景,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="3dp"/>
<solid android:color="#00574B"/>
</shape>
4、我在自定义的ComplexView中还为左右按钮增加了点击事件,这里使用了接口回调方法,可以在MainActivity中实现具体的逻辑。代码如下:
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
ComplexView topBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
topBar = (ComplexView) findViewById(R.id.top_bar);
topBar.setOnTopBarClickListener(new ComplexView.onTopBarClickListener() {
@Override
public void leftClick() {
Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_SHORT).show();
}
@Override
public void rightClick() {
Toast.makeText(MainActivity.this, "更多", Toast.LENGTH_SHORT).show();
}
});
}
}
创建自定义复合控件的整个流程到此介绍完毕。