这种布局在开发中特别常见…
所以为了省事,直接写一个自定义一劳永逸解决问题…
1.构建布局
按照布局的规律先创建一个布局…
很简单的布局,根据实际需求来即可…
2.创建自定义类
创建类CommonTextItem继承LinearLayout.
看一下LinearLayout的3个构造函数,递归调用,最后调用的都是3参数的构造函数.
我们就把逻辑写在2参数里面好了
public CommonTextItem(Context context) {
super(context);
}
public CommonTextItem(Context context, AttributeSet attrs) {
super(context, attrs);
//TODO....这里写逻辑
}
public CommonTextItem(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
TIPS:不要盲目的进行递归调用….
ScrollView就是血的教训…感兴趣的可以看看ScrollView的2参数的构造函数.
3.创建declare-styleable
res/values/attrs.xml
没有就创建一个,有就直接
<declare-styleable name="CommonTextItem">
<attr name="ctiLeftImg" format="reference"/>
<attr name="ctiRightImg" format="reference"/>
<attr name="ctiLeftText" format="reference|string"/>
<attr name="ctiRightText" format="reference|string"/>
<attr name="ctiLeftTextMargin" format="dimension"/>
<attr name="ctiRightTextColor" format="color"/>
</declare-styleable>
左边为自定义的属性名称,右边为该属性的类型
reference: 指定Theme中资源ID。
dimension:尺寸值
float:浮点型
boolean:布尔值
integer:整型
string:字符串
fraction:百分数
flag:位或运算
Color:颜色
enum:枚举
根据个人不同的需求,可以自行修改布局,添加attr属性及对应的类型
4.获取控件
基础布局创建好了,styleable也弄好了,可以开始写逻辑了.
首先肯定是添加布局,根据返回的view,findViewById找到各个组件
View view = LayoutInflater.from(context).inflate(R.layout.widget_common_text, this, true);
iv_left = (ImageView) view.findViewById(R.id.iv_left);
iv_right = (ImageView) view.findViewById(R.id.iv_right);
tv_left = (TextView) view.findViewById(R.id.tv_left);
tv_right = (TextView) view.findViewById(R.id.tv_right);
最关键的时候到了
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CommonTextItem);
拿到这个TypedArray…自定义控件已经完成一半了.
5.写逻辑
使用ta.getResourceId(styleableIndex, defValue);
第一个参数传入在attrs里面创建好的属性名称
第二个参数为该属性的默认值…
比如:
int leftImageR = ta.getResourceId(R.styleable.CommonTextItem_ctiLeftImg, -1);
当该自定义组件在xml配置是 ctiLeftImg没有添加,则默认传入-1.
传入-1干嘛,当然是拿来判断,然后隐藏了
就像这样:
int leftImageR = ta.getResourceId(R.styleable.CommonTextItem_ctiLeftImg, -1);
if (leftImageR == -1) {
iv_left.setVisibility(View.GONE);
} else {
iv_left.setImageResource(leftImageR);
}
其他的属性和这个写法一致,传入默认值是隐藏还是设置指定颜色还是默认间距这些 根据个人不同的需求自定义即可.
举个栗子:
1. attrs里面添加字体与图片的间距,属性当然就是dimension了.设置的时候,默认值可以写0啊.只有不为0的设置组件间距即可
2. attrs里面添加字体的颜色,属性当然就是color,设置的时候,默认值可以写 黑色,然后添加判断,不为黑色的时候就是指定颜色即可.
6.拓展设置
只能单独在xml里面设置多不方便啊,可以写几个set方法啊,想怎么设置就可以怎么设置
public void hideRightImg() {
iv_right.setVisibility(View.GONE);
}
public void setLeftText(CharSequence text) {
tv_left.setVisibility(View.VISIBLE);
tv_left.setText(text);
}
public void setLeftTextColor(int resourceId) {
tv_left.setTextColor(resourceId);
}
7.使用
以上弄完就能正常使用了…xml里面直接引用即可.
在xml该自定义控件内添加属性时,记得在最外层的父布局添加
xmlns:app="http://schemas.android.com/apk/res-auto"
即可.然后就可以了.
<com.your_package.widget.CommonTextItem
android:id="@+id/cti_device_name"
android:layout_width="match_parent"
android:layout_height="44dp"
app:ctiLeftImg="@drawable/icon_xxx"
app:ctiLeftText="@string/mine_xxx_left_text"
app:ctiRightImg="@drawable/icon_common_row_enter"/>
以上,OVER…