专栏首页AndroidStudio初识错误操作怎么办?用他让你不再害怕!—Dialog最详解

错误操作怎么办?用他让你不再害怕!—Dialog最详解

前言

Hi,好久不见,甚是想念各位花粉,为了感谢花粉们长久以来的支持,本篇文章继续分享Android中非常实用的干货— Dialog(对话框)!那么什么叫 Dialog,简单来说就是一句话:弹出一个窗口,提示用户自己去选择。 Dialog对话框是Android常用的基础视图组件之一,本期总结了对话框常用的几种样式,以及自定义视图和带动画效果的对话框,打开你们的IDE,赶紧跟着我们继续奋斗吧!

简介

Dialog组件并非继承自 View,而是继承自 ObjectDialog的生命周期通常会由 Activity来控制,当 Activity被销毁后,如果再有对 Dialog的操作会导致异常:java.lang.IllegalArgumentException: View not attached to window manager。

Dialog继承关系:

java.lang.Object
  ↳android.app.Dialog

Android系统自带的 Dialog有四种:

- AlertDialog 普通提示对话框,可以有0-3个按钮,可以有单选或者复选框的对话框,可以创建大多数界面

- ProgressDialog 进度条对话框,显示一个进度或者进度条,继承自AlertDialog

- DatePickerDialog 日期对话框

- TimePickerDialog 时间对话框

所有对话框,都是直接或简介继承自 Dialog,其它的几个类均继承自 AlertDialog

普通弹框
public void showDialog(View v) {
        // 这里的属性可以一直设置,因为每次设置后返回的是一个builder对象
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        // 设置提示框的标题
        builder.setTitle("提示标题");
        // 设置要显示的信息
        setMessage("你妈喊你回家吃饭了!");
        // 设置确定按钮
        setPositiveButton("确定", new OnClickListener() {
             @Override
             public void onClick(DialogInterface dialog, int which) {
                  //do something
             }
        });
        setNeutralButton("取消", new OnClickListener() {
         @Override
         public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
         }
         });
        //生成对话框
        AlertDialog alertDialog = builder.create();
        alertDialog.show();
}
选择菜单样式弹框
String[] array = new String[] {"身高160cm的妹子", "身高165cm的妹子", "身高170cm的妹子", "身高175cm的妹子"};
public void showMenuDialog(View v) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("选择你最喜欢的妹子").
    setItems(array, new OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
              Toast.makeText(MainActivity.this, "我喜欢" + array[which],0).show();
           }
     }).
     create().show();
}
单选按钮样式的弹框
String[] array = new String[] { "身高160cm的妹子", "身高165cm的妹子", "身高170cm的妹子", "身高175cm的妹子" };
public void radioListDialog(View v) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("选择你最喜欢的妹子").
        setSingleChoiceItems(array, 0, new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "我喜欢" + array[which],0).show();
            }
        });
        setPositiveButton("确定", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "选择确定", 0).show();
            }
        });
        setNegativeButton("取消", null);
        create().show();
}
多选按钮样式的弹框
public void checkboxListDialog(View v) {
    boolean[] checkedItems = { true, false, false, true };
    final List<String> list = new ArrayList<String>();
    list.add("听音乐");
    list.add("看书");
    list.add("睡觉");
    list.add("打豆豆");
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("周末你一般都喜欢做什么").
      setMultiChoiceItems(array, checkedItems,
                          new OnMultiChoiceClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog,
                                                int which, boolean isChecked) {
                              if (isChecked) {
                                // 添加数据
                                list.add(array[which]);
                              } else {
                                list.remove(array[which]);
                              }

                            }
                          });
      setPositiveButton("确定", new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          Toast.makeText(MainActivity.this, "你喜欢" + list, 0)
            .show();
        }
      });
      setNegativeButton("取消", null);
      create().show();
}
圆形进度弹框
public void circleProgress(View v) {
    //创建进度条的对话框
    ProgressDialog dialog = new ProgressDialog(this);
    //设置进度条的样式,选择圆形或条状
    dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    //设置标题
    dialog.setTitle("升级更新");
    //设置文本信息
    dialog.setMessage("正在下载...");
    //设置是否能用后退键出对话框,选择false就代表不能退出
    dialog.setCancelable(false);
    // 显示对话框
    dialog.show();
}
水平进度弹框
public void showProgress(View v) {
    final ProgressDialog dialog = new ProgressDialog(this);
    dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    dialog.setMax(100);
    dialog.setTitle("升级更新");
    dialog.setMessage("正在下载...");
    dialog.setCancelable(false);
    // 显示对话框
    dialog.show();
    // 这里新建一个线程来,更新进度和关闭页面
    new Thread(new Runnable() {
      @Override
      public void run() {
        // 获取进度值的当前的值
        int index = 0;
        // 更新进度
        while (index < dialog.getMax()) {
          index++;
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          // 设置进度的值
          dialog.setProgress(index);

        }
        // 完成任务后,退出对话框
        dialog.cancel();
      }
    }).start();
}
选择时间弹框
public void selectTime(View v) {
        //第一个参数是上下文
        //第二个参数是监听时间选择后的事件
        //后面两个数是默认是时间
        //后一个是代表是否显示时间的格式是24小时制的
        TimePickerDialog dialog = new TimePickerDialog(this,
                new OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay,
                            int minute) {
                        Toast.makeText(MainActivity.this,
                                hourOfDay + "时" + minute + "分", 0).show();
                    }
                }, 12, 12, true);
        //显示标题
        dialog.setTitle("选择你要设定的时间");
        // 显示时间的对话框
        dialog.show();
}
选择日期弹框
public void selectDate(View v) {
        // 第一个参数是上下文
        // 第二个参数是监听时间选择后的事件
        // 后面三个数是默认是日期数
        DatePickerDialog dialog = new DatePickerDialog(this,
                new OnDateSetListener() {
                    // 日期选择器上的月份是从0开始的
                    @Override
                    public void onDateSet(DatePicker view, int year,
                            int monthOfYear, int dayOfMonth) {
                        Toast.makeText(
                                MainActivity.this,
                                year + "年" + (monthOfYear + 1) + "月"
                                        + dayOfMonth + "日", 0).show();
                    }
                }, 2019, 9, 1);
        // 显示时间的对话框
        dialog.show();
}
自定义布局弹框

