打造属于自己的Dialog---仿安卓系统自带原生Dialog设计
来源:互联网 发布:java汽车租赁管理系统 编辑:程序博客网 时间:2024/05/21 18:35
前言:这个过程中遇到了两个问题,都比较基础,第一个问题是:系统无法识别图片资源,不过还好,被我删了之后就很好的运行了,第二个也是比较鬼畜的问题,错把==符号变成了!=结果导致闪退缺不报错!现在我们为什么要来这一个属于自己的dialog,原因很简单,安卓自带的太丑了!!!而且局限性强,那么为了解决这个问题,分开view与逻辑,更方便的进行拓展下面我们需要用一个非常常见的设计模式builder!
buidler设计模式:一个比方——组装电脑,一系列产品的电脑,可以有不同的配置,不同的cpu,不同的arm,一个电脑最后的模样是取决于各个配件的组合,同样的道理,我们在使用dialog的过程中也会有这样那样的需求,因此,1.为了更灵活的去运用dialog,实现更多样化。2.为了易拓展,view与实现逻辑分开!等…
具体需要的类有三个,DialogViewhelper(辅助类存在),AlertDialog,AerltController
1,AerltDialog类:继承了Dialog(值得注意的是这里继承的只是Dialog而非AlertDialog),这里具体的一些思路是,构造函数出来,然后new一个AlertController出来然后,设置一些传递参数用的方法如:setText和getview这些,当然主要的还是builder里面的内容是直接仿安卓源码的,将数据放入P中,然后进行传递!当然这里最好加上一个通过id去寻找的setContextView,同时值得注意的是,无论是文本还是事件不止只有一个,所以用SparseArray储存起来!为什么要使用这个呢,很简单在安卓源码里头,有一句英语表明了如果是键值对为int加值的这种,这个比hasmp更优越!
package com.example.baselibrary.baseActvity.dialog;import android.app.Dialog;import android.content.Context;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.ListView;import com.example.baselibrary.R;/** * Created by 廖成康 on 2017/4/26. */public class AlertDialog extends Dialog{ private AlertController mAlert; public AlertDialog(Context context, int themeResId) { super(context, themeResId); mAlert= new AlertController(this,getWindow()); } /** * 设置文本 * @param ResId * @param text */ public void setText(int ResId,CharSequence text) { mAlert.setText(ResId,text); } /** * 设置getView方法 * @param ResId * @param <T> * @return */ public <T extends View> T getView(int ResId) { return mAlert.getView(ResId); } /** * 设置点击事件 * * @param ResId * @param listener */ public void setOnClickLisnter(int ResId,View.OnClickListener listener) { mAlert.setOnClickLisnter(ResId,listener); } public static class Builder { public final AlertController.AlertParams P; /** * Creates a builder for an alert dialog that uses the default alert * dialog theme. * <p/> * The default alert dialog theme is defined by * {@link android.R.attr#alertDialogTheme} within the parent * {@code context}'s theme. * * @param context the parent context */ public Builder(Context context) { this(context, R.style.dialog); } /** * Creates a builder for an alert dialog that uses an explicit theme * resource. * <p/> * The specified theme resource ({@code themeResId}) is applied on top * of the parent {@code context}'s theme. It may be specified as a * style resource containing a fully-populated theme, such as * {@link android.R.style#Theme_Material_Dialog}, to replace all * attributes in the parent {@code context}'s theme including primary * and accent colors. * <p/> * To preserve attributes such as primary and accent colors, the * {@code themeResId} may instead be specified as an overlay theme such * as {@link android.R.style#ThemeOverlay_Material_Dialog}. This will * override only the window attributes necessary to style the alert * window as a dialog. * <p/> * Alternatively, the {@code themeResId} may be specified as {@code 0} * to use the parent {@code context}'s resolved value for * {@link android.R.attr#alertDialogTheme}. * * @param context the parent context * @param themeResId the resource ID of the theme against which to inflate * this dialog, or {@code 0} to use the parent * {@code context}'s default alert dialog theme */ public Builder(Context context, int themeResId) { P =new AlertController.AlertParams(context,themeResId); } /** * Sets a custom view to be the contents of the alert dialog. * <p/> * When using a pre-Holo theme, if the supplied view is an instance of * a {@link ListView} then the light background will be used. * <p/> * <strong>Note:</strong> To ensure consistent styling, the custom view * should be inflated or constructed using the alert dialog's themed * context obtained via {@link #getContext()}. * * @param view the view to use as the contents of the alert dialog * @return this Builder object to allow for chaining of calls to set * methods */ public Builder setContextView(View view) { P.mView = view; P.mViewLayoutResId = 0; return this; } /** * 设置布局Id * @param ResId * @return */ public Builder setContextView(int ResId){ P.mView=null; P.mViewLayoutResId=ResId; return this; } /** * 设置文本 * @param ResId * @param text * @return */ public Builder setText( int ResId,CharSequence text) { P.mTextArray.put(ResId,text); return this; } /** * 设置点击事件 * @param view * @param listener * @return */ public Builder setOnClickLisnter(int view,View.OnClickListener listener) { P.mClickArray.put(view,listener); return this; } /** * 设置宽度 * @return */ public Builder fullWidth() { P.mWidth= ViewGroup.LayoutParams.MATCH_PARENT; return this; } public Builder fromButton(boolean isAnimation) { if (isAnimation) { P.mAnimations=R.style.dialog_from_bottom_anim; } P.mGrivity= Gravity.BOTTOM; return this; } /** * 设置Dialog的宽高 * @param width * @param height * @return */ public Builder setWidthAndHeight(int width, int height){ P.mWidth = width; P.mHeight = height; return this; } /** * 添加默认动画 * @return */ public Builder addDefaultAnimation(){ P.mAnimations = R.style.dialog_scale_anim; return this; } /** * 设置动画 * @param styleAnimation * @return */ public Builder setAnimations(int styleAnimation){ P.mAnimations = styleAnimation; return this; } /** * Sets whether the dialog is cancelable or not. Default is true. * * @return This Builder object to allow for chaining of calls to set methods */ public Builder setCancelable(boolean cancelable) { P.mCancelable = cancelable; return this; } /** * Sets the callback that will be called if the dialog is canceled. * * <p>Even in a cancelable dialog, the dialog may be dismissed for reasons other than * being canceled or one of the supplied choices being selected. * If you are interested in listening for all cases where the dialog is dismissed * and not just when it is canceled, see * {@link #setOnDismissListener(android.content.DialogInterface.OnDismissListener) setOnDismissListener}.</p> * @see #setCancelable(boolean) * @see #setOnDismissListener(android.content.DialogInterface.OnDismissListener) * * @return This Builder object to allow for chaining of calls to set methods */ public Builder setOnCancelListener(OnCancelListener onCancelListener) { P.mOnCancelListener = onCancelListener; return this; } /** * Sets the callback that will be called when the dialog is dismissed for any reason. * * @return This Builder object to allow for chaining of calls to set methods */ public Builder setOnDismissListener(OnDismissListener onDismissListener) { P.mOnDismissListener = onDismissListener; return this; } /** * Sets the callback that will be called if a key is dispatched to the dialog. * * @return This Builder object to allow for chaining of calls to set methods */ public Builder setOnKeyListener(OnKeyListener onKeyListener) { P.mOnKeyListener = onKeyListener; return this; } /** * Creates an {@link AlertDialog} with the arguments supplied to this * builder. * <p/> * Calling this method does not display the dialog. If no additional * processing is needed, {@link #show()} may be called instead to both * create and display the dialog. */ public AlertDialog create() { // Context has already been wrapped with the appropriate theme. 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; } /** * Creates an {@link AlertDialog} with the arguments supplied to this * builder and immediately displays the dialog. * <p/> * Calling this method is functionally identical to: * <pre> * AlertDialog dialog = builder.create(); * dialog.show(); * </pre> */ public AlertDialog show() { final AlertDialog dialog = create(); dialog.show(); return dialog; } }}
2.AlertContorller:
这个类里面我们是给了一系列参数了的,那么这个类是干什么的呢很简单,传过来的参数传到vieqhelper里面进行实现,当然,在这个过程中,我们需要做一些优化,比如说,我们需要做,一些参数在值上默认,容错等等,这些就不具体将了注视里面相当清楚了,
而我这里主要实现了什么东西呢?1.设置文本,2.设置监听事件,3.配置全屏 从底部弹出,动画等!!
package com.example.baselibrary.baseActvity.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 廖成康 on 2017/4/26. */class AlertController{ private DialogViewHelper mdialogViewHelper; private AlertDialog malertDialog; private Window mwindow; public AlertController(AlertDialog alertDialog, Window window) { this.malertDialog=alertDialog; this.mwindow=window; } public void setMdialogViewHelper(DialogViewHelper dialogViewHelper) { this.mdialogViewHelper=dialogViewHelper; } /*** * * 设置文本 * * 具体实现在DialogViewHelper * * @param resId * @param text */ public void setText(int resId, CharSequence text) { mdialogViewHelper.setText(resId,text); } /** * 设置获取得到View * * @param resId * @param <T> * @return */ public <T extends View> T getView(int resId) { return mdialogViewHelper.getView(resId); } /** * 设置点击事件 * * @param resId * @param listener */ public void setOnClickLisnter(int resId, View.OnClickListener listener) { mdialogViewHelper.setOnClickLisnter(resId,listener); } /** * 获取得到dialog * * @return */ public AlertDialog getMalertDialog() { return malertDialog; } /** * 获取得到window * * * @return */ public Window getMwindow() { return mwindow; } /** * 一个媒介,从AlertDialog里面得到参数 * */ public static class AlertParams { public View mView; //布局的Id public int mViewLayoutResId; ///上下文 public Context mContext; ///主题的Id public int mThemeResId; ///点击空白处是否取消 public boolean mCancelable=true; ///三个参数 public DialogInterface.OnCancelListener mOnCancelListener; public DialogInterface.OnDismissListener mOnDismissListener; public DialogInterface.OnKeyListener mOnKeyListener; // 存放字体的修改 public SparseArray<CharSequence> mTextArray = new SparseArray<>(); // 存放点击事件 public SparseArray<View.OnClickListener> mClickArray = new SparseArray<>(); ///设置宽度 自定义参数 public int mWidth= ViewGroup.LayoutParams.WRAP_CONTENT; //设置位置 自定义参数 public int mGrivity= Gravity.CENTER; //设置高度 自定义参数 public int mHeight=ViewGroup.LayoutParams.WRAP_CONTENT; //设置动画 public int mAnimations=0; public AlertParams(Context context,int mThemeResId) { this.mContext=context; this.mThemeResId=mThemeResId; } public void apply(AlertController mAlert) { ///完善需要设置一些参数 //1.给DialogViewhelper设置view布局 DialogViewHelper viewHelper=null; if (mViewLayoutResId!=0) { viewHelper=new DialogViewHelper(mContext,mViewLayoutResId); } //2.设置view if (mView!=null) { viewHelper=new DialogViewHelper(); viewHelper.setContextView(mView); } //容错处理 if (viewHelper==null) { throw new IllegalArgumentException("还没有设置布局"); } ///继承的是Dialog mAlert.getMalertDialog().setContentView(viewHelper.getmContextView()); ///给辅助类设置viewhelper,对上面传参数有必要 mAlert.setMdialogViewHelper(viewHelper); //2.设置文本 int mtextsize=mTextArray.size(); for (int length=0;length<mtextsize;length++) { mAlert.setText(mTextArray.keyAt(length),mTextArray.valueAt(length)); } ///设置监听事件 int mclicksize=mClickArray.size(); for (int i=0;i<mclicksize;i++) { mAlert.setOnClickLisnter(mClickArray.keyAt(i),mClickArray.valueAt(i)); } ///配置自定义效果 全屏 从底部弹出 动画 Window window=mAlert.getMwindow(); window.setGravity(mGrivity); ///设置懂动画 if (mAnimations!=0) { window.setWindowAnimations(mAnimations); } WindowManager.LayoutParams params=window.getAttributes(); params.width=mWidth; params.height=mHeight; window.setAttributes(params); } }}
3.最后,这个类里面就是我们实现的最后的目的了,这里面有一个叫软应用的,用来防止一些情况的发生所使用的,值得注意一下,
当然这个类并不是说只有它才实现而已,前面的第二个类也已经实现了一些功能,这里的话主要实现的是设置文本和设置点击事件!这两
package com.example.baselibrary.baseActvity.dialog;/** * Created by 廖成康 on 2017/4/26. */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;/** * Dialog 作为View的辅助类 * */class DialogViewHelper{ private View mContextView=null; //// 防止霸气侧漏 private SparseArray<WeakReference<View>> mView; public DialogViewHelper(Context context,int viewId) { this(); mContextView= LayoutInflater.from(context).inflate(viewId,null); } public DialogViewHelper() { mView=new SparseArray<>(); } /** * 设置布局 * @param context */ public void setContextView(View context) { this.mContextView=context; } /** * 获取布局 * */ public View getmContextView() { return mContextView; } public <T extends View> T getView(int viewId) { WeakReference<View> viewWeakReference=mView.get(viewId); //侧漏问题 View view=null; if (viewWeakReference!=null) { view=viewWeakReference.get(); } if (view==null) { view=mContextView.findViewById(viewId); if (view==null) { mView.put(viewId,new WeakReference<View>(view)); } } return (T) view; } /** * 设置文本 * @param resId * @param text */ public void setText(int resId,CharSequence text) { TextView textView=getView(resId); if (textView!=null) { textView.setText(text); } } /** * 设置点击事件 * * @param ResId * @param listener */ public void setOnClickLisnter(int ResId,View.OnClickListener listener) { View view=getView(ResId); if (view!=null) { view.setOnClickListener(listener); } }}
到这里,资源这些的话,如果想要在联系我吧1269729771扣扣号!!!!今天要早睡了
1 0
- 打造属于自己的Dialog---仿安卓系统自带原生Dialog设计
- 打造自己的dialog
- Android系统自带的Dialog
- 打造一个属于自己的BaseActivity(沉浸状态栏,dialog,完全退出程序。应有尽有)
- Dialog弹出框(系统自带)
- Dialog(一)系统自带功能
- Dialog弹出框(系统自带)
- andorid 四种自带的dialog
- 手把手打造属于自己的Linux系统!
- 手把手打造属于自己的Linux系统!
- 丢掉系统自带的矮挫丑Toast吧,打造属于你自己的Toast
- Activity及Dialog的全透明(附android系统自带图标大全)
- Dialog(八)——改变系统自带Dialog字体大小(ContextThemeWrapper)
- 带输入的Dialog
- 定义自己的dialog
- 定义自己的dialog
- 自定义自己的Dialog
- 自定义自己的Dialog
- 中国剩余定理的扩展
- C++ 异常处理机制
- Android与H5互调
- android开源库----可自定义动效的卡片切换视图
- 大型网站应用之海量数据解决方案
- 打造属于自己的Dialog---仿安卓系统自带原生Dialog设计
- Spring的applicationContext.xml的bean 说明
- 【Web前端】:对前端开发模式的思考
- 大型网站应用之高并发情况下的解决方案
- 熄灯之后的学习——再读《MySQL必知必会》(9)|| 创建计算字段
- 姿态解算基础知识(一)
- C/C++十大经典排序算法之希尔排序
- TNS-12560: TNS: 协议适配器错误 Oracle11g 创建数据库中问题处理(必须运行Netca以配置监听程序)
- 【SQL】分组查询