前言:這個過程中遇到了兩個問題,都比較基礎,第一個問題是:系統無法識別圖片資源,不過還好,被我刪了之后就很好的運行了,第二個也是比較鬼畜的問題,錯把==符號變成了!=結果導致閃退缺不報錯!現在我們為什么要來這一個屬于自己的dialog,原因很簡單,安卓自帶的太丑了!!!而且局限性強,那么為了解決這個問題,分開view與邏輯,更方便的進行拓展下面我們需要用一個非常常見的設計模式builder!
buidler設計模式:一個比方——組裝電腦,一系列產品的電腦,可以有不同的配置,不同的cpu,不同的arm,一個電腦最后的模樣是取決于各個配件的組合,同樣的道理,我們在使用dialog的過程中也會有這樣那樣的需求,因此,1.為了更靈活的去運用dialog,實現更多樣化。2.為了易拓展,view與實現邏輯分開!等…
具體需要的類有三個,DialogViewhelper(輔助類存在),AlertDialog,AerltController
下面簡單來介紹一下這三個類吧,先從AlertDialog介紹起,為什么從這個介紹起呢,因為如果你來寫,也會從這里寫起,主要思路是先用AlertDialog來講我們所所需要的,參數傳遞進來,當然它也是這個的入口,然后是AlertController這個用來傳遞參數,到最后,用DialogViewhelper進行最終的實現,當然如果你不想寫那個輔助類也行下面簡單來介紹一下這三個類吧,先從AlertDialog介紹起,為什么從這個介紹起呢,因為如果你來寫,也會從這里寫起,主要思路是先用AlertDialog來講我們所所需要的,參數傳遞進來,當然它也是這個的入口,然后是AlertController這個用來傳遞參數,到最后,用DialogViewhelper進行最終的實現,當然如果你不想寫那個輔助類也行
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
* @return
*/
?public 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.
? ? *
* 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.
? ? *
* 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.
? ? *
* 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.
? ? *
* 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.
? ? *
* When using a pre-Holo theme, if the supplied view is an instance of
* a {@link ListView} then the light background will be used.
? ? *
* Note:<4> 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.
? ? *
? ? *
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}.
* @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.
? ? *
? ? * 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.
? ? *
* Calling this method is functionally identical to:
? ? *
* ? AlertDialog dialog = builder.create();
* ? dialog.show();
*
*/
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
* @return
*/
?public 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 mTextArray = new SparseArray<>();
? ?// 存放點擊事件
? ?public SparseArray 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
? ? ?{
? ? ? mAlert.setText(mTextArray.keyAt(length),mTextArray.valueAt(length));
? ? ?}
? ? ?///設置監聽事件
? ? ?int mclicksize=mClickArray.size();
? ? ?for (int i=0;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> 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 getView(int viewId)
? ?{
? ? ?WeakReference 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));
? ? ? ?}
? ? ?}
? ? ?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扣扣號!!!!今天要早睡了,寫在簡書強,有些東西可能不太清楚,莫怪了哈!!