1. 程式人生 > >Android自定義Dialog,炫酷主流的載入對話方塊

Android自定義Dialog,炫酷主流的載入對話方塊

前言

 最近開發中用到許多對話方塊,之前都是在外面的程式碼中建立AlertDialog並設定自定義佈局實現常見的對話方塊,諸如更新提示等含有取消和刪除兩個按鈕的對話方塊我們可以通過程式碼建立一個AlertDialog並通過它暴露的一系列方法設定我們自定義的佈局和style,但有時候系統的AlertDialog並不能實現更好的定製,這時,我們就想到了自定義Dialog。通過檢視AlertDialog的類結構發現它也是繼承於Dialog,於是我們也可以通過繼承Dialog實現我們自定義的Dialog。這篇文章將介紹如何定製當今主流的對話方塊,先上效果圖,給大家養養眼。

這裡寫圖片描述這裡寫圖片描述

程式碼實現

1、編寫自定義佈局,dialog_loading.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:orientation="vertical"
             android:layout_width="match_parent"
             android:gravity="center"
             android:background
="@drawable/bg_loading_dialog" android:layout_height="match_parent">
<ImageView android:id="@+id/iv_loading" android:layout_width="wrap_content" android:src="@mipmap/ic_dialog_loading" android:layout_height="wrap_content"/> <TextView android:id
="@+id/tv_loading" android:layout_width="wrap_content" android:layout_marginTop="20dp" android:text="@string/loading" android:textSize="16sp" android:textColor="@android:color/white" android:layout_height="wrap_content"/>
</LinearLayout>

2、繼承Dialog,覆蓋構造方法

public class LoadingDialog extends Dialog {

    private static final String TAG = "LoadingDialog";

    private String mMessage; // 載入中文字
    private int mImageId; // 旋轉圖片id
    private boolean mCancelable;
    private RotateAnimation mRotateAnimation;

    public LoadingDialog(@NonNull Context context,String message,int imageId) {
        this(context,R.style.LoadingDialog,message,imageId,false);
    }

    public LoadingDialog(@NonNull Context context, int themeResId,String message,int imageId,boolean cancelable) {
        super(context, themeResId);
        mMessage = message;
        mImageId = imageId;
        mCancelable = cancelable;
    }
}

3、覆蓋onCreate(),初始化控制元件

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    initView();
}

private void initView() {
    setContentView(R.layout.dialog_loading);
    // 設定視窗大小
    WindowManager windowManager = getWindow().getWindowManager();
    int screenWidth = windowManager.getDefaultDisplay().getWidth();
    WindowManager.LayoutParams attributes = getWindow().getAttributes();
    // 設定視窗背景透明度
    attributes.alpha = 0.3f;
    // 設定視窗寬高為螢幕的三分之一(為了更好地適配,請別直接寫死)
    attributes.width = screenWidth/3;
    attributes.height = attributes.width;
    getWindow().setAttributes(attributes);
    setCancelable(mCancelable);

    TextView tv_loading = findViewById(R.id.tv_loading);
    ImageView iv_loading = findViewById(R.id.iv_loading);
    tv_loading.setText(mMessage);
    iv_loading.setImageResource(mImageId);
    // 先對imageView進行測量,以便拿到它的寬高(否則getMeasuredWidth為0)
    iv_loading.measure(0,0);
    // 設定選擇動畫
    mRotateAnimation = new RotateAnimation(0,360,iv_loading.getMeasuredWidth()/2,iv_loading.getMeasuredHeight()/2);
    mRotateAnimation.setInterpolator(new LinearInterpolator());
    mRotateAnimation.setDuration(1000);
    mRotateAnimation.setRepeatCount(-1);
    iv_loading.startAnimation(mRotateAnimation);
}

以上程式碼需要注意設定動畫旋轉中心座標為我們imageView的中心點,需要先對imageView進行測量,同時初始化佈局的操作請放在onCreate()方法中(別直接在構造方法中初始化佈局,這樣可以在Dialog要顯示的時候才初始化,即呼叫show方法)。

4、其他

@Override
public void dismiss() {
    mRotateAnimation.cancel();
    super.dismiss();
}

@Override
public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK){
        // 遮蔽返回鍵
        return mCancelable;
    }
    return super.onKeyDown(keyCode, event);
}

這一步需要注意的是我們Dialog在顯示的時候就會無限重複(setRepeatCount(-1))執行旋轉動畫,因此在Dialog消失的時候我們要取消動畫,而遮蔽返回鍵則是為了更好地讓視窗的關閉被我們的mCancelable控制。

看到這裡你或許想知道我們設定的佈局背景drawable,如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="10dp"></corners>
    <solid android:color="@android:color/black"/>
</shape>

你可以自己設定你想要的圓角大小,也可以設定背景顏色(會被透明處理,根據我們為視窗設定的透明度)。

當然,仔細的你會發現我們還少了一些必要的配置,那就是視窗的style,如下:

<style name="LoadingDialog" parent="@android:style/Theme.Holo.Dialog.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>
  • android:windowBackground:設定視窗的背景,這裡設為透明;
  • android:backgroundDimEnabled:設定視窗是否變暗(true變暗,false不變暗,見效果圖1和2)。