Android - 自定义控件(二)
在Android - 自定义控件专题(一)一文中,列举了最简单的自定义控件的类型——直接在xml文件中完成控件自定义效果和为控件指定一个xml文件来达到自定义效果。
本篇文章继续列举自定义控件的其他使用场景及其示例。
在一个应用中,有时我们会发现有很多相似的布局,并且这些布局都是由固定的几个控件组合而成的,比如如下的布局:

下边是一个自定义的组合控件CustomEditText.java:
public class CustomEditText extends LinearLayout {
private TextView tv_left;
private EditText mEditText;
/**EditText是否可编辑*/
public void setEditTextEnabled(boolean isEnabled) {
mEditText.setEnabled(isEnabled);
}
public CustomEditText(Context context) {
this(context, null);
}
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
initSetting(context);
}
public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@SuppressLint("NewApi")
private void initSetting(Context context) {
int dip = CommInfo.dip2px(getContext(), 2);
setOrientation(LinearLayout.HORIZONTAL);
setBackgroundColor(getResources().getColor(R.color.transparent));
tv_left = new TextView(context);
tv_left.setSingleLine(true);
tv_left.setTextColor(Color.BLACK);
tv_left.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
tv_left.setBackgroundResource(Color.TRANSPARENT);
mEditText = new EditText(context);
if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
mEditText.setBackground(null);
}else{
setBackgroundDrawable(null);
}
mEditText.setSingleLine(true);
mEditText.setBackgroundResource(Color.TRANSPARENT);
mEditText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
// mEditText.setBackgroundResource(R.drawable.frame_edit_gray);
LayoutParams tvLp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tvLp.gravity = Gravity.CENTER;
tvLp.leftMargin = dip;
tvLp.rightMargin = 0;
tvLp.topMargin = dip;
tvLp.bottomMargin = dip;
tv_left.setLayoutParams(tvLp);
LayoutParams editLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
editLp.gravity = Gravity.CENTER;
editLp.leftMargin = CommInfo.dip2px(getContext(), 5);
editLp.rightMargin = dip;
editLp.topMargin = dip;
editLp.bottomMargin = dip;
mEditText.setLayoutParams(editLp);
addView(tv_left);
addView(mEditText);
}
public void setCustomText(String text) {
tv_left.setText(text);
}
public String getText(){
return mEditText.getText().toString();
}
public void setEditTextHintColor(int color){
mEditText.setHintTextColor(color);
}
/**设置EditText的hint文本和大小
* @param text
* @param hintSize 单位dip
*/
public void setEditTextHint(String text, int hintSize){
// 新建一个可以添加属性的文本对象
SpannableString ss = new SpannableString(text);
// 新建一个属性对象,设置文字的大小
AbsoluteSizeSpan ass = new AbsoluteSizeSpan(hintSize, true);
// 附加属性到文本
ss.setSpan(ass, 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mEditText.setHint(new SpannedString(ss));
}
public void setEditTextClickListener(OnClickListener click){
mEditText.setOnClickListener(click);
}
public void setEditTextTouchListener(OnTouchListener touch){
mEditText.setOnTouchListener(touch);
}
public void setInputType(CustomEditTextType type){
switch (type) {
case TYPE_NO_INPUT:
mEditText.setInputType(InputType.TYPE_NULL);
mEditText.setBackgroundResource(R.drawable.frame_edit_gray);
break;
default:
break;
}
mEditText.requestFocusFromTouch();
mEditText.requestFocus();
}
public void setEditTextText(String text){
mEditText.setText(text);
}
public void setEditTextInputType(int type){
mEditText.setInputType(type);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void changeEditMargin(int left, int right, int top, int bottom){
LayoutParams lp = (LayoutParams) mEditText.getLayoutParams();
lp.leftMargin = left;
lp.rightMargin = right;
lp.topMargin = top;
lp.bottomMargin = bottom;
mEditText.setLayoutParams(lp);
}
public void setEditWeight(int weight){
LayoutParams lp = (LayoutParams) mEditText.getLayoutParams();
lp.weight = weight;
mEditText.setLayoutParams(lp);
}
public void setTextWeight(int weight){
LayoutParams lp = (LayoutParams) tv_left.getLayoutParams();
lp.weight = weight;
tv_left.setLayoutParams(lp);
}
public void setTextWH(int width, int height){
LayoutParams lp = (LayoutParams) tv_left.getLayoutParams();
lp.width = width;
lp.height = height;
tv_left.setLayoutParams(lp);
}
public enum CustomEditTextType{
TYPE_NO_INPUT
}
public void setEditFocus(boolean focus){
mEditText.setFocusable(focus);
}
}
在xml文件中进行引入:
<com.hwgt.custom.view.CustomEditText android:id="@+id/change_pass_oldpass" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop="30dp" android:paddingLeft="10dp"/>
然后,在activity中:
private CustomEditText edt_oldpass; edt_oldpass.setBackgroundResource(R.drawable.frame_edit_gray); edt_oldpass.setCustomText(getResources().getString(R.string.old_psw)); edt_oldpass.setEditTextHint(getResources().getString(R.string.please_input), 15); edt_oldpass.setEditTextInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
drawable中的frame_edit_gray文件:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#ffffff" />
<corners android:topLeftRadius="2dp" android:topRightRadius="2dp"
android:bottomLeftRadius="2dp" android:bottomRightRadius="2dp" />
<stroke android:width="0.5dp" android:color="#dbdbdb" />
</shape>
类似本文开头所展示的图片中的这种布局,如果采用自定义控件来实现的话,好处是,统一布局的某些属性,将个性化属性的设置方法暴露出去,减少xml文件中的代码量... ...
当然,这只是增加一种解决问题的思路而已,这种简单的布局偏要写成自定义的,有时候不一定就好,还是要结合具体情况来分析。
浙公网安备 33010602011771号