Android Dialog

Android 开发中对话框随处可见,现将自己做过的项目中的Dialog,做出一个系统的总结。从以下方面开始总结:

1.AlertDialog的使用

2.Dialog的使用

3.两者的异同点与使用选择

AlertDialog的使用

在Android源码中,由于AlertDialog被保护起来,没有办法直接new出对象,但是同时提供了一个内部类Builder,可以通过Builder类来实现相应的功能。

AlertDialog.Builder按钮实现

实现一个简单的问卷调查,效果图:

anniu

代码:

 AlertDialog.Builder builder4 = new AlertDialog.Builder(MainActivity.this);
                builder4.setIcon(R.drawable.icon_title);
                builder4.setTitle("问卷调查");
                builder4.setMessage("喜欢我吗?");
                builder4.setPositiveButton("喜欢", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this, "谢谢~", Toast.LENGTH_SHORT).show();
                    }
                });
                builder4.setNegativeButton("特喜欢", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this, "嘿嘿~", Toast.LENGTH_SHORT).show();
                    }
                });
                builder4.setNeutralButton("超喜欢", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this, "嘻嘻~", Toast.LENGTH_SHORT).show();
                    }
                });
                builder4.show();

在Builder类中,提供了setIcon(),setTitle(),setMessage(),setPositiveButton(),setNegativeButton(),setNeutralButton()等方法,供选择。

AlertDialog.Builder列表框实现

效果图:

items

代码:

  final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setIcon(R.drawable.icon_title);
                builder.setTitle("请选择");
                final String[] s2 = new String[]{"1", "2", "3", "4"};
                builder.setItems(s2, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this, s2[i], Toast.LENGTH_SHORT).show();
                    }
                });
                builder.show();

选择一个即可。

AlertDialog.Builder单选框实现

效果图:

单选

代码:

  AlertDialog.Builder builder6 = new AlertDialog.Builder(MainActivity.this);
                builder6.setIcon(R.drawable.icon_title);
                builder6.setTitle("您的性别?");
                final String[] strings2 = new String[]{"男", "女", "人妖", "其他"};
                builder6.setSingleChoiceItems(strings2, 0, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this, strings2[i], Toast.LENGTH_SHORT).show();
                    }
                });
                builder6.show();

通过setSingleChoiceItems()方法实现,单选框。

AlertDialog.Builder复选框实现

效果:

复选框

代码:

  AlertDialog.Builder builder5 = new AlertDialog.Builder(MainActivity.this);
                builder5.setIcon(R.drawable.icon_title);
                builder5.setTitle("喜欢什么运动?");
                final String[] strings = {"篮球", "足球", "乒乓球", "羽毛球"};
                builder5.setMultiChoiceItems(strings, null, new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i, boolean b) {
                        Toast.makeText(MainActivity.this, "我喜欢" + strings[i], Toast.LENGTH_SHORT).show();
                    }
                });
                builder5.show();

复选框通过setMultiChoiceItems()实现。

AlertDialog.Builder自定义布局

AlertDialog实现漂亮的弹出框,就必须自定义布局了,通过setView()方法,设置布局。

一个仿照微信弹出框的效果:
防微信1

java代码:

  AlertDialog.Builder builder2 = new AlertDialog.Builder(MainActivity.this);
                View v2 = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_view, null);
                v2.findViewById(R.id.tv_no_read).setOnClickListener(this);
                v2.findViewById(R.id.tv_top_one).setOnClickListener(this);
                v2.findViewById(R.id.tv_del).setOnClickListener(this);
                builder2.setView(v2);
                AlertDialog alertDialog = builder2.create();
                alertDialog.show();

dialog_view.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="match_parent"
    android:background="@android:color/white"
    android:gravity="center_vertical"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_no_read"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:paddingLeft="15dp"
        android:gravity="center_vertical"
        android:text="标为未读" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@android:color/darker_gray" />

    <TextView
        android:id="@+id/tv_top_one"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:paddingLeft="15dp"
        android:gravity="center_vertical"
        android:text="置顶聊天" />

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@android:color/darker_gray" />

    <TextView
        android:id="@+id/tv_del"
        android:layout_width="match_parent"
        android:paddingLeft="15dp"
        android:layout_height="45dp"
        android:gravity="center_vertical"
        android:text="删除该聊天" />

</LinearLayout>

但是通过效果发现,弹出的Dialog布局的宽度与高度,不是我所想要的,我想要把宽度占据手机屏幕的0.66,这样会更美观些。

效果:

0.66

