1. 程式人生 > >簡單實現自定義Dialog彈窗

簡單實現自定義Dialog彈窗

前言

這幾天都在學習Web端的技術點,對於Android這麼好玩的技術,那麼也不能丟落。時間擠一擠,說不定還能擠出一條溝,呵呵..這幾天看到小夥伴們在專案中在為dialog相關的問題不知所措,看了大概的需求,都涉及到自定義dialog,其實也蠻簡單的,在日常開發中遇到自定義dialog的需求還是蠻多的,所以擠點時間出來練練手先.

Ⅰ.簡述

看看小夥伴的效果圖

效果圖1

這裡寫圖片描述

效果圖2

這裡寫圖片描述

看上面的效果圖,應該不是很難吧,Android系統提供的dialog往往都不滿足產品的需求,所以就需要自定義了,那麼先簡單說說怎麼實現的吧!主要就是繼承dialog類,然後給其設定佈局,再進行點選事件的回撥等等

Ⅱ.自定義Dialog實現

以上面圖1為效果圖,首頁先來個佈局,那麼下面簡單看下佈局吧


    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
>
<RelativeLayout android:id="@+id/container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true"> <TextView android:id="@+id/bg" android:layout_width
="250dp" android:layout_height="160dp" android:background="#c9f4fe" android:layout_below="@+id/iv_success" android:text="成功領取優惠劵" android:gravity="bottom|center" android:textColor="#0096ff" android:textSize="16sp"/>
<ImageView android:id="@+id/iv_success" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/receive_success" android:layout_centerInParent="true"/> </RelativeLayout> <Button android:id="@+id/btn_cancel" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/receive_success_close" android:layout_alignRight="@id/container" android:layout_marginTop="150dp" /> <Button android:id="@+id/share" android:layout_width="250dp" android:layout_height="60dp" android:background="#0096ff" android:layout_below="@id/container" android:layout_centerHorizontal="true" android:text="立即分享" android:textSize="18sp" android:textColor="#ffffff"/> </RelativeLayout>

本來接著是要繼承dialog並給其設定上面的佈局,但是考慮到專案中對dialog彈窗的使用頻率還是挺高的,所以簡單抽取dialog,以抽象類的方式提供給其他dialog去繼承,那麼下面看看抽取的BaseDialog的程式碼:


    /**
     * Created by wyk on 2016/12/28.
     */
    public abstract class BaseDialog extends Dialog implements View.OnClickListener{

        public Context mContext;

        public BaseDialog(Context context){
            super(context);
            this.mContext = context;
            initView();
        }

        public BaseDialog(Context context, int themeResId){
            super(context,themeResId);
            this.mContext = context;
            initView();
        }

        public abstract void initView();
        public abstract void onDialogClick(View v);

        /** 查詢子控制元件,省強轉 */
        public <T> T findView(int id) {
            T view = (T) findViewById(id);
            return view;
        }

        public void showToast(String text) {    //Toast
            //tell user
        }

        @Override
        public void onClick(View v) {           //點選事件
            onDialogClick(v);
        }
    }

接著就來實現自定義的dialog,自定義的dialog繼承自BaseDialog,看下面程式碼:


    /**
     * Created by wyk on 2016/12/28.
     */
    public class MyDialog extends BaseDialog{
        //dialog對應佈局上的點選事件,該介面進行回撥
        private OnCallResult mOnCallResult;
        private Button mBtnCancel;
        private Button mBtnShare;

        public MyDialog(Context context) {
            super(context);
            initDate();
            initListener();
        }

        /** 設定事件的回撥介面*/
        public void setCallBackListen(OnCallResult onCallResult){
            mOnCallResult = onCallResult;
        }

        /**該方法提供於操作佈局控制元件*/
        @Override
        public void initView() {
            Window window = getWindow();
            window.requestFeature(Window.FEATURE_NO_TITLE);
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            setContentView(R.layout.page_dialog);

            WindowManager.LayoutParams params = window.getAttributes();
            params.gravity = Gravity.CENTER;
            //這裡是設定dialog彈出、隱藏的動畫效果
            //params.windowAnimations = R.style.MyDialogAnimation;      


            mBtnCancel = findView(R.id.btn_cancel);
            mBtnShare = findView(R.id.share);
        }
        /**該方法提供於操作資料*/
        public void initDate() {
        }
        /**該方法提供於設定監聽事件*/
        public void initListener() {
            mBtnCancel.setOnClickListener(this);
            mBtnShare.setOnClickListener(this);
        }
        /**佈局的監聽函式*/
        @Override
        public void onDialogClick(View v) { 
            if(mOnCallResult!=null){
                switch (v.getId()) {
                    case R.id.btn_cancel:               //取消監聽
                       // MyDialog.this.cancel();
                        mOnCallResult.onCancel();
                        break;
                    case R.id.share:                    //分享監聽
                        mOnCallResult.onShare();
                        break;
                    default:
                        break;
                }
            }
        }
    }

