对于一些项目中通用的视图,可以采取组合控件的方式定义成一个单独的控件,简化开发。常见的如头部视图,通用录音视图等。今天,记录一下此种方式。
第一步,设计新控件的独有属性。在values文件夹中创建attrs.xml文件,添加属性。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="HeaderView">
<attr name="headerTitle" format="string"/>
<attr name="titleSize" format="dimension"/>
<attr name="titleColor" format="color"/>
<attr name="leftImage" format="reference" />
<attr name="rightText" format="string" />
<attr name="rightTextSize" format="dimension"/>
<attr name="rightTextColor" format="color" />
</declare-styleable>
</resources>
第二部,创建HeaderView控件类,继承自组合视图的子类,在HeaderView的构造函数中初始化各个子控件。
public class HeaderView extends RelativeLayout {
private String title;
private int titleColor;
private float titleSize;
private String rightText;
private int rightTextColor;
private float rightTextSize;
private Bitmap leftBitmap;
private TextView titleTV;
private TextView rightTV;
private ImageView leftIV;
private LayoutParams titleParams;
private LayoutParams rightTitleParams;
private LayoutParams leftTitleParams;
public HeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray at = context.obtainStyledAttributes(attrs, R.styleable.HeaderView);
title = at.getString(R.styleable.HeaderView_headerTitle);
titleColor = at.getColor(R.styleable.HeaderView_titleColor, 0);
titleSize = at.getDimension(R.styleable.HeaderView_titleSize, 0);
rightText = at.getString(R.styleable.HeaderView_rightText);
rightTextColor = at.getColor(R.styleable.HeaderView_rightTextColor, 0);
rightTextSize = at.getDimension(R.styleable.HeaderView_rightTextSize, 0);
leftBitmap = BitmapFactory.decodeResource(getResources(), at.getResourceId(R.styleable.HeaderView_leftImage, 0));
at.recycle();
titleTV = new TextView(context);
titleTV.setText(title);
titleTV.setTextColor(titleColor);
titleTV.setTextSize(titleSize);
titleTV.setGravity(Gravity.CENTER);
titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
titleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
addView(titleTV, titleParams);
rightTitleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
rightTitleParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
rightTV = new TextView(context);
rightTV.setText(rightText);
rightTV.setTextColor(rightTextColor);
rightTV.setTextSize(rightTextSize);
rightTV.setGravity(Gravity.CENTER);
addView(rightTV, rightTitleParams);
leftIV = new ImageView(context);
leftIV.setImageBitmap(leftBitmap);
leftTitleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
leftTitleParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
addView(leftIV, leftTitleParams);
}
public void setOnRightListener(OnClickListener listener){
rightTV.setOnClickListener(listener);
}
}
注意,TypedArray使用之后一定要记着回收,at.recycle();
第三步,在布局文件中使用,记得配置命名空间。
<!--添加命名空间pretty-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:pretty="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.superman.prettygirl.widget.HeaderView
android:id="@+id/hv_main_header"
android:layout_width="match_parent"
android:layout_height="48dp"
pretty:headerTitle="PrettyGirl"
pretty:titleSize="6sp"
pretty:titleColor="#fff"
pretty:rightText="Cancel"
pretty:rightTextColor="#fff"
pretty:rightTextSize="4sp"
android:background="#ff7428"
/>
</LinearLayout>
第四步,在Activity中获取此控件,设置点击事件。
HeaderView headerView = (HeaderView) findViewById(R.id.hv_main_header);
headerView.setOnRightListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show();
}
});