Builder模式打造通用Dialog效果
2018-03-08 07:45
375 查看
这是参照系统Dialog,采用Builder模式实现的一个万能dialog效果;
参照系统dialog的方式,涉及到AlertDialog、DialogViewHelper、AlertController这三个类,AlertDialog类中主要提供了一些dialog样式、效果、布局等设置的方法,采用Builder的设计模式,在使用的时候可以采用链式调用;
package com.dialogdemo.dialog; import android.app.Dialog; import android.content.Context; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import com.dialogdemo.R; /** * Created by Administrator on 2017/5/21. * 自定义dialog */ public class AlertDialog extends Dialog { private AlertController mAlert; public AlertDialog(Context context, int themeResId) { super(context, themeResId); mAlert = new AlertController(this, getWindow()); } /** * 设置文本 * * @param viewid * @param text */ public void setText(int viewid, CharSequence text) { mAlert.setText(viewid, text); } public <T extends View> T getView(int viewid) { return mAlert.getView(viewid); } /** * 设置点击 * * @param viewid * @param listener */ public void setOnClickListener(int viewid, View.OnClickListener listener) { mAlert.setOnClickListener(viewid, listener); } public static class Builder { private AlertController.AlertParams P; public Builder(Context context) { this(context, R.style.dialog);//默认样式 } public Builder(Context context, int themeResId) { P = new AlertController.AlertParams(context, themeResId); } public AlertDialog create() { final AlertDialog dialog = new AlertDialog(P.mContext, P.mThemeResId); P.apply(dialog.mAlert); dialog.setCancelable(P.mCancelable); if (P.mCancelable) { dialog.setCanceledOnTouchOutside(true); } dialog.setOnCancelListener(P.mOnCancelListener); dialog.setOnDismissListener(P.mOnDismissListener); if (P.mOnKeyListener != null) { dialog.setOnKeyListener(P.mOnKeyListener); } return dialog; } /** * 设置布局 * * @param v * @return */ public Builder setContentView(View v) { P.mView = v; P.mViewLayoutResId = 0; return this; } /** * 设置布局 * * @param layoutId * @return */ public Builder setContentView(int layoutId) { P.mView = null; P.mViewLayoutResId = layoutId; return this; } /** * 设置文本 * * @param viewId * @param text * @return */ public Builder setText(int viewId, CharSequence text) { P.mTextArray.put(viewId, text); return this; } /** * 设置点击 * * @param view * @param listener * @return */ public Builder setOnClickListener(int view, View.OnClickListener listener) { P.mClickArray.put(view, listener); return this; } //配置一些万能的参数 /** * 全屏 * * @return */ public Builder fullWith() { P.mWith = ViewGroup.LayoutParams.MATCH_PARENT; return this; } /** * 从底部弹出是否有动画 * * @param isAnimation * @return */ public Builder formBottom(boolean isAnimation) { if (isAnimation) { P.mAnimation = R.style.dialog_from_bottom_anim; } P.mGravity = Gravity.BOTTOM; return this; } /** * 设置宽高 * * @param with * @param height * @return */ public Builder setWithAndHeight(int with, int height) { P.mWith = with; P.mHeight = height; return this; } /** * 添加默认动画 * * @return */ public Builder addDefaultAinmation() { P.mAnimation = R.style.dialog_scale_anim; return this; } /** * 添加动画 * * @return */ public Builder setAinmation(int styleAnimation) { P.mAnimation = styleAnimation; return this; } public Builder setOnCancelListener(OnCancelListener onCancelListener) { P.mOnCancelListener = onCancelListener; return this; } public Builder setOnDismissListener(OnDismissListener onDismissListener) { P.mOnDismissListener = onDismissListener; return this; } public Builder setOnKeyListener(OnKeyListener onKeyListener) { P.mOnKeyListener = onKeyListener; return this; } public Builder setCancelable(boolean cancelable) { P.mCancelable = cancelable; return this; } public AlertDialog show() { final AlertDialog dialog = create(); dialog.show(); return dialog; } } }AlertController类是万能dialog效果实现的一个控制类,AlertController类中有提供了一个AlertParams内部类,在AlertParams内部类的apply方法中进行dialog参数的绑定和设置;
package com.dialogdemo.dialog; import android.content.Context; import android.content.DialogInterface; import android.util.SparseArray; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; /** * Created by Administrator on 2017/5/21. */ class AlertController { private AlertDialog mAlertDialog; private Window mWindow; private DialogViewHelper mViewHelper; /** * 获取AlertDialog * * @return */ public AlertDialog getDialog() { return mAlertDialog; } /** * 获取AlertDialog的Window * * @return */ public Window getWindow() { return mWindow; } public AlertController(AlertDialog alertDialog, Window window) { this.mAlertDialog = alertDialog; this.mWindow = window; } public void setViewHelper(DialogViewHelper mViewHelper) { this.mViewHelper = mViewHelper; } /** * 设置文本 * * @param viewid * @param text */ public void setText(int viewid, CharSequence text) { mViewHelper.setText(viewid, text); } public <T extends View> T getView(int viewid) { return mViewHelper.getView(viewid); } /** * 设置点击 * * @param viewid * @param listener */ public void setOnClickListener(int viewid, View.OnClickListener listener) { mViewHelper.setOnClickListener(viewid, listener); } public static class AlertParams { public Context mContext; public int mThemeResId; public boolean mCancelable = true;//点击空白是否可以取消 public DialogInterface.OnCancelListener mOnCancelListener;//AlertDialog取消监听 public DialogInterface.OnDismissListener mOnDismissListener;//AlertDialog消失监听 public DialogInterface.OnKeyListener mOnKeyListener;//AlertDialog消失监听按键监听 public View mView;//显示的布局 public int mViewLayoutResId;//布局id //there can be gaps in the indices. It is intended to be more memory efficient //* than using a HashMap to map Integers to Objects, both because it avoids //存放字体的修改 public SparseArray<CharSequence> mTextArray = new SparseArray<CharSequence>(); //存放点击事件 public SparseArray<View.OnClickListener> mClickArray = new SparseArray<View.OnClickListener>(); //默认宽度 public int mWith = ViewGroup.LayoutParams.WRAP_CONTENT; //动画 public int mAnimation = 0; //位置默认居中 public int mGravity = Gravity.CENTER; //默认高度 public int mHeight = ViewGroup.LayoutParams.WRAP_CONTENT; public AlertParams(Context context, int themeResId) { this.mContext = context; this.mThemeResId = themeResId; } /** * 绑定和设置参数 * * @param mAlert */ public void apply(AlertController mAlert) { //设置参数 //1设置布局 DialogViewHelper viewHelper = null; if (mViewLayoutResId != 0) { viewHelper = new DialogViewHelper(mContext, mViewLayoutResId); } if (mView != null) { viewHelper = new DialogViewHelper(); viewHelper.setContentView(mView); } if (viewHelper == null) { throw new IllegalArgumentException("viewHelper is null"); } //给dialog设置布局 mAlert.getDialog().setContentView(viewHelper.getContentView()); //设置AlertController辅助类 mAlert.setViewHelper(viewHelper); //2设置文本 int mTextSize = mTextArray.size(); for (int i = 0; i < mTextSize; i++) { mAlert.setText(mTextArray.keyAt(i), mTextArray.valueAt(i)); } //3设置点击 int mClickSize = mClickArray.size(); for (int i = 0; i < mClickSize; i++) { mAlert.setOnClickListener(mClickArray.keyAt(i), mClickArray.valueAt(i)); } //4设置自定效果 全屏 从底部弹出 默认动画 Window window = mAlert.getWindow(); //设置位置 window.setGravity(mGravity); //设置动画 if (mAnimation != 0) { window.setWindowAnimations(mAnimation); } //设置宽高 WindowManager.LayoutParams attributes = window.getAttributes(); attributes.width = mWith; attributes.height = mHeight; window.setAttributes(attributes); } } }最后剩下DialogViewHelper类,这个类比较简单,就是一个辅助类,用于布局的实例化加载,布局中view的缓存及设置一些点击事件等;package com.dialogdemo.dialog;
import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import java.lang.ref.WeakReference;
/**
* Created by Administrator on 2017/5/21.
* AlertDialog View 的辅助处理类
*/
class DialogViewHelper {
private View mContentView = null;
//用于缓存布局中的view
private SparseArray<WeakReference<View>> mViews;
public DialogViewHelper(Context mContext, int mViewLayoutResId) {
this();
//实例化解析加载布局文件
mContentView = LayoutInflater.from(mContext).inflate(mViewLayoutResId, null);
}
public DialogViewHelper() {
mViews = new SparseArray<>();
}
/**
* 设置布局
*
* @param contentView
*/
public void setContentView(View contentView) {
this.mContentView = contentView;
}
/**
* 设置文本
*
* @param viewid
* @param text
*/
public void setText(int viewid, CharSequence text) {
TextView tv = getView(viewid);
if (tv != null) {
tv.setText("" + text);
}
}
public <T extends View> T getView(int viewid) {
WeakReference<View> viewWeakReference = mViews.get(viewid);
View view = null;
if (viewWeakReference != null) {
view = viewWeakReference.get();
}
if (view == null) {
view = mContentView.findViewById(viewid);
if (view != null) {
mViews.put(viewid, new WeakReference<View>(view));
}
}
return (T) view;
}
/**
* 设置点击
*
* @param viewid
* @param listener
*/
public void setOnClickListener(int viewid, View.OnClickListener listener) {
View view = getView(viewid);
if (view != null) {
view.setOnClickListener(listener);
}
}
/**
* 获取contentView
*
* @return
*/
public View getContentView() {
return mContentView;
}
}接下来说下简单的调用:private void thridView() {
List<String> list = new ArrayList();
for (int i = 0; i < 5; i++) {
list.add("item" + i);
}
AlertDialog dialog = new AlertDialog.Builder(this)
.setContentView(R.layout.thrid_layout)
.setCancelable(true)
.show();
RecyclerView recyclerView = dialog.getView(R.id.recycler_view);
//设置布局管理器
recyclerView.setLayoutManager(new LinearLayoutManager(this));
DialogListAdapter adapter = new DialogListAdapter(list, this);
recyclerView.setAdapter(adapter);
}这样就实现了dialog列表的效果,是不是感觉调用很简单。源码地址:https://pan.baidu.com/s/1MuJcrcBYLox4dFud_tJ9kg
相关文章推荐
- Android View 高级框架二 Builder模式打造通用对话框
- Android View 高级框架一 Builder模式打造通用TitleBar
- 打造炫酷通用的ViewPager指示器 - Adapter模式适配所有
- Builder设计模式设置自定义Dialog
- 打造自动播放动画,实现PPt模式的效果
- Builder模式 - App内通用弹框
- Android:Dialog对话框、Builder、showDialog、模板方法设计模式
- 打造炫酷通用的ViewPager指示器 - Adapter模式适配所有
- Builder模式设置AlertDialog字体大小、颜色等属性
- AlertDialog 源码分析及Bulider 模式打造万能的dialog
- Builder 模式的变种 类似于AlertDialog
- Builder设计模式 - 构建整个应用的万能Dialog
- Android中AlertDialog, AltertDialog.Builder的基本用法与Builder模式
- 打造通用的AlertDialog
- Android使用Builder模式自定义Dialog
- Builder设计模式 - 构建整个应用的万能Dialog
- 安卓下Builder模式解析+自定义Dialog实战演练
- Builder设计模式之构建万能Dialog
- 使用Builder模式封装Dialog和PopupWindow
- Builder模式设置AlertDialog字体大小、颜色等属性