上面程式碼的OnCallResult物件,註釋是回撥的介面,可是OnCallResult長怎樣的呢??看下面程式碼

    /**
     * Created by WYK on 2016/12/28.
     */
    public interface OnCallResult {

        void onCancel();
        void onShare();
    }

Ⅲ.效果展示

上面的程式碼邏輯應該還是比較清晰的,都做了註釋說明,力求做到簡單易懂,接著使用上面自定義的MyDialog,看看效果如何。為了實現方便,就在MainActivity的佈局上新增一個按鈕,點選該按鈕彈出MyDialog,然後可點選取消dialog等,看程式碼:

    /**
     * Created by wyk on 2016/12/28.
     */
    public class MainActivity extends AppCompatActivity {
        private Button mShowDialog;
        private MyDialog mDialog;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            initListener();
        }

        /**該方法提供於操作佈局控制元件*/
        private void initView() {
            mShowDialog = (Button) findViewById(R.id.btn_show_dialog);
            mDialog = new MyDialog(this);
        }

        /**該方法提供於設定監聽事件*/
        private void initListener() {
            mDialog.setCallBackListen(new OnCallResult() {
                @Override
                public void onCancel() {
                    mDialog.cancel();
                }
                @Override
                public void onShare() {
                    Toast.makeText(MainActivity.this, "Share Success!!!", Toast.LENGTH_SHORT).show();
                    mDialog.show();
                }
            });
            mShowDialog.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mDialog.show();
                }
            });
        }

        @Override
        protected void onDestroy() {        
            super.onDestroy();
            if(mDialog!=null){              //防止突發狀態造成 窗體洩露
                mDialog.cancel();           
                mDialog = null;
            }
        }
    }

下面是MainActivity的佈局,順便也貼上

    <!--activity_main佈局-->
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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"
        tools:context="com.wyk.dialogtest.MainActivity">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="show dialog"
            android:id="@+id/btn_show_dialog"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="173dp" />
    </RelativeLayout>

上面的操作基本可以展示MyDialog,也可以點選取消/點選進行分享(分享程式碼略),佈局和程式碼都很簡單吧,也沒什麼邏輯,就這樣完成了,是不是挺So easy 的。在專案開發中,dialog的坑還是蠻多的,比如上面MainActivity標識出來的窗體洩露,找時間再寫篇文章總結下遇到的坑。還有1點沒說的,應該看到上面的BaseDialog裡的 “params.windowAnimations = R.style.MyDialogAnimation; “這一行註釋的程式碼吧,這個是設定Dialog彈出、隱藏的動畫效果,之前有篇文章已經提到,下面是Dialog動畫效果那篇文章的地址,這裡就不扯了。

最後還是來看看上面程式碼執行的效果圖(佈局醜死咯~~~怪我了):
這裡寫圖片描述

Ⅳ.總結

  • 1.在瀏覽了Dialog的程式碼,其實針對BaseDialog還可以進一步抽取的,筆者追求實用即可,就不再抽取了

  • 2.針對專案中Dialog的坑,打算之後再寫個文章記錄下,這就當留個空白吧!

  • 3.2016還剩幾天,抓緊時間,別讓心長野草了。

    扯了這麼多,嗚嗚···還是先撤了。