在Android - 自定义控件专题(一)一文中,列举了最简单的自定义控件的类型——直接在xml文件中完成控件自定义效果和为控件指定一个xml文件来达到自定义效果。
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文件中的代码量... ...
public class LayerBottom extends RelativeLayout { private View viewBlackBack; private View viewContent; private Animation animationShow; private Animation animationHide; private Animation animationBackShow; private Animation animationBackHide; public LayerBottom(Context context, AttributeSet attrs) { super(context, attrs); initView(); } private void initView() { setVisibility(View.INVISIBLE); viewBlackBack = new View(getContext()); viewBlackBack.setBackgroundColor(Color.parseColor("#55000000")); RelativeLayout.LayoutParams lpBack = new RelativeLayout.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.MATCH_PARENT); addView(viewBlackBack, lpBack); } /**是否是显示状态 */ public boolean isShow() { return (getVisibility() == View.VISIBLE); } /** 指定弹层布局文件id*/ public void setContent(int resourceId) { if (getChildCount() > 1) { removeView(getChildAt(1)); } viewContent = LayoutInflater.from(getContext()).inflate(resourceId, null); RelativeLayout.LayoutParams lpContent = new RelativeLayout.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT); lpContent.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); addView(viewContent, lpContent); } /** 打开弹层 */ public void showLayer() { if (getVisibility() == View.INVISIBLE || getVisibility() == View.GONE) { setVisibility(View.VISIBLE); } showBackBlack(); if (animationShow == null) { animationShow = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f); } animationShow.setDuration(500); viewContent.startAnimation(animationShow); } /** 隐藏弹层*/ public void hideLayer() { hideBackBlack(); if (animationHide == null) { animationHide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f); } animationHide.setDuration(500); viewContent.startAnimation(animationHide); animationHide.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { if (getVisibility() == View.VISIBLE) { setVisibility(View.INVISIBLE); } } }); } private void showBackBlack() { if (animationBackShow == null) { animationBackShow = new AlphaAnimation(0.0f, 1.0f); animationBackShow.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { viewBlackBack.setVisibility(View.VISIBLE); viewContent.setVisibility(View.VISIBLE); } @Override public void onAnimationRepeat(Animation arg0) { } @Override public void onAnimationEnd(Animation arg0) { } }); } animationBackShow.setDuration(500); viewBlackBack.startAnimation(animationBackShow); } private void hideBackBlack() { if (animationBackHide == null) { animationBackHide = new AlphaAnimation(1.0f, 0.0f); animationBackHide.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { viewBlackBack.setVisibility(View.INVISIBLE); viewContent.setVisibility(View.INVISIBLE); } }); } animationBackHide.setDuration(500); viewBlackBack.startAnimation(animationBackHide); } @Override public boolean onTouchEvent(MotionEvent event) {//保证后面的UI不可点击 return true; } }
在xml文件中引用:
<com.hwgt.custom.view.LayerBottom android:id="@+id/layer_bottom_img" android:layout_width="match_parent" android:layout_height="match_parent"/>
然后,在activity中:
//用来显示图片获取方式的布局(从底部弹出) private LayerBottom layerBottomImg; layerBottomImg = (LayerBottom) findViewById(R.id.layer_bottom_img); layerBottomImg.setContent(R.layout.layer_bottom_item_bg); ... ... layerBottomImg.showLayer();//弹出弹框 layerBottomImg.hideLayer();//隐藏弹框
布局文件layer_bottom_item_bg.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#ffffff" android:orientation="vertical" android:gravity="center"> <LinearLayout android:id="@+id/ll_layer_take_picture" android:layout_width="match_parent" android:layout_height="53dp" android:gravity="center_vertical|center_horizontal" android:orientation="vertical" android:background="@drawable/ll_layer_item_select_bg"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拍照" android:textSize="17dp" android:textColor="#222222"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#ededed"/> <LinearLayout android:id="@+id/ll_layer_select" android:layout_width="match_parent" android:layout_height="53dp" android:gravity="center_vertical|center_horizontal" android:orientation="vertical" android:background="@drawable/ll_layer_item_select_bg"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="从手机相册选择" android:textSize="17dp" android:textColor="#222222"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="12dp" android:background="#ededed"/> <LinearLayout android:id="@+id/ll_layer_cancle" android:layout_width="match_parent" android:layout_height="53dp" android:gravity="center_vertical|center_horizontal" android:orientation="vertical" android:background="@drawable/ll_layer_item_select_bg"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="取消" android:textSize="17dp" android:textColor="#222222"/> </LinearLayout> </LinearLayout>
drawable中的ll_layer_item_select_bg.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/layer_item_press" android:state_pressed="true"/> <item android:drawable="@drawable/layer_item_no_press" android:state_enabled="false"/> <item android:drawable="@drawable/layer_item_no_press"/> </selector>
drawable中的layer_item_press.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#ededed"/> <corners android:radius="0dp"/> </shape>
drawable中的layer_item_no_press.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#ffffff"/> <corners android:radius="0dp"/> </shape>
原文:http://www.cnblogs.com/hwgt/p/5420592.html