代码:

  AlertDialog.Builder builder3 = new AlertDialog.Builder(MainActivity.this);
                View v3 = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_view, null);
                v3.findViewById(R.id.tv_no_read).setOnClickListener(this);
                v3.findViewById(R.id.tv_top_one).setOnClickListener(this);
                v3.findViewById(R.id.tv_del).setOnClickListener(this);
                builder3.setView(v3);
                AlertDialog dialog3 = builder3.create();
                // 先调用show()方法,再设置params,才会起作用
                dialog3.show();
                Window window = dialog3.getWindow();
                WindowManager.LayoutParams params = window.getAttributes();
                params.width = (int) (getDisply().widthPixels * 0.66);
                window.setAttributes(params);

这样就美观多了,但是在这里有几点要注意:

  1. 在使用builder对象通过create()方法,拿到的dialog,要在给params参数设置值之前,调用show()方法,不然,参数值是无效的。
  2. dialog通过getWindow()拿到当前的window,再通过window的getAttributes()方法拿到参数,然后给参数赋予相应的数值,最后通过window设置参数。

现在我又有新的需求,要将dialog弹出的位置放在屏幕的左上方,而不是每次都是放在屏幕的中间,并且dialog的透明度设置为0.6。

效果:

left_top

代码:

AlertDialog.Builder builder2 = new AlertDialog.Builder(MainActivity.this);
                View v2 = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_view, null);
                v2.findViewById(R.id.tv_no_read).setOnClickListener(this);
                v2.findViewById(R.id.tv_top_one).setOnClickListener(this);
                v2.findViewById(R.id.tv_del).setOnClickListener(this);
                builder2.setView(v2);
                AlertDialog alertDialog = builder2.create();
                alertDialog.show();
                Window w = alertDialog.getWindow();
                WindowManager.LayoutParams attributes = w.getAttributes();
                w.setGravity(Gravity.LEFT | Gravity.TOP);
                attributes.width = (int) (getDisply().widthPixels * 0.66); // 宽度
                attributes.alpha = 0.6f; // 透明度
                // 当Window的Attributes改变时系统会调用此方法,也可以用setAttributes()
                // alertDialog.onWindowAttributesChanged(attributes);
                w.setAttributes(attributes);

注意:系统默认的Gravity是Gravity.CENTER,所以我们可以根据自己的需要去设置dialog的位置。

由于我们设置了Gravity,dialog的位置得到了改变,但是Gravity设置的位置只是一个大致的位置。要接着改变dialog的位置就需要改变x和y坐标值了。

将上面的dialog,的位置向右偏移100像素,向下偏移100像素:

效果:

100100

代码:

AlertDialog.Builder builder2 = new AlertDialog.Builder(MainActivity.this);
                View v2 = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_view, null);
                v2.findViewById(R.id.tv_no_read).setOnClickListener(this);
                v2.findViewById(R.id.tv_top_one).setOnClickListener(this);
                v2.findViewById(R.id.tv_del).setOnClickListener(this);
                builder2.setView(v2);
                AlertDialog alertDialog = builder2.create();
                alertDialog.show();
                Window w = alertDialog.getWindow();
                WindowManager.LayoutParams attributes = w.getAttributes();
                w.setGravity(Gravity.LEFT | Gravity.TOP);
                attributes.x = 100; // 新位置X坐标
                attributes.y = 100; // 新位置Y坐标
                attributes.width = (int) (getDisply().widthPixels * 0.66); // 宽度
                attributes.alpha = 0.6f; // 透明度
                // 当Window的Attributes改变时系统会调用此方法,也可以用setAttributes()
                // alertDialog.onWindowAttributesChanged(attributes);
                w.setAttributes(attributes);

注意:
x与y表示相对于原始位置的偏移.
当参数值包含Gravity.LEFT时,对话框出现在左边,所以x就表示相对左边的偏移,负值忽略。
当参数值包含Gravity.RIGHT时,对话框出现在右边,所以x就表示相对右边的偏移,负值忽略,以此类推。
当参数值包含Gravity.CENTER_HORIZONTAL时 ,对话框水平居中,所以x就表示在水平居中的位置移动x像素,正值向右移动,负值向左移动。
当参数值包含Gravity.CENTER_VERTICAL时 ,对话框垂直居中,所以y就表示在垂直居中的位置移动y像素,正值向右移动,负值向左移动。

Dialog的使用

Dialog的使用和AlertDialog大致相同,所以就很简单了。

实现防微信Dialog, 效果(带标题):

dialog1

