Android 自定义Dialog详细教程
一、概述
Dialog可以在当前页面弹出一个对话框,并且它的层级在所有view之上,可以屏蔽掉其它控件的交互能力。Dialog的用处十分广泛,但是由于系统自带的Dialog样式往往不能满足我们特定的需求,所以我们需要对其样式,大小,进出场方式等等多种属性进行自定义。下面我们展示一个自定义了样式、宽高、位置、进出场动画的自定义Dialog效果:
二、实现
- 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/
下一篇: Vue和React代码检测工具
推荐阅读
-
Android自定义控件属性详细介绍
-
Android 自定义dialog的实现代码
-
MacBook自定义Dock桌面图标位置的详细教程
-
Android编程自定义对话框(Dialog)位置及大小的方法
-
Android自定义弹出框dialog效果
-
Android进阶教程之ViewGroup自定义布局
-
Android 去掉自定义dialog的白色边框的简单方法
-
Android中自定义对话框(Dialog)的实例代码
-
Android 中自定义Dialog样式的Activity点击空白处隐藏软键盘功能(dialog不消失)
-
Android studio创建多语言ResouuceBundle文件的详细教程