自定义控件----自定义属性

时间:2022-02-06 16:43:46

自定义属性

在自己定制一个自定义控件的时候,除了绘制控件之外不免要给控件添加自定义属性方便使用者设置及调用。给一个View添加自定义属性非常简单,只需要在res的values目录下创建attrs.xml文件即可,该文件下的内容可以这样设置

<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="title" format="string" />
<declare-styleable name="TopBar">
<attr name="title" />
<attr name="titleTextSize" format="dimension" />
<attr name="titlesTextColor" format="color"/>
<attr name="leftTextColor" format="color" />
<attr name="leftBackground" format="color|reference" />
<attr name="leftText" format="string" />
<attr name="rightTextColor" format="color" />
<attr name="rightBackground" format="color|reference" />
<attr name="rightText" format="string" />
</declare-styleable>
</resources>

如上代码所示,<declare-styleable>标签声明使用自定义属性,通过name属性来确定引用的名称。<attr>标签来声明具体的自定义属性,<format>来声明属性的类型,例如文字的颜色使用format="color",要注意的一点是—-有的属性可以有两种类型,例如某个background可以设置为颜色,也可以设置一张图片。当有两种类型的时候可以用“|”将两种属性隔开eg:”fomat=”color|reference”颜色和引用类型。
定义好了属性之后,那么久可以创建一个继承于ViewGroup的自定义控件—–TopBar了。那么如何将TopBar与该定义的属性绑定在一起呢?我们要做两步操作:1.获取自定义属性集并获取所有的自定义属性 2.组合控件,为创建的组建元素赋值,这些值就是自定义属性。
例如我们要实现一个这样的自定义控件,一般的APP都有一个titleBar在抬头做导航,左右两边分别一个按钮,中间有该页面的title。入下图所示:
自定义控件----自定义属性
左右两边都是Button,中间是一个title标题。好了下面我们就开始代码来完成上面说的两个步骤吧!
第一步拿到自定义属性值

    private void init(Context context, AttributeSet attrs) {
//系统提供了TypedArray这样的数据结构来获取自定义属性集
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar);
//通过TypedArray对象来获取定义的属性值代码如下所示
mLeftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0);
mLeftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground);
mLeftText = ta.getString(R.styleable.TopBar_leftText);

mRightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, 0);
mRightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground);
mRightText = ta.getString(R.styleable.TopBar_rightText);

mTitleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 10);
mTitleTextColor = ta.getColor(R.styleable.TopBar_titlesTextColor, 0);
mTitle = ta.getString(R.styleable.TopBar_title);

ta.recycle();//这里需要注意,当获取完所有属性时,需要调用TypeArray上这个方法来完成资源回收

//获取所有的自定义属性值之后,就可以组合控件了。
combineComponent(context);
}

看到这一行代码

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar);

系统提供了一个这样的数据结构TypedArray来接收属性值。然后通过TypedArray的对象来获取各个自定义属性值。

第二步给各个组件元素附上属性值

//将控件组合进TopBar中
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void combineComponent(Context context) {
mLeftButton = new Button(context);
mRightButton = new Button(context);
mTitleView = new TextView(context);
//为创建的组件元素赋值 这些值即是来源于之前获取的自定义属性
mLeftButton.setText(mLeftText);
mLeftButton.setBackground(mLeftBackground);
mLeftButton.setTextColor(mLeftTextColor);

mRightButton.setText(mRightText);
mRightButton.setBackground(mRightBackground);
mRightButton.setTextColor(mRightTextColor);

mTitleView.setText(mTitle);
mTitleView.setTextSize(mTitleTextSize);
mTitleView.setTextColor(mTitleTextColor);
mTitleView.setGravity(Gravity.CENTER);

//为组件设置相应的布局元素
mLeftParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
addView(mLeftButton, mLeftParams);//将组件加入TopBar

mRightParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
addView(mRightButton, mRightParams);

mTitleParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
addView(mTitleView, mTitleParams);
}

通过以上的所有操作就可以在layout布局文件中引用这个控件了。
在AndroidStudio中引用第三方控件需要引入命名空间:

xmlns:app="http://schemas.android.com/apk/res-auto"

IDE会提示导入,接下来就可以使用这个控件了

<com.byzk.nbview.TopBar
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="10dp"
android:background="@color/colorAccent"
app:leftBackground="@android:color/holo_blue_light"
app:leftText="取消"
app:leftTextColor="@android:color/black"
app:rightBackground="@android:color/holo_blue_bright"
app:rightText="帅也是错啊"
app:rightTextColor="@android:color/black"
app:title="lihongxiangleo"
app:titleTextSize="4sp"
app:titlesTextColor="@android:color/white" />

当我们完成了上面的操作后,整个TopBar的自定义属性IDE都会给我们提示出来。完成了以上操作之后我们还可以给自己的控件添加接口暴露给使用者调用,方法由使用者来实现,例如点击事件等。
创建两个接口

/**
* Author: lihongxiang
* Time: 下午 3:59
* Email:lihongxiangleo@163.com
*/


public interface TopBarClickListener {

void leftClick();

void rightCick();
}

提供一个方法来给调用者注册接口,实现接口回调。

//在模版中为左右按钮设置点击事件,但不去实现具体逻辑,而是调用接口中相应的点击方法
private void initListener() {
mRightButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.rightCick();

}
});

mLeftButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mListener.leftClick();
}
});
}


private TopBarClickListener mListener;

//暴露一个方法给调用者来注册接口回调
//通过接口回调来获得回调者对接口方法的实现
public void setOnTopbarClickListener(TopBarClickListener mListener) {
this.mListener = mListener;
}

Activity中的代码

private void initView() {
tb = (TopBar) findViewById(R.id.tb);

tb.setOnTopbarClickListener(new TopBarClickListener() {
@Override
public void leftClick() {
Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show();
}

@Override
public void rightCick() {
Toast.makeText(MainActivity.this, "right", Toast.LENGTH_SHORT).show();
}
});
}

调用的代码很简单,方法大家可以自定义,实现效果如下:
自定义控件----自定义属性
以上就是自定义属性的使用方法和实例,大家可以通过自定义属性来给自定义控件定制自己想要的一些属性!


总结一下使用自定义属性的操作:

1.在res目录下的valus里创建attrs.xml文件
2.在attrs.xml中通过<declare-styleble> <attr>等标签声明自定义属性
3.使用TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar);方法 获取属性集合并通过ta获取所有的属性值
4.创建组件元素->设置属性值->添加组件元素–addView()
5.在xml中应用UI模板