Android自定义Dialog对话框

请关注DeveloperQ公众号

DeveloperQ公众号

Android本身提供了很多Dialog对话框,比如AlertDialog、ProgressDialog,基本上已经包含了普通(包含提示消息和按钮)、列表、单选、多选、等待、进度条、编辑、自定义等多种对话框形式,那么我们为什么还要大费周章的来自定义Dialog对话框呢?在这个“看脸”越来越严重的社会,大家觉得Android自带的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:layout_margin="40dp"    android:background="@drawable/bg_dialog"    android:orientation="vertical">    <LinearLayout        android:id="@+id/llcontainer"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginLeft="6dp"        android:layout_marginRight="6dp"        android:orientation="vertical">        <TextView            android:id="@+id/title"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="left"            android:layout_marginLeft="10dp"            android:layout_marginTop="10dp"            android:layout_marginBottom="10dp"            android:text="标题"            android:textColor="#666666"            android:textSize="18sp"            android:textStyle="bold" />        <TextView            android:id="@+id/message"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="left"            android:layout_marginBottom="10dp"            android:layout_marginTop="10dp"            android:text="内容"            android:textColor="@color/baseTextColor"            android:textSize="16sp" />    </LinearLayout>    <View        android:layout_width="match_parent"        android:layout_height="0.1dp"        android:layout_margin="4dp"        android:background="#CCCCCC" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="10dp">        <Button            android:id="@+id/confirm"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:layout_weight="1"            android:background="@drawable/normalbtnstyle"            android:gravity="center"            android:text="确定"            android:textColor="@color/white"            android:textSize="16sp" />        <Button            android:id="@+id/cancel"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="10dp"            android:layout_weight="1"            android:background="@drawable/normalbtnstyle"            android:gravity="center"            android:text="取消"            android:textColor="@color/white"            android:textSize="16sp" />   </LinearLayout>
</LinearLayout>

看下XML编辑器中预览出来的效果吧



界面写好了,下面看代码部分,先讲第一种实现方式(比较挫一点的),继承Dialog类,实现相应的方法。


/**
* Created by alany on 2017/4/12.
*/
public class CustomDialog extends Dialog {
     private Context context;
   private
String title = "";
   private
String message = "";
   private
String confirmBtnText = "";
   private
String cancelBtnText = "";
   private
ClickListenerInterface clickListenerInterface;

   public interface
ClickListenerInterface {
           void doConfirm();
       void
doCancel();
   
}

   public CustomDialog(Context context, String title, String message) {
       super(context, R.style.MyDialogStyle);
       this
.context = context;
       this
.title = title;
       this
.message = message;
   
}

   public CustomDialog(Context context, String title, String message, String confirmBtnText, String cancelBtnText) {
       this(context,title,message);
       this
.confirmBtnText = confirmBtnText;
       this
.cancelBtnText = cancelBtnText;
   
}

   @Override
   
protected void onCreate(Bundle savedInstanceState) {
       // TODO Auto-generated method stub
       
super.onCreate(savedInstanceState);
       
init();
   
}

   public void init() {
       LayoutInflater inflater = LayoutInflater.from(context);
       
View view = inflater.inflate(R.layout.my_info_dialog, null);
       
setContentView(view);

       
TextView tvTitle = (TextView) view.findViewById(R.id.title);
       
TextView tvMessage = (TextView) view.findViewById(R.id.message);
       
Button btnConfirm = (Button) view.findViewById(R.id.confirm);
       
Button btnCancel = (Button) view.findViewById(R.id.cancel);

       
tvTitle.setText(title);
       
tvMessage.setText(message);
       if
(! confirmBtnText.isEmpty() && ! cancelBtnText.isEmpty()) {
           btnConfirm.setText(confirmBtnText);
           
btnCancel.setText(cancelBtnText);
       
}

       btnConfirm.setOnClickListener(new clickListener());
       
btnCancel.setOnClickListener(new clickListener());

       
Window dialogWindow = getWindow();
       
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
       
DisplayMetrics d = context.getResources().getDisplayMetrics(); // 获取屏幕宽、高用
       
lp.width = (int) (d.widthPixels * 0.8); // 高度设置为屏幕的0.6
       
dialogWindow.setAttributes(lp);
   
}

   public void setClicklistener(ClickListenerInterface clickListenerInterface) {
       this.clickListenerInterface = clickListenerInterface;
   
}

   private class clickListener implements View.OnClickListener {
       @Override
       
public void onClick(View v) {
           // TODO Auto-generated method stub
           
int id = v.getId();
           switch
(id) {
               case R.id.confirm:
                   clickListenerInterface.doConfirm();
                   break;
               case
R.id.cancel:
                   clickListenerInterface.doCancel();
                   break;
           
}
       }
   };

}


自定义Dialog写好之后,下面在Activity中使用:

final CustomDialog confirmDialog = new CustomDialog(DataAdmin.this, "备份提示",
   
"该操作会覆盖已有备份数据,是否确认备份?");
confirmDialog.show();
confirmDialog.setClicklistener(new CustomDialog.ClickListenerInterface() {
   @Override
   
public void doConfirm() {
       // TODO Auto-generated method stub
       
confirmDialog.dismiss();
       try
{
           backupFile.createNewFile();
           
fileCopy(dbFile, backupFile);
           
status = BACKUP_SUCCESS;
       
} catch (Exception e) {
           e.printStackTrace();
           
faildError = e.getMessage();
           
status = BACKUP_ERROR;
       
}
       freshUI(status);
   
}

   @Override
   
public void doCancel() {
       // TODO Auto-generated method stub
       
confirmDialog.dismiss();
   
}
});

