天天看點

自定義dialog (建構者模式打造自定義dialog)有什麼不懂的,或者有好的提議可以添加qq 1075770029,或者加qq群127299409,歡迎大家一起讨論

  • 效果

自定義dialog (建構者模式打造自定義dialog)有什麼不懂的,或者有好的提議可以添加qq 1075770029,或者加qq群127299409,歡迎大家一起讨論
  • 前言

dialog彈窗是Android中一個常用的控件,Android本身提供dialog又不滿足我們的需求

  • dialog的種類

  1. dialog
  2. FragmentDialog
  3. BottomSheetDialog
  4. FragmentBottomSheetDialog

本片文章是用構模組化式打造一個快捷dialog的使用

  • 建構思路

  1. 控件初始化構造
  2. 資料初始化構造
  • 控件初始化構造

這一部分是不會變化的,我門采用建構者模式設定

/dialog的builder類
   public class DialogBuilder {
   //布局id
    private int layoutId;
   //寬高
    private int wight = ViewGroup.LayoutParams.MATCH_PARENT;
    private int height = ViewGroup.LayoutParams.WRAP_CONTENT;
    //動畫
    private int anim;
    //點選外面是否取消
    private boolean canceledOnTouchOutside=true;
    //傳回是否可以取消
    private boolean canceled=true;
   //主題類型
    private int themeRes= R.style.BaseDialog;
    //view的點選時間
    private View.OnClickListener onClickListener;
    //取消監聽
    private DialogInterface.OnDismissListener onDismissListener;
    //onkey監聽
    private DialogInterface.OnKeyListener onKeyListener;

    public DialogBuilder setOnDismissListener(DialogInterface.OnDismissListener onDismissListener) {
        this.onDismissListener = onDismissListener;
        return this;
    }

    public DialogBuilder setOnKeyListener(DialogInterface.OnKeyListener onKeyListener) {
        this.onKeyListener = onKeyListener;
        return this;
    }

    public DialogBuilder setContentView(@LayoutRes int layoutId)
    {
        this.layoutId=layoutId;
        return this;
    }

    public DialogBuilder setWight(int wight) {
        this.wight = wight;
        return this;
    }

    public DialogBuilder setHeight(int height) {
        this.height = height;
        return this;
    }

    public DialogBuilder setAnim(int anim) {
        this.anim = anim;
        return this;
    }

    public DialogBuilder setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
        this.canceledOnTouchOutside = canceledOnTouchOutside;
        return this;
    }

    public DialogBuilder setCanceled(boolean canceled) {
        this.canceled = canceled;
        return this;
    }

    public DialogBuilder setThemeRes(int themeRes) {
        this.themeRes = themeRes;
        return this;
    }

    public DialogBuilder setOnClickListener(View.OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
        return this;
    }

     //建構dialogutils
    public DialogUtils buildDialog(Context context)
    {
        View view = LayoutInflater.from(context).inflate(layoutId!=0?layoutId: R.layout.pure_window_error, null);
        Dialog dialog = new Dialog(context,themeRes);
        dialog.setContentView(view,new ViewGroup.LayoutParams(wight,height));
        dialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
        dialog.setCancelable(canceled);
        if (onDismissListener!=null)
        {
            dialog.setOnDismissListener(onDismissListener);
        }
        if (onKeyListener!=null)
        {
            dialog.setOnKeyListener(onKeyListener);
        }
        Window window = dialog.getWindow();
        if (anim!=0)
        {
            window.setWindowAnimations(anim);
        }
        return new DialogUtils(dialog,window,view,onClickListener);
    }


    //建構BaseDialogUtils
    public BaseDialogUtils buildBottom(Context context)
    {
        View view = LayoutInflater.from(context).inflate(layoutId!=0?layoutId: R.layout.pure_window_error, null);
        BottomSheetDialog dialog = new BottomSheetDialog(context, themeRes);
        dialog.setContentView(view,new ViewGroup.LayoutParams(wight,height));
        dialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
        dialog.setCancelable(canceled);
        if (onDismissListener!=null)
        {
            dialog.setOnDismissListener(onDismissListener);
        }
        if (onKeyListener!=null)
        {
            dialog.setOnKeyListener(onKeyListener);
        }
        if (anim!=0)
        {
            Window window = dialog.getWindow();
            window.setWindowAnimations(anim);
        }
        return new BaseDialogUtils(dialog,view,onClickListener);
    }
}
           

