目錄
前言
之前寫過一篇《Android自定義通用的Dialog》,最近在整理文章時看到了,發現代碼其實可以簡化一下,所以本篇也是寫一個通用的Dialog,但是我們會對代碼做進一步的封裝,讓我們的代碼邏輯看起來更加簡潔清晰,好了,話不多說,一起來動手實現吧!
一、自定義DialogView
封裝思路:既然是封裝Dialog,那麼我們肯定是首先要考慮它的通用性,而不是每種不同的Dialog我們都要單獨寫一個類,在裏面定義它的方法,我們儘量要做到能夠統一管理,所以這裏我們考慮當UI改變時,我們只去替換xml佈局文件即可,對於主題樣式的展示我們使用統一定義的類。再一個就是Dialog的顯示位置,我們這裏考慮可能不同的需求需要顯示在屏幕的不同位置,所以這裏我們也考慮做到動態傳入。那麼基於這個大致的思路,我們來寫一個類繼承自系統的Dialog:
import android.app.Dialog;
import android.content.Context;
import android.view.Window;
import android.view.WindowManager;
/**
* 作者:created by Jarchie
* 時間:2019-11-12 21:24:08
* 郵箱:[email protected]
* 說明:自定義提示框
*/
public class DialogView extends Dialog {
public DialogView(Context context,int layout, int style,int gravity) {
super(context, style);
setContentView(layout);
Window window = getWindow();
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.gravity = gravity;
window.setAttributes(layoutParams);
}
}
對於它的構造參數我們不用全部都實現,因爲我們需要使用它的透明主題,所以這裏我使用了它的兩個參數的構造方法,super是調用了它父類的構造方法,兩個參數很明顯context和style,然後我們根據上面最開始的思路,我們再定義我們自己需要的參數,從代碼中可以看到那就是我們的layout佈局文件和gravity它的顯示位置,因爲這裏是調用了super,所以這裏我們自己的參數想怎樣傳都是可以的,你也可以繼續增加你需要的參數都是OK的,因爲父類的構造參數一定是會調用的。然後下面就是對方法內部的代碼做一個簡要的說明,都是大家很熟悉的東西了:
setContentView(layout):傳入layout設置我們的佈局;
getWindow():拿到它的父容器,爲下面做改變主題打基礎;
window.getAttributes():拿到window對象的屬性,返回的是一個LayoutParams;
layoutParams.width&layoutParams.height:設置它的寬和高,layoutParams.gravity是設置它的位置,使我們傳入的參數;
window.setAttributes:把屬性設置回去,這樣我們的簡單的自定義就完成了。
二、自定義Dialog管理類
這裏我們定義了一個類用來管理我們所有的Dialog,也就是第一步中我們所創建的DialogView,所以我這裏使用了單例模式進行創建,保證管理類實例唯一性。
既然是管理所有的Dialog,所以我們需要給它一些通用的方法,比如:初始化、顯示隱藏等,所以我們定義幾個方法:
initView():初始化Dialog,這裏直接返回一個DialogView的實例,構造方法中傳入的是DialogView的構造方法需要的參數,這裏主題我們在values下的style文件裏面定義了一個,內容也比較簡單:背景透明無標題,代碼如下:
<!--DialogView Theme Style-->
<style name="Theme_Dialog" parent="Theme.AppCompat.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="windowNoTitle">true</item>
</style>
然後我們重載一個方法,給了一個默認的居中顯示的位置,方便大多數情況下居中顯示的需求處理,所以對於居中顯示的可以直接調用我們的兩個參數的構造方法即可。
show():定義顯示Dialog的方法,判斷是否正在顯示,不是正在顯示的情況下才顯示。
hide():定義隱藏Dialog的方法,判斷是否正在顯示,正在顯示的情況下才隱藏。
具體的代碼如下所示:
import android.content.Context;
import android.view.Gravity;
import com.jarchie.resizeitem.R;
import com.jarchie.resizeitem.view.DialogView;
/**
* 作者:created by Jarchie
* 時間:2019-11-12 21:28:58
* 郵箱:[email protected]
* 說明:提示框管理類
*/
public class DialogManager {
//單例模式
private static volatile DialogManager mInstance = null;
private DialogManager() {
}
public static DialogManager getInstance() {
if (mInstance == null) {
synchronized (DialogManager.class) {
if (mInstance == null) {
mInstance = new DialogManager();
}
}
}
return mInstance;
}
public DialogView initView(Context mContext, int layout) {
return new DialogView(mContext, layout, R.style.Theme_Dialog, Gravity.CENTER);
}
public DialogView initView(Context mContext, int layout, int gravity) {
return new DialogView(mContext, layout, R.style.Theme_Dialog, gravity);
}
public void show(DialogView view){
if (view!=null){
if (!view.isShowing()){
view.show();
}
}
}
public void hide(DialogView view){
if (view !=null){
if (view.isShowing()){
view.dismiss();
}
}
}
}
三、使用
寫完了上面這些呢,我們的自定義Dialog就已經寫完了,那我們怎麼使用它呢?其實很簡單,一起來看一下!
首先我們可以在Activity中定義一個全局變量DialogView的對象,比如:
private DialogView mCodeView;
然後在需要初始化的地方進行初始化,只需要一行代碼即可,傳入上下文對象和自定義的佈局文件:
mCodeView = DialogManager.getInstance().initView(this,R.layout.dialog_code_view_layout);
這樣就初始化完成了,你就可以在需要顯示或隱藏的地方通過DialogManager調用show和hide方法即可,傳入我們的DialogView對象:
DialogManager.getInstance().show(mCodeView); //顯示
DialogManager.getInstance().hide(mCodeView); //隱藏
如果需要對Dialog中的某個控件做事件處理,也很簡單,可以先獲取這個控件,然後就可以隨心所欲的處理監聽事件了:
TouchPictureView mPictureView = mCodeView.findViewById(R.id.mPictureView);
mPictureView.setViewResultListener(new TouchPictureView.OnViewResultListener() {
@Override
public void onResult() {
//處理手勢擡起事件
}
});
四、拓展
這個拓展內容我這裏只說一下是什麼,代碼最後我會給出,但不會放在這裏,我想大家可以自己先做一下,然後再去和我的代碼對比一下,每個人有每個人的寫法,這個沒有標準答案,只要能實現功能都是OK的。現在我來說一下這個思維拓展的內容:
基於上面封裝的DialogView,製作一個加載提示框,上面圖片下面文字,思考一下怎麼實現?
就大致是這樣一個效果,幾乎所有app裏面都有的一個加載提示。。。。。。
我的實現是:自定義一個類LoadingView結合DialogView再封裝一層,單獨具有加載功能的DialogView,佈局很簡單上面一個圖片控件ImageView,下面一個文本控件TextView,構造方法中使用上面的方法對DialogView進行初始化,圖片使用屬性動畫做旋轉動畫,注意loading開始時旋轉,loading結束時停止旋轉,提供默認文本及開放式設置文本的api,提供顯示隱藏的api,整體邏輯就是這麼多,對這塊比較熟悉的童鞋可以直接略過。
夜已深,不多擾,文至此,關電腦!
哦對了,最後放個源碼地址—— LoadingView 類點擊查看,
因爲我前幾天寫另一個Demo的時候用到了這幾個類,所以就不再另外寫Demo了,直接把另一個Demo的地址放上:Android---RecyclerView之動畫(工具類)實現可展開列表 ,這個Demo中的內容也是挺值得一看的,有需要的可以把源碼clone下來看一下!
晚安了,各位!好夢!