可以通过创建一个自定义布局,然后调用 AlertDialog.Builder对象上的 setView()方法将其添加到 AlertDialog

xml自定义布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="wrap_content"
    android:background="#0000"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:background="#fff">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:orientation="vertical"
            android:paddingLeft="20dp"
            android:paddingRight="20dp"
            android:paddingBottom="20dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="30dp"
                android:text="开启新世界"
                android:textSize="18sp" />

            <EditText
                android:id="@+id/login_et1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="40dp"
                android:background="@null"
                android:hint="请输入用户名"
                android:textSize="16sp" />

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:layout_marginTop="5dp"
                android:background="#d3d3d3" />

            <EditText
                android:id="@+id/login_et2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="30dp"
                android:background="@null"
                android:hint="请输入密码"
                android:inputType="textPassword"
                android:textSize="16sp" />

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:layout_marginTop="5dp"
                android:background="#d3d3d3" />

            <Button
                android:id="@+id/login_btn"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginTop="35dp"
                android:background="#000000"
                android:padding="5dp"
                android:text="登 录"
                android:textColor="#ffffff"
                android:textSize="16sp" />

        </LinearLayout>

    </RelativeLayout>

</LinearLayout>

DialogFragmentonCreateDialog()方法中加载自定义布局文件,并添加到 AlertDialog.Builder中,在按钮点击事件中获取用户名和密码

public class LoginDialogFragment extends DialogFragment implements View.OnClickListener {

