Android自定义Dialog
来源:互联网 发布:js获取下拉框选中的值 编辑:程序博客网 时间:2024/06/15 14:32
在项目中我们经常需要使用Dialog弹出一些信息告知用户或者指引用户做一些选择性操作。
Android系统提供了Dialog类,以及Dialog的子类,常见如AlertDialog来实现此类功能。但是不足之处有以下几点:
1. 基于Android提供的Dialog及其子类样式单一,风格上与App本身风格可能不太协调;
2. Dialog弹窗在布局和功能上有所限制,不一定能满足实际的业务需求。
基于以上不足所以我们会想自己定义Dialog进行展示,在这篇博文中后面的部分主要是界面方面的内容,有兴趣的博友可以一起探讨一下。下面就介绍我在项目中自定义的Dialog,先展示一下效果吧。
我们通过效果图可以看到这个自定义的对话框是圆角效果,title是喜庆的大红颜色,底部两个按钮一个是确认按钮另一个是取消按钮。风格呢各位博友可以自己根据喜爱进行修改,以下我要开始贴代码了(代码顺序:1.Java代码;2.layout文件;3.调用示例;4.资源文件(color、dimen、drable))
我们的CustomDialog继承自android.app.Dialog,里面通过静态内部类Builder来设置dialog的布局和属性,最后通过Builder来create一个CustomDialog对象,来看实现(代码里面有相应的注释)
package cn.dai.com.widget;import android.app.Dialog;import android.content.Context;import android.content.DialogInterface;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup.LayoutParams;import android.widget.Button;import android.widget.LinearLayout;import android.widget.TextView;import cn.dai.com.R;/********************************************************* * @类描述: 自定义dialog * @创建人: daizhenhong * @创建时间:2016-3-18 上午9:35:22 ***************************************************************************/public class CustomDialog extends Dialog { public CustomDialog(Context context) { super(context); } public CustomDialog(Context context, int theme) { super(context, theme); } public CustomDialog setCloseOnTouchOutside(boolean flag) { this.setCanceledOnTouchOutside(flag); return this; } public static class Builder { private Context context; private String title; private String message; private String positiveButtonText; private String negativeButtonText; private View contentView; /** 默认点击对话框外部可以关闭*/ private boolean enableCloseoutside = true; /** 默认点击back键可以关闭对话框*/ private boolean enableCloseBackKey = true; /** 默认可以取消*/ private boolean cancelable = true; private DialogInterface.OnClickListener positiveButtonClickListener; private DialogInterface.OnClickListener negativeButtonClickListener; public Builder(Context context) { this.context = context; } public Builder setMessage(String message) { this.message = message; return this; } /** * Set the Dialog message from resource * * @param title * @return */ public Builder setMessage(int message) { this.message = (String) context.getText(message); return this; } /** * Set the Dialog title from resource * * @param title * @return */ public Builder setTitle(int title) { this.title = (String) context.getText(title); return this; } /** * Set the Dialog title from String * * @param title * @return */ public Builder setTitle(String title) { this.title = title; return this; } public Builder setContentView(View v) { this.contentView = v; return this; } /** * Set the positive button resource and it's listener * * @param positiveButtonText * @return */ public Builder setPositiveButton(int positiveButtonText, DialogInterface.OnClickListener listener) { this.positiveButtonText = (String) context.getText(positiveButtonText); this.positiveButtonClickListener = listener; return this; } public Builder setPositiveButton(String positiveButtonText, DialogInterface.OnClickListener listener) { this.positiveButtonText = positiveButtonText; this.positiveButtonClickListener = listener; return this; } public Builder setNegativeButton(int negativeButtonText, DialogInterface.OnClickListener listener) { this.negativeButtonText = (String) context.getText(negativeButtonText); this.negativeButtonClickListener = listener; return this; } public Builder setNegativeButton(String negativeButtonText, DialogInterface.OnClickListener listener) { this.negativeButtonText = negativeButtonText; this.negativeButtonClickListener = listener; return this; } public Builder setCloseOnTouchOutside(boolean cancel) { enableCloseoutside = cancel; return this; } public Builder enableCloseOnBackKey(boolean enable) { enableCloseBackKey = enable; return this; } public Builder setCancelable(boolean cancel) { cancelable = cancel; return this; } public CustomDialog create() { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // instantiate the dialog with the custom Theme final CustomDialog dialog = new CustomDialog(context, R.style.Dialog); // 装载自定义的布局文件dialog_normal.xml View layout = inflater.inflate(R.layout.dialog_normal, null); dialog.addContentView(layout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); // set the dialog title ((TextView) layout.findViewById(R.id.title)).setText(title); // set the confirm button if (positiveButtonText != null) { ((Button) layout.findViewById(R.id.positiveButton)).setText(positiveButtonText); if (positiveButtonClickListener != null) { ((Button) layout.findViewById(R.id.positiveButton)).setOnClickListener(new View.OnClickListener() { public void onClick(View v) { positiveButtonClickListener.onClick(dialog, DialogInterface.BUTTON_POSITIVE); } }); } } else { // if no confirm button just set the visibility to GONE layout.findViewById(R.id.positiveButton).setVisibility(View.GONE); } // set the cancel button if (negativeButtonText != null) { ((Button) layout.findViewById(R.id.negativeButton)).setText(negativeButtonText); if (negativeButtonClickListener != null) { ((Button) layout.findViewById(R.id.negativeButton)).setOnClickListener(new View.OnClickListener() { public void onClick(View v) { negativeButtonClickListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE); } }); } } else { // if no confirm button just set the visibility to GONE layout.findViewById(R.id.negativeButton).setVisibility(View.GONE); } // set the content message if (message != null) { ((TextView) layout.findViewById(R.id.message)).setText(message); } //如果通过setContentView设置了自定义的View布局,则将默认的内容控件移除,并添加设置的contentView(保持内容显示的灵活性,同时保留自定义Dialog头部和底部按钮的样式风格不变) if (contentView != null) { // if no message set // add the contentView to the dialog body ((LinearLayout) layout.findViewById(R.id.content)).removeAllViews(); ((LinearLayout) layout.findViewById(R.id.content)).addView(contentView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); } // set closeOnTouchOutside dialog.setCanceledOnTouchOutside(enableCloseoutside); dialog.setCancelable(cancelable); dialog.setContentView(layout); if (!enableCloseBackKey) dialog.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) return true; return false; } }); return dialog; } }}
以上就是java代码段了,然后就是layout文件,其中会引用多个资源文件,需要先把资源文件添加到项目中。
<?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="wrap_content" android:layout_gravity="center" android:background="@drawable/bg_dialog_layout" android:orientation="vertical" > <TextView android:id="@+id/title" style="@style/text_18_ffffff" android:layout_width="match_parent" android:layout_height="45dp" android:background="@drawable/bg_dialog_top" android:gravity="center" android:text="提示" android:visibility="visible" /> <ScrollView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:minHeight="120dp" > <LinearLayout android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="120dp" android:background="@color/white" android:gravity="center" > <TextView android:id="@+id/message" style="@style/text_16_666666" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="left|center" android:lineSpacingMultiplier="1.5" android:minHeight="120dp" android:paddingBottom="15dp" android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingTop="15dp" /> </LinearLayout> </ScrollView> <View android:layout_width="match_parent" android:layout_height="1.0px" android:background="#ffd0d0d0" /> <LinearLayout android:layout_width="match_parent" android:layout_height="60dp" android:layout_gravity="bottom" android:gravity="center" android:orientation="horizontal" > <Button android:id="@+id/negativeButton" style="@style/text_15_666666_sdw" android:layout_width="114dp" android:layout_height="40dp" android:layout_margin="10dp" android:background="@drawable/bg_btn_negetive" android:gravity="center" android:text="取    消" /> <Button android:id="@+id/positiveButton" style="@style/text_15_ffffff_sdw" android:layout_width="114dp" android:layout_height="40dp" android:layout_margin="10dp" android:background="@drawable/bg_btn_position" android:gravity="center" android:text="确    定" /> </LinearLayout></LinearLayout>
调用示例:
public void showDialog() { CustomDialog dialog = null; CustomDialog.Builder builder = new CustomDialog.Builder(mContext); builder.setTitle("应用更新"); builder.setMessage("当前是最新版本不需更新!"); builder.setPositiveButton("现在更新", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO 处理点击确定的事件 dialog.dismiss(); } }); builder.setNegativeButton("下次再说", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO 处理点击取消的事件 dialog.dismiss(); } }); //这里可以自定义一个布局文件,并将自定义的布局文件覆盖对话框的内容区域 // View view = getUpgradeContentView(bean); // builder.setContentView(view); // 设置点击back键dialog不消失 // builder.enableCloseOnBackKey(false); dialog = builder.create(); dialog.setCloseOnTouchOutside(false); dialog.show(); }
1.colors文件,这个颜色文件需要我们添加到values文件夹的colors.xml文件中
<?xml version="1.0" encoding="utf-8"?><resources><!-- 应用头部背景颜色 --> <color name="bg_head">#e51c23</color> <!-- 应用面板背景颜色 --> <color name="bg_app_panel">#f5f0f5</color> <color name="bg_app_content">#ffffff</color> <!-- 应用中积极响应的按钮颜色色值 --> <color name="bg_button_positive_nomal">#e51c23</color> <color name="bg_button_positive_pressed">#a00303</color> <color name="bg_button_positive_disenable">#999999</color> <!-- 应用中按钮边框色值 --> <color name="bg_button_stroke">#ffffff</color> </resources>
2.dimens文件,添加到values文件夹中的dimens.xml中
<?xml version="1.0" encoding="utf-8"?><resources> <!-- 应用text默认字体大小 --> <dimen name="text_default_size">16sp</dimen> <!-- 自定义对话框 --> <dimen name="dialog_corner_size">10dp</dimen> <dimen name="dialog_btn_corner_size">5dp</dimen></resources>
3.drable文件,进行dialog边框以及背景的设置
1. bg_btn_negetive.xml 取消按钮的背景设置
<?xml version="1.0" encoding="UTF-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"><shape> <solid android:color="@android:color/darker_gray" /> <corners android:radius="@dimen/dialog_btn_corner_size" /> <stroke android:width="1dp" android:color="@android:color/darker_gray" /> </shape></item> <item android:state_enabled="true"><shape android:shape="rectangle"> <solid android:color="@android:color/white" /> <corners android:radius="@dimen/dialog_btn_corner_size" /> <stroke android:width="1dp" android:color="@android:color/darker_gray" /> </shape></item></selector>
2. bg_btn_position.xml 确定按钮的背景设置
<?xml version="1.0" encoding="UTF-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 按钮被点击 --> <item android:state_pressed="true"><shape> <solid android:color="@color/bg_button_positive_pressed" /> <corners android:radius="@dimen/dialog_btn_corner_size" /> <stroke android:width="1dp" android:color="@color/bg_button_stroke" /> </shape></item> <!-- 按钮可以点击 --> <item android:state_enabled="true"><shape> <solid android:color="@color/bg_button_positive_nomal" /> <corners android:radius="@dimen/dialog_btn_corner_size" /> </shape></item> <!-- 按钮不可点击 --> <item android:state_enabled="false"><shape> <solid android:color="@android:color/darker_gray" /> <corners android:radius="@dimen/dialog_btn_corner_size" /> </shape></item></selector>
3. bg_dialog_layout.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" > <corners android:radius="@dimen/dialog_corner_size" /> <solid android:color="@color/bg_app_panel" /></shape>
4. bg_dialog_bottom.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" > <corners android:bottomLeftRadius="@dimen/dialog_corner_size"android:bottomRightRadius="@dimen/dialog_corner_size" /></shape>
5. bg_dialog_top.xml
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" > <corners android:topLeftRadius="@dimen/dialog_corner_size" android:topRightRadius="@dimen/dialog_corner_size"/> <solid android:color="@color/bg_head" /></shape>
- styles文件,将以下style添加到styles.xml文件中
<style name="text_16_666666"> <item name="android:textSize">16.0dip</item> <item name="android:textColor">#ff666666</item> </style> <style name="text_15_666666_sdw" parent="@style/sdw_white"> <item name="android:textSize">15.0dip</item> <item name="android:textColor">#ff666666</item> </style> <style name="Dialog" parent="android:style/Theme.Dialog"> <item name="android:background">#00000000</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> </style>
以上主要就是资源文件了,切记先把资源文件导入后在导入layout文件,最后才导入java代码。
谨以此文记录关于自定义Dialog的路程
- 自定义Dialog android Dialog
- 【Android】Dialog以及自定义Dialog
- android 系统Dialog,自定义Dialog
- android 自定义dialog 自定义dialog 宽度问题
- Android 自定义 dialog
- Android 自定义 dialog
- Android 自定义 dialog
- Android 自定义Dialog分类
- Android Dialog( 自定义对话框)
- Android自定义Dialog
- Android-自定义Dialog样式
- Android 自定义Dialog样式
- Android:自定义dialog
- Android 自定义dialog
- Android自定义Dialog对话框
- Android 自定义dialog
- Android自定义Dialog
- Android自定义Dialog
- 线上课堂目录
- 洛谷 P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…
- leetcode刷题系列--152. Maximum Product Subarray
- java并发编程--ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue
- Android 导入so包后,报java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader
- Android自定义Dialog
- spring-mvc过滤器
- android -日志框架
- ios afnetworking如何往服务器提交图片
- iOS Cocoapods 安装 使用
- Linux中dd命令详解
- SURF与SIFT比较
- 7段实用代码
- CentOS安装zip unzip命令