Android自定義Dialog詳解

(!!新手看過來!!—轉載請著明出處跪謝!嘿嘿~—)在開發過程中經常會用到自定義對話框,今天自己總結下簡單自定義一個對話框的方法和過程.
首先要自定義一個Dialog需要這幾步:
1.創建一個繼承Dialog的類
2.重寫必要構造方法和其他方法
3.繪製對話框佈局
4.對話框中的業務邏輯處理
5.實現對話樣式的設置和定義
6.對話框在頁面的展示
爲了能充分理解所以步驟寫的比較細.好了下面進行正文:
(每一步都對應上面寫好的步驟)
1.創建一個自定義Dialog類繼承Dialog;2.重寫必要構造方法和其他方法:
import android.app.Dialog;
import android.content.Context;
public class MyDialog extends Dialog {

//繼承自父類的構造器,共有三個構造器,此處只保留了兩個來展示(一個是有主題形參的theme,一個是沒有,如果你需要其他參數自己添加就好,在後面的步驟我會把回調參數和其他此例需要的參數添加到下面的構造器中)
    public MyDialog(Context context, int theme) {
        super(context, theme);
        this.context = context;
        this.myDialogListenser = myDialogListenser;
        this.mContentText = mContentText;
    }
    public MyDialog(Context context) {
        super(context);
    }
    //重寫onCreat()方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}
3.繪製對話框佈局:
在res下layout文件夾下新建佈局文件dialog_layout.xml,佈局結構可根據自己項目要求自己定義(此處只簡單添加了兩個textview,一個用來顯示用戶在主頁輸入的內容,一個用來關閉對話框):
<?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="#FFFFFF"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="194dp"
        android:background="#FFFFFF"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:text="這是文本展示框"
            android:textSize="30sp" />

        <TextView
            android:id="@+id/close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="100dp"
            android:text="關閉"
            android:textSize="20sp" />
    </LinearLayout>

</LinearLayout>

寫好佈局後在MyDialog中把佈局添加進去,並拿到佈局中的組件:

// 重寫onCreat()方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 佈局填充器拿到寫好的佈局
        View layout = LayoutInflater.from(context).inflate(R.layout.dialog_layout, null);
        text = (TextView) layout.findViewById(R.id.text);
        close = (TextView) layout.findViewById(R.id.close);
        //把佈局添加到頁面上
        setContentView(layout);
    }

4.對話框中的業務邏輯處理:
首先業務邏輯有兩點
(1)獲取主頁用戶輸入的內容顯示在textview—->”text”上;
(2)對關閉按鈕賦予關閉事件;
要實現關閉對話框事件有兩種方法,第一在自定義對話框類中實現;第二在程序主頁面實現.
如果對話框只是簡單的功能那麼就不用麻煩在主頁面實現對對話框內容的操作了,如果需要在對話框中實現比較複雜的涉及數據和主頁面數據處理和交互那麼建議利用接口回調機制實現.
下面只按照第二種接口回調的方式實現對對話框的操作,這也是開發中經常遇到的一種情況:
(1)首先在MyDialog中定義接口定義一個關閉監聽方法(我寫這個方法的時候加了一個參數,意味着點擊關閉按鈕時對話框會把某些對話框中的數據傳到主頁面)

public interface MyDialogListenser {
        public void CloseClickListenser(String text);
    }

創建接口全局變量:

private MyDialogListenser myDialogListenser;

把回調添加到構造器中:

public MyDialog(Context context, int theme,String mContentText,MyDialogListenser myDialogListenser) {
        super(context, theme);
        this.context = context;
        this.myDialogListenser = myDialogListenser;
        this.mContentText = mContentText;
    }

(2)給關閉按鈕添加點擊事件

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 佈局填充器拿到寫好的佈局
        View layout = LayoutInflater.from(context).inflate(R.layout.dialog_layout, null);
        text = (TextView) layout.findViewById(R.id.text);
        close = (TextView) layout.findViewById(R.id.close);
        close.setOnClickListener(this);//點擊事件
    }
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.close) {
            myDialogListenser.CloseClickListenser(mContentText+"這是dialog傳回來的值:用戶輸入的值加上我自己寫的內容");//此處把要回傳的值添加進去.主頁面就能拿到此值
        }
    }

(3)把主頁面傳過來的數據設置到對話框的頁面上

// 重寫onCreat()方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 佈局填充器拿到寫好的佈局
        View layout = LayoutInflater.from(context).inflate(R.layout.dialog_layout, null);
        text = (TextView) layout.findViewById(R.id.text);
        if (!mContentText.equals("")) {
            text.setText(mContentText);
        }
        close = (TextView) layout.findViewById(R.id.close);
        close.setOnClickListener(this);
        //把佈局添加到頁面上
        setContentView(layout);
    }

主頁面的邏輯一會兒在後面會寫到,不要着急!
5.實現對話樣式的設置和定義(可以在自定義類中實現也可以在主頁面通過此類的對象實現)我通過在主頁面實現 6.對話框在頁面的展示(這兩步一起寫)
在主頁面中
創建對話框對象並展示.其中在利用自定義類中的構造器創建對象的時候要傳對話框主題樣式

MyDialog myDialog= null;
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn) {
            //拿到用戶輸入的內容
            String user_tv = user_input_et.getText().toString();
            myDialog= new MyDialog(this, R.style.mAlertDialog, user_tv, new MyDialogListenser() {
                @Override
                public void CloseClickListenser(String text) {

                    //此處寫關閉操作text就是dialog穿過來的值
                }
            });
        }

    }

期中主題樣式在res—->valus—>style.xml中定義

 <!-- 自定義彈出框的樣式 -->
    <style name="mAlertDialog" >
        <item name="android:windowNoTitle">true</item>
    </style>