    public static final String USERNAME = "userName";
    public static final String USERPASSWORD = "userPassword";
    private EditText mUsername;
    private EditText mPassword;
    private Button loginBtn;
    private AlertDialog.Builder builder = null;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //设置背景透明
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        builder = new AlertDialog.Builder(getActivity());
        View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_login, null);
        mUsername = view.findViewById(R.id.login_et1);
        loginBtn = view.findViewById(R.id.login_btn);
        mPassword = view.findViewById(R.id.login_et2);
        loginBtn.setOnClickListener(this);
        builder.setView(view);
        return builder.create();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.login_btn:
                if (TextUtils.isEmpty(mUsername.getText().toString()) 
                    || TextUtils.isEmpty(mPassword.getText().toString())) {
                    Toast.makeText(getActivity(), 
                                   "用户名或密码不能为空", Toast.LENGTH_SHORT).show();
                    return;
                }
                Toast.makeText(getActivity(),
                "用户名: " + mUsername.getText().toString() 
                + "   密码: " + mPassword.getText().toString(),Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

MainActivity中拉起 Dialog的按钮

xml布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <Button
        android:id="@+id/login_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点击登录" />

</RelativeLayout>

MainActivity拉起 Dialog弹框代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button loginBtn = (Button) findViewById(R.id.login_btn);
        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LoginDialogFragment fragment = new LoginDialogFragment();
                fragment.show(getFragmentManager(), "login");
            }
        });
    }

}

运行效果

本文分享自微信公众号 - 下码看花(gh_d16267287c27),作者:下码看花

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 这个控件你必须会用!—ListView+GirdView合集

    ListView 列表视图,直接继承了 AbsListView,是一个以垂直方式在项目中显示 View视图的列表。ListView的数据项,来自一个继承了 Li...

    下码看花
  • 常用控件之Button详解

    小伙伴们肯定都有在玩儿一些游戏,比如和平精英,在界面上展示的名字,其实就是Android中咱们上一篇介绍到的TextView控件。而今天,我们再给大家带来一个非...

    下码看花
  • 六大布局之LinearLayout

    Layout——界面布局,为应用程序提供界面架构。控制Activity中控件的大小、位置、颜色等属性的方法.

    下码看花
  • RecyclerView分割线开发技巧

    在上一期通过简单学习,已经领略到了RecyclerView的灵活性,当然都是一些最基础的用法,那么本期一起来学习RecyclerView的分割线使用。 ...

    分享达人秀
  • 安卓自定义列表dialog

    这个形式也是最常用的,不过最近需要用到列表信息Dialog,原生的不光样式不能满足需求,而且是开发电视端的APP,需要对焦点进行特殊处理,所以就需要自定义...

    先知先觉
  • Default Activity Not Found

    方才遇到如标题所述的bug, 也就是点击运行按钮时,AS左下角弹出红色背景对话框, 提示“ Default Activity Not Found ” 基于...

    凌川江雪
  • 日期选择器DatePicker和时间选择器TimePicker

    在实际开发中,经常会遇见一些时间选择器、日期选择器、数字选择器等需求,那么从本期开始来学习Android中常用选择器,今天学习的是DatePicker和...

    分享达人秀
  • 这个控件你必须会用!—ListView+GirdView合集

    ListView 列表视图,直接继承了 AbsListView,是一个以垂直方式在项目中显示 View视图的列表。ListView的数据项,来自一个继承了 Li...

    下码看花
  • Android UI控件系列:LinearLayout(线性布局)

    Android UI控件系列:LinearLayout(线性布局) LinearLayout是在线性方向显示View元素的一个ViewGroup,可以是水平方...

    用户1289394
  • Android学习Tabhost、gallery、listview、imageswitcher

    Tabhost控件又称分页控件,在很多的开发语言中都存在。它可以拥有多个标签页,每个标签页可以拥有不同的内容。android中,一个标签页可以放 一个view或...

    水击三千

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动