随着Android的快速发展,对于Android开发者来说也是一个挑战,Android现有控件已经满足不了项目的一些特殊需求,这个时候就需要到了自定义控件,组合控件相当于把自己需要的UI封装到一个控件中(这里做一个TitleView的组合控件)。
自定义属性
在values文件下创建attrs.xml文件(名字随意,能用就好)
<resources>
<declare-styleable name="TitleView">
<!--标题-->
<attr name="title_backgroundColor" format="color" />
<attr name="title_title_text" format="string" />
<attr name="title_title_textColor" format="color" />
<attr name="title_title_textSize" format="dimension" />
<!--返回-->
<attr name="title_back_backgroudImage" format="reference" />
<!--更多-->
<attr name="title_more_VisibilityImage" format="boolean" />
<attr name="title_more_VisibilityText" format="boolean" />
<attr name="title_more_backgroundImage" format="reference" />
<attr name="title_more_backgroundText" format="string" />
<attr name="title_more_backgroundTextSize" format="dimension" />
<attr name="title_more_backgroundTextColor" format="color" />
</declare-styleable>
</resources>
在layout中布局想要Title的UI
这里可以理解成一个Item,需要加载到一个控件中!
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_custom_title"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:gravity="center" />
<LinearLayout
android:id="@+id/btn_custom_back"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<ImageView
android:id="@+id/iv_custom_back"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/default_back" />
</LinearLayout>
<RelativeLayout
android:id="@+id/btn_custom_more"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentRight="true"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<ImageView
android:id="@+id/iv_custom_more"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/default_more" />
<TextView
android:id="@+id/tv_custom_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center" />
</RelativeLayout>
</RelativeLayout>
自定义控件
继承RelativeLayout
public class TitleView extends RelativeLayout {
public TitleView(Context context) {
super(context);
}
public TitleView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public TitleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
}
初始化UI
- 将Item加载到我们自定义的控件中(this是关键)
//加载title到当前view
LayoutInflater.from(context).inflate(R.layout.custom_base_title, this);
- 初始化Item中的控件
//标题
mTextViewTitle = findViewById(R.id.tv_custom_title);
//返回
mLinearLayoutBack = findViewById(R.id.btn_custom_back);
//返回图片
mImageViewBack = findViewById(R.id.iv_custom_back);
//更多
mRelativeLayoutMore = findViewById(R.id.btn_custom_more);
//更多图片
mImageViewMore = findViewById(R.id.iv_custom_more);
//更多文字
mTextViewMore = findViewById(R.id.tv_custom_more);
- 找到设置的自定义属性
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleView);
//Title背景颜色
int titleBackgroundColor = mTypedArray.getColor(R.styleable.TitleView_title_backgroundColor, context.getResources().getColor(R.color.custom_title_backgroudColor));
//Title文字
String titleText = mTypedArray.getString(R.styleable.TitleView_title_title_text);
//Title文字大小
float titleTextSize = mTypedArray.getDimension(R.styleable.TitleView_title_title_textSize, converSp2Px(18));
//Title文字颜色
int titleTextColor = mTypedArray.getColor(R.styleable.TitleView_title_title_textColor, context.getResources().getColor(R.color.colorWhite));
//Back背景图片
int titleBackBackGroundImage = mTypedArray.getResourceId(R.styleable.TitleView_title_back_backgroudImage, R.drawable.default_back);
//更多背景图片
int titleMoreBackGroundImage = mTypedArray.getResourceId(R.styleable.TitleView_title_more_backgroundImage, R.drawable.default_more);
//更多背景文字
String titleMoreBackGroundText = mTypedArray.getString(R.styleable.TitleView_title_more_backgroundText);
//更多背景文字大小
float titleMoreBackGroundTextSize = mTypedArray.getDimension(R.styleable.TitleView_title_more_backgroundTextSize, converSp2Px(14));
//更多背景文字颜色
int titleMoreBackGroundTextColor = mTypedArray.getColor(R.styleable.TitleView_title_more_backgroundTextColor, context.getResources().getColor(R.color.colorWhite));
//是否显示图片
boolean isMoreImage = mTypedArray.getBoolean(R.styleable.TitleView_title_more_VisibilityImage, false);
//是否显示文字
boolean isMoreText = mTypedArray.getBoolean(R.styleable.TitleView_title_more_VisibilityText, false);
- 给Item中的控件设置默认属性
//设置Title
mTextViewTitle.setText(TextUtils.isEmpty(titleText) ? "请设置Title" : titleText);
mTextViewTitle.setTextSize(converPx2Sp(titleTextSize));
mTextViewTitle.setTextColor(titleTextColor);
mTextViewTitle.setBackgroundColor(titleBackgroundColor);
//设置返回
mImageViewBack.setImageResource(titleBackBackGroundImage);
//设置更多
if (isMoreImage || (isMoreText == isMoreImage)) {
//如果设置显示图片、设置都显示、都不设置的时候
mImageViewMore.setVisibility(VISIBLE);
mTextViewMore.setVisibility(GONE);
mImageViewMore.setImageResource(titleMoreBackGroundImage);
}
if (isMoreText && (isMoreText != isMoreImage)) {
//如果设置文字的时候
mImageViewMore.setVisibility(GONE);
mTextViewMore.setVisibility(VISIBLE);
mTextViewMore.setText(TextUtils.isEmpty(titleMoreBackGroundText) ? "请设置更多提示" : titleMoreBackGroundText);
mTextViewMore.setTextSize(converPx2Sp(titleMoreBackGroundTextSize));
mTextViewMore.setTextColor(titleMoreBackGroundTextColor);
}
- 默认属性效果
<com.nightrain.qfamily.nightrain_library.custom.TitleView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
组合控件默认效果图.png
- 设置属性效果
<com.nightrain.qfamily.nightrain_library.custom.TitleView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title_title_text="首页"
app:title_more_VisibilityText="true"
app:title_backgroundColor="@color/colorPrimaryDark"
app:title_more_backgroundText="保存"
app:title_more_backgroundTextSize="20sp"/>
组合控件设置属性效果图.png
- 尺寸转换
/**
* Px装换Sp
* @param pxValue
* @return
*/
private float converPx2Sp(float pxValue) {
if (pxValue != 0) {
float scale = this.getResources().getDisplayMetrics().density;
return (pxValue / scale);
}
return 0;
}
/**
* Sp转换PX
* @param spValue
* @return
*/
private int converSp2Px(float spValue) {
if (spValue != 0) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spValue, this.getResources().getDisplayMetrics());
}
return 0;
}
网友评论