代码:

 Dialog dialog = new Dialog(MainActivity.this);
                dialog.setTitle("操作");
                //设置是否可以点击其他区域取消dialog,默认为 true
                //dialog.setCancelable(false);
                //加载布局
                View v = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_view, null);
                v.findViewById(R.id.tv_no_read).setOnClickListener(this);
                v.findViewById(R.id.tv_top_one).setOnClickListener(this);
                v.findViewById(R.id.tv_del).setOnClickListener(this);
                //只有setContentView()没有setView();
                dialog.setContentView(v);
                dialog.show();

注意:

  1. Dialog默认有title,若去掉title,可以采用自定义Theme的方式
  2. Dialog只有setContentView()方法。
  3. Dialog没有Builder要先create()拿到dialog,就要调show()方法的问题,Dialog在设置完成参数之后再调用show()方法,是没有问题的。

实现Dialog防微信,效果(不带标题):

dialog_no_title

  Dialog dialog = new Dialog(MainActivity.this,R.style.my_dialog);
             //   dialog.setTitle("操作");
                //设置是否可以点击其他区域取消dialog,默认为 true
                //dialog.setCancelable(false);
                //加载布局
                View v = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_view, null);
                v.findViewById(R.id.tv_no_read).setOnClickListener(this);
                v.findViewById(R.id.tv_top_one).setOnClickListener(this);
                v.findViewById(R.id.tv_del).setOnClickListener(this);
                //只有setContentView()没有setView();
                dialog.setContentView(v);
                dialog.show();

my_dialog代码:

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

Dialog的位置大小等属性和AlertDialog是差不多的,就不再罗嗦了。

再附上一个自定义防QQ的Dialog,效果:

qq_menu

MainActivity.java


/**
 * @author zyc
 * created at 2016/4/28 13:55
 */
public class QQDialogActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.qq_dialog);

        init();
    }

    private void init() {
        findViewById(R.id.iv_menu).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        CustomDialogView customDialogView = new CustomDialogView(QQDialogActivity.this, R.style.my_dialog);
        Window win = customDialogView.getWindow();
        WindowManager.LayoutParams p = win.getAttributes();
        win.setGravity(Gravity.RIGHT | Gravity.TOP);
        p.x = 20;//设置x坐标
        p.y = 130;//设置y坐标
        win.setAttributes(p);
        //设置点击Dialog外部任意区域关闭Dialog
        customDialogView.setCanceledOnTouchOutside(true);
        customDialogView.show();
    }
}

CustomDialogView.java

/**
*@author zyc
*created at 2016/4/28 11:36
*/
public class CustomDialogView extends Dialog {

    public CustomDialogView(Context context) {
        super(context);
    }

    public CustomDialogView(Context context, int themeResId) {
        super(context, themeResId);
        setContentView(R.layout.custom_dialog_view);
    }

}

custom_dialog_view.xml

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

    <TextView
        android:id="@+id/tv_build_talk_team"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/icon_title"
        android:gravity="center"
        android:padding="10dp"
        android:text="创建讨论组"
        android:textColor="@android:color/black"></TextView>

    <TextView
        android:id="@+id/tv_add_friend"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/icon_title"
        android:gravity="center"
        android:padding="10dp"
        android:paddingTop="5dp"
        android:text="加好友"
        android:textColor="@android:color/black"></TextView>

    <TextView
        android:id="@+id/tv_scan"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/icon_title"
        android:gravity="center"
        android:padding="10dp"
        android:text="扫一扫"
        android:textColor="@android:color/black"></TextView>

    <TextView
        android:id="@+id/tv_send_to_pc"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/icon_title"
        android:gravity="center"
        android:padding="10dp"
        android:text="发送到电脑"
        android:textColor="@android:color/black"></TextView>

    <TextView
        android:id="@+id/tv_face_to_face"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/icon_title"
        android:gravity="center"
        android:padding="10dp"
        android:text="面对面快传"
        android:textColor="@android:color/black"></TextView>

    <TextView
        android:id="@+id/tv_pay"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/icon_title"
        android:gravity="center"
        android:padding="10dp"
        android:text="付款"
        android:textColor="@android:color/black"></TextView>
</LinearLayout>

3.两者的异同点与使用选择

1 dialog 默认有title,可以setContentView() 没有按钮;
2 builder 默认没有title,有 多按钮、 setSingleChoiceItems()单选框 、setMultiChoiceItems()复选框、 可以setView() 。

Dialog的总结就到这了,干货会持续不断的~~~

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值