使用Builder模式封装Dialog和PopupWindow
来源:互联网 发布:javascript长度函数 编辑:程序博客网 时间:2024/06/05 17:33
转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/75125971
本文出自:【顾林海的博客】
前言
Builder模式的定义是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,也就是说将构建过程和部件的表示隔离开,用户可以在不知道内部构建细节的情况下,对对象的构造流程进行相应的控制,比如在Android中典型的Builder模式就是AlerDialog.Builder类。本篇文章主要采用Builder模式对Dialog和PopupWindow进行相应的封装,像这种用对话框形式来表示的UI,在大部分的APP中都会使用到,因此,良好的封装可以让使用者使用起来比较方便。
Dialog的封装
在封装Dialog时,会使用静态内部类Builder对Diloag的标题、内容、按钮以及事件监听进行配置,并通过CommonDialog类展示,Builder类的结构如下:
可以看出这是很典型的Builder模式,在配置参数时返回的是Builder本身,这样的话可以通过链式调用,使代码的可读性大大提高。由于封装的是Dialog,因此,Builder类会去继承Dialog来自定义Dialog。下面贴出完整的Dialog封装类:
package com.glh.getproject.view;import android.app.Dialog;import android.content.Context;import android.os.Bundle;import android.text.TextUtils;import android.view.Gravity;import android.view.View;import android.view.View.OnClickListener;import android.view.WindowManager;import android.widget.TextView;import com.glh.getproject.R;public class CommonDialog { private Builder mBuilder; private CommonDialog(Builder builder) { this.mBuilder = builder; } public void show() { mBuilder.showDialog(); } public static class Builder extends Dialog implements OnClickListener { private TextView tv_title; private TextView tv_left; private TextView tv_right; private TextView tv_info; private DialogListener mDialogListener; private String title; private String info; private String strLeftBtn; private String strRightBtn; public interface DialogListener { void ok(); void cancel(); } void showDialog() { show(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.dialogl_info_show); initUI(); initEvent(); initViewStatus(); } private void initUI() { tv_title = findViewById(R.id.tv_title); tv_left = findViewById(R.id.tv_left); tv_right = findViewById(R.id.tv_right); tv_info = findViewById(R.id.tv_info); } private void initViewStatus() { if (!TextUtils.isEmpty(title)) { tv_title.setText(title); } if (!TextUtils.isEmpty(info)) { tv_info.setText(info); } if (!TextUtils.isEmpty(strLeftBtn)) { tv_left.setText(strLeftBtn); } else { tv_left.setText("确定"); } if (!TextUtils.isEmpty(strRightBtn)) { tv_right.setText(strRightBtn); } else { tv_right.setText("取消"); } } private void initEvent() { tv_left.setOnClickListener(this); tv_right.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tv_left: if (mDialogListener != null) { dismiss(); mDialogListener.ok(); } break; case R.id.tv_right: if (mDialogListener != null) { dismiss(); mDialogListener.cancel(); } break; default: break; } } public Builder(Context context) { super(context, R.style.MessageBox); setCanceledOnTouchOutside(false); getWindow().setBackgroundDrawableResource(android.R.color.transparent); WindowManager.LayoutParams wl = getWindow().getAttributes(); wl.gravity = Gravity.CENTER; getWindow().setAttributes(wl); } public Builder setListener(DialogListener listener) { this.mDialogListener = listener; return this; } public Builder setTitle(String title) { this.title = title; return this; } public Builder setInfo(String info) { this.info = info; return this; } public Builder setLeftButtonTitle(String title) { this.strLeftBtn = title; return this; } public Builder setRightButtonTitle(String title) { this.strRightBtn = title; return this; } public CommonDialog build() { return new CommonDialog(this); } }}
相关的Style:
<style name="MessageBox"> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:layout_gravity">center</item></style>
layout文件:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/transparent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:background="@drawable/dialog_background_shape" android:paddingLeft="16dp" android:paddingRight="16dp"> <LinearLayout android:id="@+id/ll_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:lineSpacingExtra="2dp" android:textColor="@color/title" android:textSize="17sp" android:visibility="visible" /> <TextView android:id="@+id/tv_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:lineSpacingExtra="2dp" android:paddingTop="20dp" android:textColor="@color/title" android:textSize="17sp" android:visibility="visible" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/ll_title" android:layout_centerHorizontal="true" android:layout_marginTop="25dp" android:gravity="center" android:orientation="horizontal" android:paddingBottom="20dp" android:visibility="visible"> <TextView android:id="@+id/tv_left" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginRight="5dp" android:layout_weight="1" android:background="@drawable/red_button_shape" android:gravity="center" android:paddingBottom="7dp" android:paddingLeft="30dp" android:paddingRight="30dp" android:paddingTop="7dp" android:textColor="@color/white" android:textSize="14sp" android:visibility="visible" /> <TextView android:id="@+id/tv_right" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_weight="1" android:background="@drawable/gray_button_shape" android:gravity="center" android:paddingBottom="7dp" android:paddingLeft="30dp" android:paddingRight="30dp" android:paddingTop="7dp" android:textColor="@color/white" android:textSize="14sp" android:visibility="visible" /> </LinearLayout> </RelativeLayout></RelativeLayout>
整个Dialog的布局背景和按钮都是通过自定义Shape来实现的:
dialog_background_shape:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/white" /> <corners android:radius="10dp" /></shape>
red_button_shape:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="5dp" /> <solid android:color="#FA001F" /></shape>
gray_button_shape:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <corners android:radius="5dp" /> <solid android:color="@color/gray" /></shape>
在Activity中使用:
public void showDialog() { CommonDialog commonDialog = new CommonDialog.Builder(this) .setListener(new CommonDialog.Builder.DialogListener() { @Override public void ok() { Toast.makeText(MainActivity.this, "正在更新...", Toast.LENGTH_SHORT).show(); } @Override public void cancel() { } }).setTitle("更新通知") .setInfo("当前版本暂不可用,请下载最新版本,以便享受优质内容。") .setLeftButtonTitle("知道了") .setRightButtonTitle("不需要") .build(); commonDialog.show();}
PopupWindow的封装
PopupWindow的封装和Dialog的封装是一样的套路,Builder的结构如下:
最后通过PopupWindow的showAtLocation方法显示。
完整的PopupWindow封装代码如下:
package com.glh.getproject.view;import android.content.Context;import android.graphics.drawable.BitmapDrawable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.PopupWindow;import android.widget.TextView;import com.glh.getproject.R;/** * 更新弹框 * Created by glh on 2017-05-09. */public class UpdateDialog { private PopupWindow mPopupWindow; private Builder mBuilder; private UpdateDialog(Builder builder) { this.mBuilder = builder; View mPopupLayout = builder.mPopupLayout; this.mPopupWindow = new PopupWindow(mPopupLayout, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true); this.mPopupWindow.setContentView(mPopupLayout); this.mPopupWindow.setOutsideTouchable(true); this.mPopupWindow.setFocusable(true); this.mPopupWindow.setBackgroundDrawable(new BitmapDrawable()); this.mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { if (mBuilder.mCloseListener != null) { mBuilder.mCloseListener.onClose(); } } }); this.mPopupWindow.update(); } public void dismiss() { if (!mPopupWindow.isShowing()) { return; } mPopupWindow.dismiss(); } public void showAtLocation(View parent, int gravity, int x, int y) { mPopupWindow.showAtLocation(parent, gravity, x, y); } public static class Builder { private View mPopupLayout; private TextView tv_title; private TextView tv_left; private TextView tv_right; private TextView tv_info; private UpgradeListener mUpgradeListener; private CloseListener mCloseListener; private void initEvent() { tv_left.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mUpgradeListener != null) { mUpgradeListener.upgrade(true); } } }); tv_right.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mUpgradeListener != null) { mUpgradeListener.upgrade(false); } } }); } public interface UpgradeListener { void upgrade(boolean upgrade); } public interface CloseListener { void onClose(); } public Builder(Context context) { mPopupLayout = LayoutInflater.from(context).inflate(R.layout.dialogl_info_show, null, true); tv_title = mPopupLayout.findViewById(R.id.tv_title); tv_left = mPopupLayout.findViewById(R.id.tv_left); tv_right = mPopupLayout.findViewById(R.id.tv_right); tv_info = mPopupLayout.findViewById(R.id.tv_info); initEvent(); } public Builder setUpgradeListener(UpgradeListener listener) { this.mUpgradeListener = listener; return this; } public Builder setCloseListener(CloseListener listener) { this.mCloseListener = listener; return this; } public Builder setTitle(String title) { this.tv_title.setText(title); return this; } public Builder setInfo(String info) { this.tv_info.setText(info); return this; } public Builder setLeftButtonTitle(String title) { this.tv_left.setText(title); return this; } public Builder setRightButtonTitle(String title) { this.tv_right.setText(title); return this; } public UpdateDialog build() { return new UpdateDialog(this); } }}
layout文件和Dialog的布局文件一样,这里就不贴出来了。
在Activity的使用:
private UpdateDialog commonDialog;private void showPopupWindow() { if (null == commonDialog) { commonDialog = new UpdateDialog.Builder(this) .setUpgradeListener(new UpdateDialog.Builder.UpgradeListener() { @Override public void upgrade(boolean upgrade) { commonDialog.dismiss(); if (upgrade) { Toast.makeText(MainActivity.this, "正在更新...", Toast.LENGTH_SHORT).show(); } } }).setCloseListener(new UpdateDialog.Builder.CloseListener() { @Override public void onClose() { Toast.makeText(MainActivity.this, "对话框关闭了", Toast.LENGTH_SHORT).show(); } }).setTitle("更新通知") .setInfo("当前版本暂不可用,请下载最新版本,以便享受优质内容。") .setLeftButtonTitle("知道了") .setRightButtonTitle("不需要") .build(); } commonDialog.showAtLocation(mGroup, Gravity.CENTER, 0, 0);}
总结
总的来说相同的方法,不同的执行顺序,产生不同的事件结果时,可以考虑采用建造者模式;多个部件或零件,都可以装配到一个对象中,但产生的运行结果又不相同时,可以考虑采用建造者模式;产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,可以考虑采用建造者模式。
- 使用Builder模式封装Dialog和PopupWindow
- Android自定义弹框Dialog和Popupwindow的封装使用
- Android使用Builder模式自定义Dialog
- 对PopupWindow常用API的简单封装,几行代码就搞定PopupWindow弹窗,使用Builder模式,链式调用,像使用AlertDialog 一样
- Android的Dialog和PopupWindow的使用
- Dialog和Popupwindow
- PopupWindow和Dialog
- 自定义popupwindow和dialog的区别与使用
- popupWindow的封装使用
- dialog和popupwindow和activityDialog
- 使用PopupWindow完成各种dialog
- 笔记41--Dialog和Popupwindow
- Dialog和Popupwindow的区别
- Dialog和PopupWindow的区别
- Android弹出框PopupWindow,Dialog,AlertDialog.Builder,AlertDialog的一知半解
- 模式对话框PopupWindow实现Dialog的功能
- AlertDialog.Builder和Dialog分析
- Android PopupWindow的封装使用
- iOS Widget开发
- JVM 工作原理和流程
- 在线机器学习书籍
- 梳理社招面试以及浅述对程序员职业生涯的看法《转》
- C语言课程设计-教师工作管理系统
- 使用Builder模式封装Dialog和PopupWindow
- centos7 编译安装tensorflow1.2
- jpa nulls last 不起作用
- Java注解(Annotation)详解(四)——注解反射生成SQL语句
- 564. Find the Closest Palindrome
- 省市县三级自身一对一关联的表,联动查询SQL
- HDU
- 移动开发----biu,biu,一个有趣的EditText
- Android源码-高质量开发库