在Android项目中我们经常会遇到如下的UI展示需求
demo下载
就是模块标题的显示,通常后面内容是动态的,还有诸如有无向右箭头,上下是否显示线条等不同需求.之前项目中的做法是用一个include标签将次布局引入,这必然导致布局文件不易读,而且引入太多include标签页会影响界面的渲染速度,所以改为组合控件形式的自定义控件来改造,支持xml属性定义并且对外暴露相关方法.
1.首先还是自定义我们需要的一些属性,在values文件夹下边新建attrs.xml文件<!--自定义表单-->
<declare-styleable name="CommonFormLayout">
<attr name="leftImage" format="reference" />
<attr name="hasRightArrow" format="boolean" />
<attr name="titleText" format="string|reference" />
<attr name="contentText" format="string|reference" />
<attr name="titleTextColor" format="color" />
<attr name="contentTextColor" format="color|reference" />
<attr name="contentTextHintColor" format="color|reference" />
<attr name="contextTextHint" format="string|reference" />
<attr name="titleTextSize" format="integer|reference" />
<attr name="contentTextSize" format="integer|reference" />
<!--有顶部线时设置为true-->
<attr name="hasTopLine" format="boolean" />
<!--短底部线时设置为true-->
<attr name="isShotBottomLine" format="boolean" />
</declare-styleable>
2.自定义类继承自RelativeLayout,这里将控件载入,并且在构造方法中进行属性解析,并且对外提供必要的set(),get()方法,以便在Java代码中控制属性.
package shidong.com.commonformlayout;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* <declare-styleable name="CommonFormLayout">
* <attr name="leftImage" format="reference" />
* <attr name="hasRightArrow" format="boolean" />
* <attr name="titleText" format="string|reference" />
* <attr name="contentText" format="string|reference" />
* <attr name="titleTextColor" format="color|reference" />
* <attr name="contentTextColor" format="color|reference" />
* <attr name="contentTextHintColor" format="color|reference" />
* <attr name="contextTextHint" format="string|reference" />
* <attr name="titleTextSize" format="integer|reference"/>
* <attr name="contentTextSize" format="integer|reference"/>
* <!--有顶部线时设置为true-->
* <attr name="hasTopLine" format="boolean" />
* <!--短底部线时设置为true-->
* <attr name="isShotBottomLine" format="boolean" />
* </declare-styleable>
* Created by shidong on 16/7/30.
*/
public class CommonFormLayout extends RelativeLayout {
private final TextView tv_common_title;
private final TextView tv_common_content;
private final View view_top_line;
private final View view_bottom_long;
private final View view_bottom_short;
public CommonFormLayout(Context context) {
this(context, null);
}
public CommonFormLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CommonFormLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
LayoutInflater.from(context).inflate(R.layout.layout_common_form, this, true);
tv_common_title = (TextView) findViewById(R.id.tv_common_title);
tv_common_content = (TextView) findViewById(R.id.tv_common_content);
view_top_line = findViewById(R.id.view_top_line);
view_bottom_long = findViewById(R.id.view_bottom_long);
view_bottom_short = findViewById(R.id.view_bottom_short);
//获取属性并解析
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CommonFormLayout);
int count = typedArray.getIndexCount();
for (int i = 0; i < count; i++) {
int itemId = typedArray.getIndex(i);
if (itemId == R.styleable.CommonFormLayout_titleText) {
tv_common_title.setText(typedArray.getText(itemId));
} else if (itemId == R.styleable.CommonFormLayout_contentText) {
tv_common_content.setText(typedArray.getText(itemId));
} else if (itemId == R.styleable.CommonFormLayout_hasRightArrow) {
if (typedArray.getBoolean(itemId, false)) {
tv_common_content.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.mipmap.icon_right_arrow), null);
}
} else if (itemId == R.styleable.CommonFormLayout_leftImage) {
tv_common_title.setCompoundDrawablesWithIntrinsicBounds(typedArray.getDrawable(itemId), null, null, null);
} else if (itemId == R.styleable.CommonFormLayout_titleTextColor) {
tv_common_title.setTextColor(typedArray.getColor(itemId, getResources().getColor(R.color.grey_333333)));
} else if (itemId == R.styleable.CommonFormLayout_contentTextColor) {
tv_common_content.setTextColor(typedArray.getColor(itemId, getResources().getColor(R.color.grey_888888)));
} else if (itemId == R.styleable.CommonFormLayout_hasTopLine) {
if (typedArray.getBoolean(itemId, false)) {
view_top_line.setVisibility(VISIBLE);
}
} else if (itemId == R.styleable.CommonFormLayout_isShotBottomLine) {
if (typedArray.getBoolean(itemId, false)) {
view_bottom_short.setVisibility(VISIBLE);
view_bottom_long.setVisibility(GONE);
}
} else if (itemId == R.styleable.CommonFormLayout_contentTextHintColor) {
tv_common_content.setHintTextColor(typedArray.getColor(itemId, getResources().getColor(R.color.grey_d3d3d3)));
} else if (itemId == R.styleable.CommonFormLayout_contextTextHint) {
tv_common_content.setHint(typedArray.getText(itemId));
} else if (itemId == R.styleable.CommonFormLayout_titleTextSize) {
tv_common_title.setTextSize(TypedValue.COMPLEX_UNIT_SP, typedArray.getInt(itemId, 0));
} else if (itemId == R.styleable.CommonFormLayout_contentTextSize) {
tv_common_content.setTextSize(TypedValue.COMPLEX_UNIT_SP, typedArray.getInt(itemId, 0));
}
}
}
/**
* 设置左侧标题图标
*
* @param resId
*/
public void setLeftImage(int resId) {
setLeftImage(getResources().getDrawable(resId));
}
/**
* 设置左侧标题图标
*
* @param drawable
*/
public void setLeftImage(Drawable drawable) {
tv_common_title.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
}
/**
* 设置是否有向右箭头
*
* @param hasRightArrow
*/
public void setHasRightArrow(boolean hasRightArrow) {
if (hasRightArrow) {
tv_common_content.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.mipmap.icon_right_arrow), null);
} else {
tv_common_content.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
}
}
/**
* 设置标题文本
*
* @param resID
*/
public void setTitleText(int resID) {
setTitleText(getResources().getString(resID));
}
/**
* 设置标题文本
*
* @param text
*/
public void setTitleText(String text) {
tv_common_title.setText(text);
}
/**
* 返回标题文本
*/
public CharSequence getTitleText() {
return tv_common_title.getText();
}
/**
* 设置内容文本
*
* @param resId
*/
public void setContentText(int resId) {
setContentText(getResources().getString(resId));
}
/**
* 设置内容文本
*
* @param text
*/
public void setContentText(String text) {
tv_common_content.setText(text);
}
/**
* 返回内容文本
*/
public CharSequence getContentText() {
return tv_common_content.getText();
}
/**
* 设置标题文本颜色
*
* @param resId
*/
public void setTitleTextColor(int resId) {
tv_common_title.setTextColor(resId);
}
/**
* 设置内容文本颜色
*
* @param resId
*/
public void setContentTextColor(int resId) {
tv_common_content.setTextColor(resId);
}
public void addTextChangedListener(TextWatcher watcher) {
tv_common_content.addTextChangedListener(watcher);
}
public void setContentTextHintColor(int resId) {
tv_common_content.setHintTextColor(resId);
}
public void setHintText(int resId) {
setHintText(getResources().getString(resId));
}
public void setHintText(String text) {
tv_common_content.setHint(text);
}
public void setTitleTextStyleBold() {
TextPaint paint = tv_common_title.getPaint();
paint.setFakeBoldText(true);
}
public void setContentTextStyleBold() {
TextPaint paint = tv_common_content.getPaint();
paint.setFakeBoldText(true);
}
/**
* 内容文本点击监听
*
* @param onClickListener
*/
public void setContentTextClickListener(OnClickListener onClickListener) {
tv_common_content.setOnClickListener(onClickListener);
}
/**
* 设置标题字体大小
*
* @param size 文字大小,单位是sp
*/
public void setTitleTextSize(int size) {
tv_common_title.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}
/**
* 设置内容字体大小
*
* @param size 文字大小,单位是sp
*/
public void setContentTextSize(int size) {
tv_common_content.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}
/**
* 设置根view的背景
*
* @param background
*/
public void setRootViewBackgroundDrawable11(Drawable background) {
View view = findViewById(R.id.root_commom_formlayout);
view.setBackgroundDrawable(null);
}
}
3.然后在界面中就能很轻松地控制这个控件了
package shidong.com.commonformlayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CommonFormLayout commonFormLayout = (CommonFormLayout) findViewById(R.id.common_layout);
commonFormLayout.setTitleTextColor(getResources().getColor(R.color.grey_333333));
commonFormLayout.setContentTextClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getBaseContext(), "点击内容", Toast.LENGTH_SHORT).show();
}
});
}
}
项目中的一个小功能而已.其实想说的是我们在完成一个功能或者模块之前,一定要先统筹全局想一想,是否可以封装公用的代码;并且自己封装的空间和自定义的属性,方法等一定要命名规范,并且添加简洁明了的注释代码,不要给后人留坑啊,亲身被坑所以深有感触…