Android 自定义Dialog详细教程

一、概述

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

二、实现

  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
        
        "android:windowIsTranslucent">true
        
        "android:windowNoTitle">true
        
        "android:windowIsFloating">true
        
        "android:backgroundDimEnabled">true
        
        "android:backgroundDimAmount">0.5
        
        "android:background">@drawable/shape_10dp
    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


  顾名思义,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/

你可能感兴趣的:(android开发)