首页 > 移动平台 > 详细

Android - 自定义控件(二)

时间:2016-04-22 11:52:51      阅读:238      评论:0      收藏:0      [点我收藏+]

Android - 自定义控件专题(一)一文中,列举了最简单的自定义控件的类型——直接在xml文件中完成控件自定义效果和为控件指定一个xml文件来达到自定义效果。

本篇文章继续列举自定义控件的其他使用场景及其示例。
一、在一个应用中,有时我们会发现有很多相似的布局,并且这些布局都是由固定的几个控件组合而成的,比如如下的布局:
技术分享
 
类似这种textview和edittext的组合会大量的出现在一个应用中,有时我们可以根据需要自定义一个layout,以达到对这种控件组合布局的复用。
下边是一个自定义的组合控件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文件中的代码量... ...

当然,这只是增加一种解决问题的思路而已,这种简单的布局偏要写成自定义的,有时候不一定就好,还是要结合具体情况来分析。
 
二、一个自定义layout用以实现弹出个性化的提示框
技术分享
 
比如需要上传照片时,可以弹出这样的一个提示框供用户选择获取图片的方式,同样,在其他情况下也可能有类似的需求,于是,可以考虑使用自定义控件来达到复用和可扩展的目的。
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>

  

 

 

Android - 自定义控件(二)

原文:http://www.cnblogs.com/hwgt/p/5420592.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!