Android-自定义View之重写控件(自定义Dialog)

自定义控件实现的方式主要有:重写控件,组装控件,继承View,opengL等。这里说的控件是指安卓自有的控件,TextView、Button等。

本篇先讲第一种方式:重写控件

重写控件,也就是继承控件类,主要是重写原有的方法,增加自定义方法,修改原有部分属性。更多的应用场景是为父控件设置一个特定的布局,或者是设置特定的点击响应。以便在app里达到重用或者是简化代码的目的。是自定义控件的一个常用的方式。

这里我将创建一个自定义的Dialog用来讲解这个方法。

我们将修改Dialog原有的样式,提供确定和取消键。

首先,我们构造一个Dialog的完整布局。注意是完整布局,包括标题等。整个弹窗的视图都在这里创建。对于原有标题,我们将通过创建无标题样式将其去掉。这样我们可以很方便地控制标题的位置等。以下是名为dialog.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:background="#b98304"
	android:orientation="vertical">

	<TextView
		android:id="@+id/title"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_marginTop="20dp"
		android:layout_marginLeft="30dp"
		android:layout_marginBottom="15dp"
		android:layout_marginRight="30dp"
			android:textColor="#FFFFFF"/>
	<TextView
		android:layout_width="fill_parent"
		android:layout_height="2dp"
		android:includeFontPadding="false"
		android:background="#992a942f"/>

	<LinearLayout
		android:orientation="vertical"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:layout_marginTop="20dp"
		android:layout_marginLeft="30dp"
		android:layout_marginRight="30dp"
		android:layout_marginBottom="15dp"
		android:gravity="center">

		<TextView
			android:id="@+id/message"
			android:layout_width="350dp"
			android:layout_height="wrap_content"
			android:gravity="center"
			android:textColor="#FFFFFF"/>

	</LinearLayout>

	<TextView
		android:layout_width="fill_parent"
		android:layout_height="1dp"
		android:background="#992a942f"/>
	<LinearLayout
		android:orientation="horizontal"
		android:layout_width="fill_parent"
		android:layout_height="60dp"
		android:gravity="center_vertical">

		<TextView
			android:id="@+id/positiveButton"
			android:layout_width="0dp"
			android:layout_weight="1"
			android:layout_height="fill_parent"
			android:includeFontPadding="false"
			android:textSize="18sp"
			android:textColor="#FFFFFF"
			android:gravity="center"
			android:singleLine="true"
			android:clickable="true"
			android:text="确定"/>
		<TextView
			android:id="@+id/txv_dialog_common_diliver"
			android:layout_width="1dp"
			android:layout_height="60dp"
			android:includeFontPadding="false"
			android:background="#992a942f"/>
		<TextView
			android:id="@+id/negativeButton"
			android:layout_width="0dp"
			android:layout_weight="1"
			android:layout_height="fill_parent"
			android:includeFontPadding="false"
			android:textSize="18sp"
			android:textColor="#FFFFFF"
			android:gravity="center"
			android:singleLine="true"
			android:clickable="true"
			android:text="取消"/>
	</LinearLayout>

</LinearLayout>

然后,我们还需要创建一个style文件,其属性大致有以下即可:

	<style
		name="CustomDialog"
		parent="android:style/Theme.Dialog">
		<item
			name="android:windowFrame">@null</item><!--边框 -->
		<item
			name="android:windowIsFloating">true</item><!--是否浮现在activity之上 -->
		<item
			name="android:windowIsTranslucent">true</item><!--半透明 -->
		<item
			name="android:windowNoTitle">true</item><!--无标题 -->
		<item
			name="android:windowBackground">@android:color/transparent</item><!--背景透明 -->
		<item
			name="android:backgroundDimEnabled">true</item><!--模糊 -->
	</style>

接着,也是最关键的一步,就是要继承一个Dialog类。然后调用父类的方法,为自定义控件填充视图。并重写一些必要的方法。

/**
 * 自定义控件-自定义对话框
 * @author Ives
 *
 */
public class CustomDialog extends Dialog {
	private TextView titleTxv;	//标题
	private TextView msgTxv;	//提示内容文字
	private TextView positiveTxv;	//确定按钮
	private TextView negativeTxv;	//取消按钮

	/**
	 * @param context
	 */
	public CustomDialog(Context context) {
		super(context,R.style.CustomDialog);	//自定义style主要去掉标题,标题将在setCustomView中自定义设置
		setCustomView();
	}
	
	public CustomDialog(Context context, boolean cancelable,
			OnCancelListener cancelListener) {
		super(context, R.style.CustomDialog);
		this.setCancelable(cancelable);
		this.setOnCancelListener(cancelListener);
		setCustomView();
	}

	public CustomDialog(Context context, int theme) {
		super(context, R.style.CustomDialog);
		setCustomView();
	}

	/**
	 * 设置整个弹出框的视图
	 */
	private void setCustomView(){
		View mView = LayoutInflater.from(getContext()).inflate(R.layout.dialog, null);
		titleTxv = (TextView) mView.findViewById(R.id.title);
		msgTxv = (TextView) mView.findViewById(R.id.message);
		positiveTxv = (TextView) mView.findViewById(R.id.positiveButton);
		negativeTxv = (TextView) mView.findViewById(R.id.negativeButton);
		super.setContentView(mView);
	}
	
	@Override
	public void setContentView(View view){
		//重写本方法,使外部调用时不可破坏控件的视图。
		//也可以使用本方法改变CustomDialog的内容部分视图,比如让用户把内容视图变成复选框列表,图片等。这需要获取mView视图里的其它控件
	}

	@Override
	public void setTitle(CharSequence title) {
		titleTxv.setText(title);
	}

	@Override
	public void setTitle(int titleId) {
		setTitle(getContext().getString(titleId));
	}
	
	/**
	 * 设置提示内容文字
	 * @param msg
	 */
	public void setMessage(CharSequence msg){
		msgTxv.setText(msg);
	}
	/**
	 * 设置确定键文字
	 * @param text
	 */
	public void setPositiveText(CharSequence text){
		positiveTxv.setText(text);
	}
	/**
	 * 设置取消键文字
	 * @param text
	 */
	public void setNegativeText(CharSequence text){
		negativeTxv.setText(text);
	}
	
	/**
	 * 确定键监听器
	 * @param listener
	 */
	public void setOnPositiveListener(View.OnClickListener listener){
		positiveTxv.setOnClickListener(listener);
	}
	/**
	 * 取消键监听器
	 * @param listener
	 */
	public void setOnNegativeListener(View.OnClickListener listener){
		negativeTxv.setOnClickListener(listener);
	}
	

}

代码里说得比较详细,这是比较基本的一个实现。使用方式直接new之后,set完上面几个方法,调用show方法即可显示。

其实这个例子已经有点偏向组装控件的方式了,组装控件将会在下一篇中讲到。更典型更纯粹的继承控件的例子你可以写一个自定义的Toast或者TextView,这样更纯粹是继承控件,就没有组装控件的内容了。总的来说,继承控件只要有以下两步:

1.继承一个自有控件;

2.重写父类的一些方法。


你可能感兴趣的:(android,自定义控件,自定义dialog,封装控件,继承Dialog)