方式:继承一个合适的ViewGroup,再添加指定功能的控件,需要拓展一些可以配置的属性,以达到更好的重用功能。
以一个自定义标题栏为例。
具体功能:标题栏分为三个部分,左按钮、右按钮、标题,按钮可以设置文字、文字颜色、背景,并且可以隐藏;标题可以设置文字、文字颜色、文字大小、背景。
步骤:
1.定义标题栏的属性,如标题颜色、大小等等,需要在res/values目录下创建一个attrs.xml文件,并通过如下代码定义相应的属性。
<resources>
<declare-styleable name="topBar">
<attr name="titleText" format="string"/>
<attr name="titleTextSize" format="dimension"/>
<attr name="titleTextColor" format="color"/>
<attr name="titleBackground" format="color"/>
<attr name="leftText" format="string"/>
<attr name="leftTextColor" format="color"/>
<attr name="leftBackground" format="reference|color"/>
<attr name="rightText" format="string"/>
<attr name="rightTextColor" format="color"/>
<attr name="rightBackground" format="reference|color"/>
</declare-styleable>
</resources>
2.创建标题栏类TopBar,并继承一个ViewGroup,这里选择RelativeLayout。我们需要在其构造方法中获取自定义属性集,即attrs.xml里面定义的属性,这里用到了TypedArray,通过它的getString()、getColor()等方法获取属性值。
public class TopBar extends RelativeLayout{
private String mLeftText;
private int mLeftTextColor;
private Drawable mLeftBackground;
private String mRightText;
private int mRightTextColor;
private Drawable mRightBackground;
private String mTitleText;
private int mTitleTextColor;
private float mTitleTextSize;
private Drawable mTitleBackground;
private Button mLeftButton;
private Button mRightButton;
private TextView mTitleView;
private LayoutParams mLeftParams;
private LayoutParams mRightParams;
private LayoutParams mTitleParams;
private TopBarClickListener mListener;
public TopBar(Context context, AttributeSet attrs) {
super(context, attrs);
//存储自定义的属性集
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.topBar);
//取出TypedArray中的值
mLeftText = ta.getString(R.styleable.topBar_leftText);
mLeftTextColor = ta.getColor(R.styleable.topBar_leftTextColor, 0);
mLeftBackground = ta.getDrawable(R.styleable.topBar_leftBackground);
mRightText = ta.getString(R.styleable.topBar_rightText);
mRightTextColor = ta.getColor(R.styleable.topBar_rightTextColor, 0);
mRightBackground = ta.getDrawable(R.styleable.topBar_rightBackground);
mTitleText = ta.getString(R.styleable.topBar_titleText);
mTitleTextColor = ta.getColor(R.styleable.topBar_titleTextColor, 0);
mTitleTextSize = ta.getDimension(R.styleable.topBar_titleTextSize, 10);
mTitleBackground = ta.getDrawable(R.styleable.topBar_titleBackground);
//回收资源
ta.recycle();
//为控件的属性赋值
init(context);
}
private void init(Context context){
mLeftButton = new Button(context);
mRightButton = new Button(context);
mTitleView = new TextView(context);
mLeftButton.setText(mLeftText);
mLeftButton.setTextColor(mLeftTextColor);
mLeftButton.setBackground(mLeftBackground);
mRightButton.setText(mRightText);
mRightButton.setTextColor(mRightTextColor);
mRightButton.setBackground(mRightBackground);
mTitleView.setText(mTitleText);
mTitleView.setTextColor(mTitleTextColor);
mTitleView.setTextSize(mTitleTextSize);
mTitleView.setBackground(mTitleBackground);
mTitleView.setGravity(Gravity.CENTER);
mLeftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
addView(mLeftButton, mLeftParams);
mRightParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
addView(mRightButton, mRightParams);
mTitleParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
addView(mTitleView, mTitleParams);
mLeftButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.leftClick();
}
});
mRightButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.rightClick();
}
});
}
/**
* 注册接口回调
* @param listener
*/
public void setOnTopBarClickListener(TopBarClickListener listener){
mListener = listener;
}
/**
* 左右按钮点击事件的接口,发生点击事件时回调方法
*/
public interface TopBarClickListener{
void leftClick();
void rightClick();
}
/**
* 控制按钮是否显示
* @param id 0:左,1:右
* @param flag true:显示 false:隐藏
*/
public void setButtonDisplay(int id, boolean flag){
if (flag){
if (id == 0){
mLeftButton.setVisibility(View.VISIBLE);
}else{
mRightButton.setVisibility(View.VISIBLE);
}
}else{
if (id == 0){
mLeftButton.setVisibility(View.GONE);
}else{
mRightButton.setVisibility(View.GONE);
}
}
}
}
3.引用自定义标题栏:需要指定第三方也就是我们自定义的命名空间,我定义的是 xmlns:topBar="http://schemas.android.com/apk/res-auto" ,当然,这里的topBar你可以替换成任意你想定义的名字,比如one、two、three都应该没什么问题。
<priv.ky2.viewdemo.widget.TopBar
xmlns:topBar="http://schemas.android.com/apk/res-auto"
android:id="@+id/topBar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/light_black"
topBar:leftText="Left"
topBar:leftTextColor="@color/white"
topBar:rightText="Right"
topBar:rightTextColor="@color/white"
topBar:titleText="Title"
topBar:titleTextSize="10sp"
topBar:titleTextColor="@color/white"/>
注:左右按钮点击接口回调
mTopBar = (TopBar) findViewById(R.id.topBar);
mTopBar.setOnTopBarClickListener(new TopBar.TopBarClickListener() {
@Override
public void leftClick() {
}
@Override
public void rightClick() {
}
});
效果
网友评论