dialogutils

public static DialogBuilder builder()
    {
        return new DialogBuilder();
    }
           

dialog存在螢幕可以設定,或者寬高設定

public class DialogUtils extends BaseDialogUtils<DialogUtils> {

    private Window window;
    public DialogUtils(Dialog dialog, Window window, View view, View.OnClickListener onClickListener) {
        super(dialog,view, onClickListener);
        this.window=window;
    }


    public DialogUtils setSplace(float scaleX, float scaleY)
    {
        return setSplace(scaleX,scaleY,Gravity.NO_GRAVITY);
    }


    public DialogUtils setSplace(float scaleX, float scaleY, int gravity)
    {
        return setSplace(scaleX,scaleY,0,0,gravity);
    }

    public DialogUtils setSplace(float scaleX, float scaleY, int x, int y, int gravity)
    {
        WindowManager.LayoutParams lp = window.getAttributes();
        if (scaleX>0&&scaleX<=1)
        {
            lp.width=(int)(SizeUtils.getScreenWidth()*scaleX);
        }
        if (scaleY>0&&scaleY<=1)
        {
            lp.height=(int)(SizeUtils.getScreenHeight()*scaleY);
        }
        if (x!=0)
        {
            lp.x=x;
        }
        if (y!=0)
        {
            lp.y=y;
        }
        lp.gravity=gravity;
        window.setAttributes(lp);
        return this;
    }

    public DialogUtils setSplace(int width, int height)
    {
        return setSplace(width,height,Gravity.NO_GRAVITY);
    }

    public DialogUtils setSplace(int width, int height, int gravity)
    {
        return setSplace(width,height,0,0,gravity);
    }


    public DialogUtils setSplace(int width, int height, int x, int y, int gravity)
    {
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = width;
        lp.height = height;
        if (x!=0)
        {
            lp.x=x;
        }
        if (x!=0)
        {
            lp.y=y;
        }
        lp.gravity=gravity;
        window.setAttributes(lp);
        return this;
    }


    public static DialogBuilder builder()
    {
       return new DialogBuilder();
    }
}
           

baseDialogUtils

public class BaseDialogUtils<T extends BaseDialogUtils> extends WindowViewUtils<T> {


    private Dialog dialog;
    public BaseDialogUtils(Dialog dialog, View view, View.OnClickListener onClickListener) {
        super(view, onClickListener);
        this.dialog=dialog;
    }

   //顯示
    public void show()
    {
        if (dialog!=null&&!dialog.isShowing());
        {
            dialog.show();
        }
    }


   //隐藏
    public void dismiss()
    {
        if (dialog!=null&&dialog.isShowing())
        {
            dialog.dismiss();
        }
    }


}
           

控件初始化打造基本完成

  • 資料初始化打造

我們拿到view,就可以對view裡面的控件進行對應的複制,或者設定,為了避免多餘findbyid,采用一個view緩存機制

public class WindowViewUtils<T extends WindowViewUtils>{

    private SparseArray<View> sparseArray=new SparseArray<>();
    protected View viewParent;
    protected Context context;
    protected View.OnClickListener onClickListener;


    public WindowViewUtils(View view, View.OnClickListener onClickListener)
    {
        this.viewParent=view;
        this.onClickListener=onClickListener;
    }



    public <V extends View> V fdView(@IdRes int id)
    {
        View view = sparseArray.get(id);
        if (view==null)
        {
            view=viewParent.findViewById(id);
            sparseArray.put(id,view);
        }
        return (V)view;
    }


    /**
     * 設定點選事件
     * @param
     * @return
     */
    public T setClick(@IdRes int ...ids)
    {
        if (onClickListener!=null)
        {
            for(int id:ids)
            {
                fdView(id).setOnClickListener(onClickListener);
            }
        }
        return ((T) this);
    }



    /**
     * TextView
     * @param id
     * @param content
     * @param click
     * @return
     */
    public T setTextView(@IdRes int id,String content,boolean click)
    {
        View view = fdView(id);
        if (view instanceof TextView)
        {
            TextView textView = (TextView) view;
            textView.setText(TextUtils.isEmpty(content)?"":content);
            if (click&&onClickListener!=null)
            {
                textView.setOnClickListener(onClickListener);
            }
        }
        return ((T) this);
    }

