自定义控件实现的方式主要有:重写控件,组装控件,继承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 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>
/** * 自定义控件-自定义对话框 * @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.重写父类的一些方法。