欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 自定义Dialog详细教程

程序员文章站 2022-07-02 19:23:01
...

一、概述

  Dialog可以在当前页面弹出一个对话框,并且它的层级在所有view之上,可以屏蔽掉其它控件的交互能力。Dialog的用处十分广泛,但是由于系统自带的Dialog样式往往不能满足我们特定的需求,所以我们需要对其样式,大小,进出场方式等等多种属性进行自定义。下面我们展示一个自定义了样式、宽高、位置、进出场动画的自定义Dialog效果:
Android 自定义Dialog详细教程

二、实现

  1. Dialog布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_marginTop="3dp"
    android:layout_height="wrap_content">
    <TextView
        android:textSize="20sp"
        android:textColor="#062dda"
        android:layout_weight="1"
        android:layout_marginTop="5dp"
        android:layout_gravity="center"
        android:text="这个是标题"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:textColor="#020101"
        android:layout_weight="2"
        android:layout_margin="5dp"
        android:layout_gravity="left"
        android:text="        这个是我们要展示的内容!可以是列表,可以是按钮,可以是图片。可以是任何你想要的布局!"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <View
        android:layout_margin="5dp"
        android:background="#bfb5b5"
        android:layout_width="match_parent"
        android:layout_height="1dp"/>

    <LinearLayout
        android:layout_weight="1"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:padding="5dp"
            android:background="@drawable/selector_dialog"
            android:id="@+id/tv_sure"
            android:layout_marginLeft="10dp"
            android:gravity="center"
            android:text="确定"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />
        <View
            android:layout_gravity="center"
            android:background="#bfb5b5"
            android:layout_width="1dp"
            android:layout_height="10dp"/>
        <TextView
            android:layout_marginRight="10dp"
            android:background="@drawable/selector_dialog"
            android:id="@+id/tv_cancel"
            android:padding="5dp"
            android:gravity="center"
            android:text="取消"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />
    </LinearLayout>
</LinearLayout>

  这是我们Dialog的布局,它的上部是一个Title,中部显示内容,可以是文字,可以是列表,可以是按钮…自定义布局的用法和我们平时创建布局的方法一样,可以适用于大多数你想要的布局。
2. Activity中的代码

       //引入自定义布局
        View view1 = this.getLayoutInflater().inflate(R.layout.background_dialog, null);
        //自定义的style 在里面进行了圆角背景的设置
        final Dialog dialog = new Dialog(this, R.style.MyDialogStyle);
        dialog.setContentView(view1);
        dialog.show();
        //放在show()之后,不然有些属性是没有效果的,比如height和width
        Window dialogWindow = dialog.getWindow();
        //Dialog 进出场动画
        dialogWindow.setWindowAnimations(R.style.MyDialogAnination);
        WindowManager m = getWindowManager();
        // 获取屏幕宽、高
        Display d = m.getDefaultDisplay();
        // 获取对话框当前的参数值
        WindowManager.LayoutParams p = dialogWindow.getAttributes();
        //设置高度和宽度  高度设置为屏幕的0.3
        p.height = (int) (d.getHeight() * 0.3);
        // 宽度设置为屏幕的0.8
        p.width = (int) (d.getWidth() * 0.8);
        //设置位置
        p.gravity = Gravity.CENTER;
        //下面注掉的代码可以用来设置Dialog透明度
//        p.alpha = 0.5f;
        dialogWindow.setAttributes(p);
        // 设置点击外围解散
        dialog.setCanceledOnTouchOutside(true);
        //自定义布局里面的两个按钮
        TextView mTvSure;
        TextView mTvCancel;
        mTvSure = (TextView) dialog.findViewById(R.id.tv_sure);
        mTvCancel = (TextView) dialog.findViewById(R.id.tv_cancel);
        //按钮点击监听
        mTvCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "点击了取消", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        });
        mTvSure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "点击了确定", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        });

  Dialog的用法很简单,首先通过View view1 = this.getLayoutInflater().inflate(R.layout.background_dialog, null)引入我们的自定义布局,即那个Dialog的布局文件R.layout.background_dialog。然后设置Dialog的样式R.style.MyDialogStyle。该文件位于res文件夹下的values文件夹里面的styles文件中。该自定义样式style的详细内容如下:

<style name="MyDialogStyle" parent="android:Theme.Dialog">
        <!-- 背景颜色及透明程度 -->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 是否半透明 -->
        <item name="android:windowIsTranslucent">true</item>
        <!-- 是否没有标题 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 是否浮现在activity之上 -->
        <item name="android:windowIsFloating">true</item>
        <!-- 是否背景模糊 -->
        <item name="android:backgroundDimEnabled">true</item>
        <!-- 设置背景模糊的透明度-->
        <item name="android:backgroundDimAmount">0.5</item>
        <!--背景 10dp的圆角-->
        <item name="android:background">@drawable/shape_10dp</item>
    </style>

  注意我们的自定义样式要通过继承android:Theme.Dialog来实现我们的自定义效果。我们平常用到的属性大概以上七种,不是必选项。我们可以根据自己的需求进行自己定义。其中android:backgroundDimEnabled可以设置背景模糊,若值为0即可实现PopupWindow的背景部模糊效果。android:backgroundDimAmount可以设置背景模糊的透明度。而android:background实现的就是我们白色背景、10dp圆角、黑色边框的Dialog布局效果。本文所有代码均已上传,不了解怎么实现此布局背景的可以在文末找项目地址进行下载研究。
  设置了样式之后,我们可以通过dialog.show();展示出我们的Dialog了。而且有些效果必须在dialog.show();再设置才可生效。所以最后早一点调用show()方法。之后我们可以设置Dialog的进出场动画R.style.MyDialogAnination,该动画和Dialog样式一样,放在res/values/styles文件下,内容很简单,两个补间动画而已(关于动画的用法,可以参考我的上一篇文章Android开发总结之动画(帧动画+补间动画))。
xml
<style name="MyDialogAnination">
<!--入场动画-->
<item name="android:windowEnterAnimation">@anim/dialog_enter</item>
<!--出场动画-->
<item name="android:windowExitAnimation">@anim/dialog_exit</item>
</style>

  顾名思义,android:windowEnterAnimation即进场动画,android:windowExitAnimation为出场动画。
  上面操作做完之后,如果还需要自定义Dialog的大小,我们可以通过获取屏幕宽高—>设置Dialog与屏幕宽高比例的方法设置Dialog的大小。我一般习惯于把屏幕宽高保存在共享参数中,这样我们可以在任何Activity或者Fragment中随时取用。我们这里设置的Dialog宽度为屏幕的0.8,高度为屏幕的0.3。同样Dialog出现的位置我们也可以自定义,p.gravity = Gravity.CENTER;就是把他设置在了中间位置,当然我们也可以把它设置在屏幕的上下左右各个方向。最后通过dialogWindow.setAttributes(p)使我们的设置生效。当然我们可以设置Dialog点击外部是否可以消失,通过dialog.setCanceledOnTouchOutside(true);即可设置外围解散,如果我们设置为false,那么只有主动调用Dialog的dialog.cancel()或者dialog.dismiss()来让Dialog消失了。至于Dialog里面View的点击监听,正常设置就可以,没有什么特殊要求。

三、后记

  最近公司发生了太多事,所以暂时写一些基础教程来给大家分享。因为最近实在静不下心去层层分析代码分析源码。最后奉劝一句大家,平时一定要多锻炼身体。多运动多健身,健康的身体比什么都重要。所以大家还是尽量多运动吧,为家人、为自己。保护好自己的身体。
github项目地址:https://github.com/tangxuesong6/dialog/