1. 程式人生 > >Android之UI--打造萬能自定義Dialog

Android之UI--打造萬能自定義Dialog

在我們開發app的時候,很多地方需要彈出一個對話方塊,我們要不就直接用系統的Dialog或者就是AlertDialog,但是美工給我們的效果圖片很多都是無法去實現的。接下來我們來看下自定義Dialog的使用方法:首先我給大家展示2個圖片:
這裡寫圖片描述 這裡寫圖片描述

上面的2組圖片使我們開發app經常需要的彈窗展示,四周是圓角,ios幾乎都是這個效果,裡面的文字資訊,顏色都可以改變。接下來我們逐一的進行講解怎麼去自定義Dialog做出這樣子的效果:
一:首先我們要在values檔案styles下,來寫dialog的風格:

 <!-- dialog樣式 -->
    <style name
="dialog_custom" parent="@android:style/Theme.Dialog"> <item name="android:windowIsFloating">true</item> <!--是否浮在介面上--> <item name="android:windowIsTranslucent">true</item> <!--是否半透明--> <item name="android:windowNoTitle">false</item
> <!--是否有標題--> <item name="android:windowBackground">@android:color/transparent</item> <!--視窗背景色透明--> <item name="android:backgroundDimEnabled">false</item> <!--背景是否模糊顯示--> </style> <!-- dialog底部彈出選單動畫 --> <style name
="bottom_menu_animation" parent="android:Animation"> <item name="@android:windowEnterAnimation">@anim/bottom_menu_enter</item> <item name="@android:windowExitAnimation">@anim/bottom_menu_exit</item> </style>

大家可以看到我在styles裡面還加了一個動畫效果風格,這個在後面自定義Dialog的時候會用到。@anim/bottom_menu_enter和@anim/bottom_menu_exit 分別是在res下建一個anim包添加了2個檔案bottom_menu_enter和bottom_menu_exit :
在bottom_menu_enter下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="400"
        android:fromYDelta="100%p" />
</set>

在bottom_menu_exit 下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="600"
        android:toYDelta="100%p" />
</set>

上面的動畫我就不在闡述了,繼續朝下說:
首先我們先想下,自定義一個Dialog,首先要繼承Dialog,然後就是要有構造方法,然後重寫裡面的某些方法,其實就是這樣子。如果我們在某個Activity或者Fragment裡面想要這個自定義Dialog的話,那麼我們就要new這個自定義的Dialog。
那麼我們就很自然的想到我們需要一個Context上下文,一個佈局檔案,如果我們還要操作佈局裡面的檔案的話,那我們還要佈局檔案裡面的id和監聽事件;
說到這裡:我們就開始一步一步的去寫這個自定義的檔案:
我們起一個自定義Dialog叫CenterDialog:

 private Context context;      // 上下文
 private int layoutResID;      // 佈局檔案id
 private int[] listenedItems;  // 要監聽的控制元件id

 public CenterDialog(Context context, int layoutResID, int[] listenedItems) {
        super(context, R.style.dialog_custom); //dialog的樣式
        this.context = context;
        this.layoutResID = layoutResID;
        this.listenedItems = listenedItems;
    }

通過上面的分析,我們已經把Context,佈局檔案,佈局檔案裡面的控制元件id還有構造方法都寫好了,這裡說下,因為佈局檔案裡面的id控制元件會有很多,所有寫了一個int[]陣列。

接下來我們重寫onCreate()方法:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Window window = getWindow();
        window.setGravity(Gravity.CENTER); // 此處可以設定dialog顯示的位置為居中
        window.setWindowAnimations(R.style.bottom_menu_animation); // 新增動畫效果
        setContentView(layoutResID);

        WindowManager windowManager = ((Activity) context).getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.width = display.getWidth()*4/5; // 設定dialog寬度為螢幕的4/5
        getWindow().setAttributes(lp);
        setCanceledOnTouchOutside(true);// 點選Dialog外部消失
        //遍歷控制元件id,新增點選事件
        for (int id : listenedItems) {
            findViewById(id).setOnClickListener(this);
        }
    }

接下來就是讓CenterDialog implements View.OnClickListener重寫onClick()方法,到這裡我們再想下,如果想在外部要監聽佈局檔案控制元件的事件,首先我們要對CenterDialog新增監聽事件,然後才可以進行控制控制元件的監聽事件?怎麼做呢?
如果java學的好的話,很明顯我們要在這裡面寫個介面,然後新增一個方法,讓外部重寫,那下面我們看下程式碼:

 private OnCenterItemClickListener listener;
 public interface OnCenterItemClickListener {
        void OnCenterItemClick(CenterDialog dialog, View view);
    }
 public void setOnCenterItemClickListener(OnCenterItemClickListener listener) {
        this.listener = listener;
    }

  @Override
    public void onClick(View view) {
        dismiss();//注意:我在這裡加了這句話,表示只要按任何一個控制元件的id,彈窗都會消失,不管是確定還是取消。
        listener.OnCenterItemClick(this, view);
    }

好了,自定義的CenterDialog已經書寫完畢,那我們呼叫看看:
首先寫個簡單的佈局:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F0EFF5">
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="點選" />
</LinearLayout>

然後再寫個dialog佈局:dialog_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/dialog_center_background"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <TextView
        android:id="@+id/dialog_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginTop="20dp"
        android:text="需要寫的資訊"
        android:textColor="#F88833"
        android:textSize="20sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#cecece" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/dialog_cancel"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="取消"
            android:textColor="#6FBF6A"
            android:textSize="20sp" />

        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="#cecece" />

        <TextView
            android:id="@+id/dialog_sure"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="確定"
            android:textColor="#6FBF6A"
            android:textSize="20sp" />
    </LinearLayout>

</LinearLayout>

在MainActivity裡面:我們new出CenterDialog物件,並新增點選事件:

package com.fshsoft.dialogdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, CenterDialog.OnCenterItemClickListener {

    private Button button;
    private CenterDialog centerDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(this);
        centerDialog = new CenterDialog(this, R.layout.dialog_layout,
         new int[]{R.id.dialog_cancel, R.id.dialog_sure});
        centerDialog.setOnCenterItemClickListener(this);

    }

    @Override
    public void onClick(View v) {
        centerDialog.show();
    }

    @Override
    public void OnCenterItemClick(CenterDialog dialog, View view) {
           case R.id.dialog_sure:
                Toast.makeText(MainActivity.this,"確定按鈕",Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
    }
}

在OnCenterItemClick();裡面我沒有進行取消按鈕的判斷,是因為在自定義的CenterDialog裡面我已經把所有控制元件的id,點選都dismiss了,前面已經提到了。

以上就是自定義dialog的內容,到這裡,也許你會說,我的佈局裡面需要一個取消按鈕,但是不是確定,是新增圖片這個字,我不可能再去寫個佈局把,你說的對,我們可以這樣子做:

new int[]{R.id.dialog_cancel, R.id.dialog_sure});
  centerDialog.show();
  TextView dialog_sure = (TextView) centerDialog.findViewById(R.id.dialog_sure);
  dialog_sure.setText("新增圖片");

這裡需要注意的事就是,需要先把dialog給show()出來,然後通過centerDialog.findViewById(R.id.dialog_sure);才能拿到控制元件物件,然後在setText(“新增圖片”);當然還可以改變字型的顏色等等資訊,這裡就不再列舉。

以上就是全部內容,寫到這裡,你可以嘗試寫下第二張圖片的dialog.

不足之處請留言指正!有問題的可以給我留言!謝謝!

下載原始碼