此處每一項作用可以網上查詢
設置對話框位置什麼的可以利用:

 Window dialogWindow = myDialog.getWindow();
            WindowManager.LayoutParams lp = dialogWindow.getAttributes();
            dialogWindow.setGravity(Gravity.CENTER);
            WindowManager m = getWindowManager();
            Display d = m.getDefaultDisplay(); // 獲取屏幕寬、高用
            WindowManager.LayoutParams p = dialogWindow.getAttributes(); // 獲取對話框當前的參數值
            p.height = (int) (d.getHeight() * 0.4); // 高度設置爲屏幕的0.6
            p.width = (int) (d.getWidth() * 0.8); // 寬度設置爲屏幕的0.65
            dialogWindow.setAttributes(p);

6.對話框展示: myDialog.show();
以上寫的比較亂,代碼也不全,下面是全部代碼,可以結合步驟對照下面的代碼瞭解:
//————————————————————————
(一)自定義dialog類:

package com.example.dialogtest;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

public class MyDialog extends Dialog implements android.view.View.OnClickListener {

    private LayoutInflater inflater;
    private TextView text;
    private TextView close;
    private Context context;
    private MyDialogListenser myDialogListenser;
    private String mContentText;
    //本次事例使用的構造器
    public MyDialog(Context context, int theme, String mContentText, MyDialogListenser myDialogListenser) {
        super(context, theme);
        this.context = context;
        this.myDialogListenser = myDialogListenser;
        this.mContentText = mContentText;
    }
    //沒有自定義樣式的構造器,在這個例子中沒有使用
    public MyDialog(Context context, String mContentText, MyDialogListenser myDialogListenser) {
        super(context);
        this.context = context;
        this.myDialogListenser = myDialogListenser;
        this.mContentText = mContentText;
    }

    // 重寫onCreat()方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 佈局填充器拿到寫好的佈局
        View layout = LayoutInflater.from(context).inflate(R.layout.dialog_layout, null);
        text = (TextView) layout.findViewById(R.id.text);
        //把主頁面傳過來的內容設置到dialog上
        if (!mContentText.equals("")) {
            text.setText(mContentText);
        }
        close = (TextView) layout.findViewById(R.id.close);
        //添加點擊時間,類實現android.view.View.OnClickListener方法
        close.setOnClickListener(this);
        // 把佈局添加到頁面上
        setContentView(layout);
    }
    //接口
    public interface MyDialogListenser {
    //自定義的回調方法,添加了一個參數,用於把dialog中的內容返回去
        public void CloseClickListenser(String text);
    }
    //點擊方法
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.close) {
//利用實例化的接口對象調用定義好的接口方法,以便於實現回調
            myDialogListenser.CloseClickListenser(mContentText);
        }
    }
}
//--------------------------------------------------------

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="#FFFFFF"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="194dp"
        android:background="#FFFFFF"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:text="這是文本展示框"
            android:textSize="30sp" />

        <TextView
            android:id="@+id/close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="100dp"
            android:text="關閉"
            android:textSize="20sp" />
    </LinearLayout>

</LinearLayout>

主頁代碼MainActivity.java:

package com.example.dialogtest;

import android.support.v7.app.ActionBarActivity;

import com.example.dialogtest.MyDialog.MyDialogListenser;
import android.os.Bundle;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity implements OnClickListener {
        //用戶輸入框
    private EditText user_input_et;
    //打開對話框的按鈕
    private Button btn;
    //展示dialog返回數據的文本框
    private TextView back_text;
    //dialog對象
    private MyDialog myDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        user_input_et = (EditText) findViewById(R.id.user_input_et);
        back_text = (TextView) findViewById(R.id.edit);
        btn = (Button) findViewById(R.id.btn);
        btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn) {
            // 拿到用戶輸入的內容
            String user_tv = user_input_et.getText().toString();
            myDialog = new MyDialog(this, R.style.mAlertDialog,user_tv, new MyDialogListenser() {

                @Override
                public void CloseClickListenser(String text) {
                    // 把對話框傳回來的值設置到主頁上;
                    back_text.setText(text);
                    // 點擊按鈕關閉對話框
                    myDialog.dismiss();
                }
            });
            //設置對話框位置的操作
            Window dialogWindow = myDialog.getWindow();
            WindowManager.LayoutParams lp = dialogWindow.getAttributes();
            dialogWindow.setGravity(Gravity.CENTER);
            WindowManager m = getWindowManager();
            Display d = m.getDefaultDisplay(); // 獲取屏幕寬、高用
            WindowManager.LayoutParams p = dialogWindow.getAttributes(); // 獲取對話框當前的參數值
            p.height = (int) (d.getHeight() * 0.4); // 高度設置爲屏幕的0.6
            p.width = (int) (d.getWidth() * 0.8); // 寬度設置爲屏幕的0.65
            dialogWindow.setAttributes(p);
            //展示對話框
            myDialog.show();
        }

    }

}
//--------------------------------------------------------

主頁佈局文件activity_main.xml:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/user_input_et"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:textColor="#FFFFFF"
        android:background="@color/dim_foreground_disabled_material_light"
        android:hint="請輸入對話框要顯示的內容" />

    <TextView
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:text="此處顯示對話框返回的值"
        android:background="@color/dim_foreground_disabled_material_light" />

    <Button
        android:id="@+id/btn"
        android:layout_width="100dp"
        android:layout_marginTop="10dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="展示我的自定義對話框" />

</LinearLayout>
//--------------------------------------------------------

源碼地址:http://download.csdn.net/detail/github_33905879/9501880

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章