看下效果:


这样写感觉还不够好,没有充分发挥java语言面向对象和封装继承的优势,所以我准备了方法二。


自定义Dialog方法二:

布局就都一样了,主要是对CustomDialog类的修改,使其尽量靠近Android 自身的AlertDialog的使用习惯,还增加了setView 方法,可以再加入一些个性化的View,看代码吧:

/**
* Created by alany on 2017/4/12.
*/
public class CustomDialog1 extends Dialog {
   private Context context;
   private
String title = "";
   private
String message = "";
   private
View customView;
   private
String confirmBtnText = "";
   private
String cancelBtnText = "";
   private
OnConfirmClickListener onConfirmClickListener;
   private
OnCancelClickListener onCancelClickListener;

   public interface
OnConfirmClickListener{
       void doConfirm();
   
}
   public interface OnCancelClickListener{
       void doCancel();
   
}

   public CustomDialog1(Context context){
       super(context, R.style.MyDialogStyle);
       this
.context = context;
   
}

   public CustomDialog1 setTitle(String title){
       this.title = title;
       return this;
   
}
   public CustomDialog1 setMessage(String message){
       this.message = message;
       return this;
   
}
   public CustomDialog1 setView(View customView){
       this.customView = customView;
       return this;
   
}
   public CustomDialog1 setConfirmButton(String text, OnConfirmClickListener onClickListener){
       this.confirmBtnText = text;
       this
.onConfirmClickListener = onClickListener;
       return this;
   
}

   public CustomDialog1 setCancelButton(String text, OnCancelClickListener onClickListener){
       this.cancelBtnText = text;
       this
.onCancelClickListener = onClickListener;
       return this;
   
}

   @Override
   
protected void onCreate(Bundle savedInstanceState) {
       // TODO Auto-generated method stub
       
super.onCreate(savedInstanceState);
       
init();
   
}

   public void init() {
       LayoutInflater inflater = LayoutInflater.from(context);
       
View view = inflater.inflate(R.layout.my_info_dialog, null);
       
setContentView(view);

       
LinearLayout container = (LinearLayout) view.findViewById(R.id.llcontainer);
       if
(customView != null){
           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
               container.addView(customView);
           
}
       }
       TextView tvTitle = (TextView) view.findViewById(R.id.title);
       
TextView tvMessage = (TextView) view.findViewById(R.id.message);
       
Button btnConfirm = (Button) view.findViewById(R.id.confirm);
       
Button btnCancel = (Button) view.findViewById(R.id.cancel);

       
tvTitle.setText(TextUtils.isEmpty(title) ? "提示" : title);
       if
(TextUtils.isEmpty(message)) {
           tvMessage.setVisibility(View.GONE);
       
}else{
           tvMessage.setText(message);
       
}
       if(! TextUtils.isEmpty(confirmBtnText) && ! TextUtils.isEmpty(cancelBtnText)) {
           btnConfirm.setText(confirmBtnText);
           
btnCancel.setText(cancelBtnText);
       
}

       btnConfirm.setOnClickListener(new CustomDialogClickListener());
       
btnCancel.setOnClickListener(new CustomDialogClickListener());

       
Window dialogWindow = getWindow();
       
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
       
DisplayMetrics d = context.getResources().getDisplayMetrics(); // 获取屏幕宽、高用
       
lp.width = (int) (d.widthPixels * 0.8); // 高度设置为屏幕的0.6
       
dialogWindow.setAttributes(lp);
   
}

   private class CustomDialogClickListener implements View.OnClickListener{
       @Override
       
public void onClick(View v) {
           // TODO Auto-generated method stub
           
int id = v.getId();
           switch
(id) {
               case R.id.confirm:
                   onBackPressed();
                   if
(onConfirmClickListener != null){
                       onConfirmClickListener.doConfirm();
                   
}
                   break;
               case
R.id.cancel:
                   onBackPressed();
                   if
(onCancelClickListener != null){
                       onCancelClickListener.doCancel();
                   
}
                   break;
           
}
       }
   };
}


一样的,看下修改后的CustomDialog的用法,是不是跟AlertDialog很类似?

final View view = View.inflate(mContext, R.layout.account_edit, null);
final
EditText etName = (EditText) view.findViewById(R.id.et_account_name);
final
EditText etMoney = (EditText) view.findViewById(R.id.et_account_money);
etName.setTextSize(16);
etMoney.setTextSize(16);
new
CustomDialog1(mContext).setTitle(dt).setView(view).setConfirmButton("确定",
   new
CustomDialog1.OnConfirmClickListener() {
   
@Override
   
public void doConfirm() {
       
//点击确定按钮的实现
   }
}).setCancelButton(
"取消",null).show();

也看下实际效果:


好了,源码几乎都贴在上面了,需要的童鞋直接引用吧,非Android开发专业选手,有不妥之处烦请指正,感谢~


测试开发栈

往期更多原创技术好文和资料,请关注下方公众号:

软件测试开发合并必将是趋势,不懂开发的测试、不懂测试的开发都将可能被逐渐替代,因此前瞻的技术储备和知识积累是我们以后在职场和行业脱颖而出的法宝,期望我们的经验和技术分享能让你每天都成长和进步,早日成为测试开发栈上的技术大牛~~

同时也欢迎加入我们的QQ群交流和提问:427020613


测试开发栈










相关问题推荐