1. 程式人生 > >Dialog顯示載入中

Dialog顯示載入中

移動端的的網路情況有的時候是很不穩定的(在地下室額,氣死人)或是使用某些運營商的SIM卡,有的時候進出地鐵就會沒訊號,所以造成資料載入很慢,假如我們沒有對這塊做處理,App的使用者就會很煩躁(一般不超過5秒),所以就有了當在載入資料的時候,顯示一個正在載入,會讓使用者的情緒得到一定的緩解。

這個哥們的Dialog就寫的不錯,這個dialog是仿ios的載入彈窗 ,以下是原作者的地址及使用:
原作者的專案地址

1、專案下的build.gradle新增
allprojects {
repositories {

maven { url ‘https://www.jitpack.io’ }
}
}

2、模組下的build.gradle新增依賴
dependencies {
compile ‘com.github.gittjy:LoadingDialog:1.0.2’
}

3、在程式碼中使用
LoadingDailog.Builder loadBuilder=new LoadingDailog.Builder(this)
.setMessage(“載入中…”)
.setCancelable(true)
.setCancelOutside(true);
LoadingDailog dialog=loadBuilder.create();
dialog.show();

不過由於Dialog的特殊性,不需要和Activity attach,所以我把這個dialog封裝到了一個utils中了,程式碼如下:

public class Utils {
    private static LoadingDialog.Builder loadBuilder;
    private static  LoadingDialog loadingDialog;
	    /**
	     * 顯示載入中對話方塊
	     */
	     
	    public static void showLoadingDialog(Context context) {
	        loadBuilder =  new LoadingDialog.Builder(context).setMessage("載入資料中...")
	                .setCancelable(false)
	                .setCancelOutside(false);
	        loadingDialog = loadBuilder.create();
	        if (loadingDialog != null && context != null) {
	            loadingDialog.show();
	        }
	    }
	    /**
	     * 關閉載入對話方塊
	     */
	    public static void closeLoadingDialog() {
	        if (loadingDialog != null) {
	            loadingDialog.dismiss();
	        }
	        loadingDialog = null;
	    }
   

在需要使用Dialog的地方使用Utils.showLoadingDialog(context),在需要關閉的地方使用Utils.closeLoadingDialog()。這樣可以再大多數的場合使用了,但是當這個dialog開啟後,你使用任何別的辦法是關閉不了的,除非這個Dialog唄呼叫了Utils.closeLoadingDialog()。當我在網路請求中使用這個的時候,由於網路並不好,那畫面就剩下這個載入中…當時點選空白處消失不了,點選物理鍵返回不好使。這就讓我鬱悶了…(容我悲傷逆流成河吧…)。當網路不好的時候,我不想等待了,就直接把這個Activity結束掉(不用再等待這個無奈的返回結果了),所以我對這個Dialog進行了二次的開發。重新寫一個class,繼承於LoadingDailog(其實可以把原作者的這個類拷貝一份,重新寫下),加一個對物理返回鍵的監聽(本著編寫一次程式碼,可以到處執行的精神,我把這個方法加在了這個類中,讓這個Dialog進行管理),程式碼如下:
setListener()這個方法是加在你繼承於LoadingDailog這個類中的

 public void setListener() {
        setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    if (dialog != null)
                        dialog.dismiss();
                    if (context != null) {
                        Activity activity = (Activity) context;
                        activity.finish();
                    }
                }
                return false;
            }
        });
    }

呼叫還是依舊只不過是在showLoadingDialog()方法中新增一個 loadingDialog.setListener()就可以了。
loadingDialog1.setListener();這句程式碼是重點。
程式碼如下:
LoadingDialog1是我繼承於LoadingDialog這個類的

public static void showLoadingDialog(Context context) {
        loadBuilder =  new LoadingDialog1.Builder(context).setMessage("載入資料中...")
                .setCancelable(false)
                .setCancelOutside(false);
        loadingDialog1 = loadBuilder.create();
        if (loadingDialog1 != null && context != null) {
            loadingDialog1.setListener();
            loadingDialog1.show();
        }
    }

完整程式碼如下:

public class LoadingDialog1 extends LoadingDailog {
    private Context context;

    public LoadingDialog1(Context context) {
        super(context);
        this.context = context;
    }

    public LoadingDialog1(Context context, int themeResId) {
        super(context, themeResId);
        this.context = context;
    }

    public static class Builder {
        private Context context;
        private String message;
        private boolean isShowMessage = true;
        private boolean isCancelable = false;
        private boolean isCancelOutside = false;

        public Builder(Context context) {
            this.context = context;
        }

        public LoadingDialog1.Builder setMessage(String message) {
            this.message = message;
            return this;
        }

        public LoadingDialog1.Builder setShowMessage(boolean isShowMessage) {
            this.isShowMessage = isShowMessage;
            return this;
        }

        public LoadingDialog1.Builder setCancelable(boolean isCancelable) {
            this.isCancelable = isCancelable;
            return this;
        }

        public LoadingDialog1.Builder setCancelOutside(boolean isCancelOutside) {
            this.isCancelOutside = isCancelOutside;
            return this;
        }
	    //這個layout是使用了原作者的了
        public LoadingDialog1 create() {
            LayoutInflater inflater = LayoutInflater.from(this.context);
            View view = inflater.inflate(com.android.tu.loadingdialog.R.layout.dialog_loading, (ViewGroup) null);
            LoadingDialog1 loadingDialog1 = new LoadingDialog1(this.context,
                    com.android.tu.loadingdialog.R.style.MyDialogStyle);
            TextView msgText = (TextView) view.findViewById(com.android.tu.loadingdialog.R.id.tipTextView);
            if (this.isShowMessage) {
                msgText.setText(this.message);
            } else {
                msgText.setVisibility(View.VISIBLE);
            }

            loadingDialog1.setContentView(view);
            loadingDialog1.setCancelable(this.isCancelable);
            loadingDialog1.setCanceledOnTouchOutside(this.isCancelOutside);
            return loadingDialog1;
        }
    }

    public void setListener() {
        setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    if (dialog != null)
                        dialog.dismiss();
                    if (context != null) {
                        Activity activity = (Activity) context;
                        activity.finish();
                    }
                }
                return false;
            }
        });
    }
}

**

後記:

**
但是這種寫在utils中的做法是不好的(1,有記憶體洩漏的危險;2,經常找不到activity,由於dialog的執行時繫結到activity中的),經過線上執行,發現經常是dialog繫結不到decorview上。所以想了想還是把這個dialog寫在BaseActivity中的比較好。