    public T setTextView(@IdRes int id, @StringRes int content, boolean click)
    {
        return setTextView(id,context.getResources().getString(content),click);
    }






    /**
     * 設定editview
     * @param id
     * @param content
     * @param hint
     * @return
     */
    public T setEditView(@IdRes int id,String content,boolean hint)
    {
        View view = fdView(id);
        if (view instanceof EditText)
        {
            EditText editText = (EditText) view;
            if (hint)
            {
                editText.setText("");
                editText.setHint(TextUtils.isEmpty(content)?"":content);
            }
            else
            {
                editText.setText(TextUtils.isEmpty(content)?"":content);
            }
        }
        return ((T) this);
    }


    public T setEditView(@IdRes int id,@StringRes int content,boolean hint)
    {
        return setEditView(id,context.getResources().getString(content),hint);
    }








    /**
     * recyclerview
     * @param id
     * @param adapter
     * @param layoutManager
     * @return
     */
    public T setRecyclerView(@IdRes int id, @NonNull RecyclerView.Adapter adapter
            ,@NonNull RecyclerView.LayoutManager layoutManager)
    {
        View view = fdView(id);
        if (view instanceof RecyclerView)
        {
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setAdapter(adapter);
            recyclerView.setLayoutManager(layoutManager);
        }
        return ((T) this);
    }




    /**
     * button
     * @param id
     * @param content
     * @param click
     * @return
     */
    public T setButton(@IdRes int id,String content,boolean click)
    {
        View view = fdView(id);
        if (view instanceof Button)
        {
            Button button = (Button) view;
            button.setText(TextUtils.isEmpty(content)?"":content);
            if (click&&onClickListener!=null)
            {
                button.setOnClickListener(onClickListener);
            }
        }
        return ((T) this);
    }


    public T setButton(@IdRes int id,@StringRes int content,boolean click)
    {
        return setButton(id,context.getResources().getString(content),click);
    }


    /**
     * RadioButton
     * @param id
     * @param content
     * @return
     */
    public T setRadioButton(@IdRes int id,String content)
    {
        View view = fdView(id);
        if (view instanceof RadioButton)
        {
            RadioButton radioButton = (RadioButton) view;
            radioButton.setText(TextUtils.isEmpty(content)?"":content);
        }
        return ((T) this);
    }

    public T setRadioButton(@IdRes int id,@StringRes int content)
    {
        return setRadioButton(id,context.getResources().getString(content));
    }

}
           
  • 其他

整個思想基本完成,由于在activity銷毀的時候dialog還存在系統就會崩潰,是以我寫了一個銷毀方法

public class WindowPureUtils {


    public static void onDialogDestory(BaseDialogUtils...dialogUtils)
    {
        for (BaseDialogUtils dialogUtil:dialogUtils) {
            if (dialogUtil!=null)
            {
                dialogUtil.dismiss();
            }
        }
    }


    public static void onPopupDestory(PopupWindowUtils...popupWindowUtils)
    {
        for (PopupWindowUtils popupWindowUtil:popupWindowUtils) {
            if (popupWindowUtil!=null)
            {
                popupWindowUtil.dismiss();
            }
        }
    }


}
           
  • 使用

//dialog的建立 
dialogOne= DialogUtils.builder()
                            .setContentView(R.layout.dialog_one)
                            .setOnClickListener(this)
                            .setAnim(WindowAnimStyle.left_anim_window)
                            .buildDialog(this)
                            .setTextView(R.id.dialog_content,"純白架構必然是精品",false)
                            .setTextView(R.id.dialog_sure,"确定",true)
                            .setTextView(R.id.dialog_clear,"取消",true)
                            .setSplace(0.8f,0);


//dialog取消或者銷毀

  
    @Override
    protected void onDestroy() {
        super.onDestroy();
        WindowPureUtils.onDialogDestory(dialogOne,dialogTwo);
    }
           

  • 代碼

項目中window檔案中

純白架構

有什麼不懂的,或者有好的提議可以添加qq 1075770029,或者加qq群127299409,歡迎大家一起讨論