1. 程式人生 > >安卓與html混合開發之原生與js相互呼叫

安卓與html混合開發之原生與js相互呼叫

原生和html的優缺點就不多說了,有些特定條件下用html頁面可以很方便,也很容易更新和維護,那麼這就涉及到html與安卓原生的互動和通訊。

接下來我要分享的是html呼叫原生的彈窗和位置資訊,安卓原生呼叫JS中的方法。

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:id="@+id/linearlayout"
    android:layout_height="match_parent">
    <include layout="@layout/layout_title"></include>

<WebView
    android:id="@+id/wv_location"
    android:layout_width="match_parent"
    android:layout_height="match_parent"></WebView>

</LinearLayout>

初始化WebView之後就開始載入html以及幾個關鍵程式碼:
  webView.setWebChromeClient(new WebChromeClient() );
        webView.getSettings().setJavaScriptEnabled(true);   //開啟JavaScript支援

        // 新增一個物件, 讓JS可以訪問該物件的方法, 該物件中可以呼叫JS中的方法
        webView.addJavascriptInterface(new JSInterface1(), "baobao");
        webView.setWebViewClient(new MyWebViewClient());
        webView.loadUrl("file:///android_asset/PriseLocation.html");

webView.setWebChromeClient(new WebChromeClient());必不可少,它是解決js中alert不彈出的問題和其它內容的渲染問題。

關鍵的兩行程式碼說一下,首先是js呼叫原生的方法:webView.addJavascriptInterface(new JSInterface1(),"baobao");JSInterface1內部類中的方法都是提供給js呼叫的,“baobao”相當於一個“id”,用於標記原生的物件,被html用來呼叫原生的方法,就相當於引用一樣。另一行重要的程式碼就是webView.loadUrl("javascript: showMsg()");loadUrl方法內的字串就是呼叫js中的方法。

JSInterface1:

class JSInterface1 {

        //JavaScript呼叫此方法
        @JavascriptInterface

        public void callAndroidMethod(int a, float b, String c, boolean d) {
            if (d) {
                String strMessage = "a+b+c=" + a + b + c;
                T.showThort(mContext, strMessage);

//                showPopupWindowIntroDestine();


            }
        }

        @JavascriptInterface
        public void callLocation() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //獲取Location
                    /**
                     * 獲取地理位置
                     */
                    String locaLocation = getLocaLocation();
                }
            });


        }

        @JavascriptInterface
        public void callAlert(final String info) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.getAlert(info, 0.3f);
                }
            });

        }

        /**
         * @param info
         */
        @JavascriptInterface
        public void callConfirm(final String info) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.seConfirmButtonText("確認", "取消");
                    popUtils.getConfirm(info, 0.3f, new PopAlertStyleUtils.CallBackLeftRightButton() {
                        @Override
                        public void rightButton(View v) {
                            popUtils.popDismiss();
                        }

                        @Override
                        public void leftButton(View v) {

                            T.showThort(mContext, "我是左邊按鈕");
                        }
                    });
                }
            });

        }

        @JavascriptInterface
        public void callPrompt(final String info) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.setLeftRightBtText("繼續", "不玩了");
                    popUtils.getPromptWindow(info, 0.3f, new PopAlertStyleUtils.CallBackPrompt() {
                        @Override
                        public void rightButton(View v, EditText editText) {
                            popUtils.popDismiss();
                        }

                        @Override
                        public void leftButton(View v, EditText editText) {
                            T.showThort(mContext, "請繼續玩吧-----" + editText.getText().toString());
                        }
                    });
                }
            });
        }


        @JavascriptInterface
        public void callLoading(final String info) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.getLoading(info, 0.3f);
                    new Handler() {
                    }.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            popUtils.popDismiss();
                        }
                    }, 2000);
                }
            });
        }


        @JavascriptInterface
        public void callToast(final String info) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.getToast(info, 1.0f);
                    new Handler() {
                    }.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            popUtils.popDismiss();
                        }
                    }, 2000);
                }
            });
        }

        @JavascriptInterface
        public void callActionsheet() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.setTitle("Who wins");
                    nameList = new ArrayList<String>();
                    nameList.add("張賽寶");
                    nameList.add("小黃");
                    nameList.add("張紹均");
                    nameList.add("楊峰");

                    popUtils.getActionsheet(0.3f, new PopAlertStyleUtils.CallBackActionSheet() {
                        @Override
                        public void backListView(ListView listView, Button button) {

                            button.setText("確定");
                            NameListAdapter adapter = new NameListAdapter(mContext, nameList);
                            listView.setAdapter(adapter);
                            button.setOnClickListener(new ButtonOnclick());
                            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                                @Override
                                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                                    webView.loadUrl("javascript: showMsg()");
                                }
                            });
                        }
                    });
                }
            });
        }

        @JavascriptInterface
        public void callChosen() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.setTitle("Who wins");
                    final List<String> choseList = new ArrayList<>();
                    choseList.add("張賽寶");
                    choseList.add("小黃");
                    choseList.add("張紹均");
                    choseList.add("楊峰");
                    popUtils.getChosen(0.3f, new PopAlertStyleUtils.CallBackChosen() {
                        @Override
                        public void backChosen(ListView listView) {
                            final ChosenAdapter adapter = new ChosenAdapter(mContext, choseList);
                            listView.setAdapter(adapter);
                            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                                @Override
                                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                                    adapter.setSelectNum(position);
                                    adapter.notifyDataSetChanged();
                                }
                            });
                        }
                    });
                }
            });
        }

        @JavascriptInterface
        public void callModal() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.setTitle("2.5版本更新");
                    popUtils.setLeftRightBtText("瞭解更多", "知道了");
                    popUtils.getModal("1.功能更新2.功能更新", 0.3f, new PopAlertStyleUtils.CallBackModal() {
                        @Override
                        public void rightButton(View v) {
                            T.showThort(mContext, "我是左邊按鈕");
                        }

                        @Override
                        public void leftButton(View v) {
                            T.showThort(mContext, "我是右邊按鈕");
                        }

                        @Override
                        public void initImag(ImageView imageView) {
                            Glide.with(mContext).load(R.mipmap.bg_banner).transform(new GlideRoundTransform(mContext, 15)).into(imageView);
                        }
                    });
                }
            });
        }

        @JavascriptInterface
        public void callTimepicker() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.getDatePicker();
                }
            });
        }

        @JavascriptInterface
        public void callDatepicker() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    final PopAlertStyleUtils popUtils = new PopAlertStyleUtils(mContext, parentsView);
                    popUtils.getTimePicker();
                }
            });
        }

        @JavascriptInterface
        public void btBack() {//返回
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    finish();
                }
            });

        }

        @JavascriptInterface
        public void btHelp() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Intent intent = new Intent(mContext, HelpDemoActivity.class);
                    startActivity(intent);
                }
            });
        }

        @JavascriptInterface
        public void setTitle(final String title) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tvTitle.setText(title);
                }
            });
        }
    }
Html程式碼,主要就是通過定義的引用 baobao.XXX()呼叫原生中的方法,可以傳遞引數。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
 
    <script src="http://api.map.baidu.com/api?v=1.2" type="text/javascript"></script>

<script>
   function showMsg(){
      alert("hello world!");
   }
function showHelp(){
      alert("我是幫助回撥");
   }
function getTitle(){
    var id=document.getElementById("text").value;

    baobao.setTitle(id);
}
   </script>
</head>
<body>
<div className="page-dialog" >
<button  class="btn"onClick="baobao.callAndroidMethod(100,100,'ccc',true)">我是彈窗按鈕</button></div>
    <div className="page-dialog" >
<button class="btn"onClick="baobao.callLocation()">我是地理位置按鈕</button></div>

<div className="page-dialog" >
    <button class="btn" onClick="baobao.callAlert('我是提示資訊')">alert</button></div>
<div className="page-dialog"  >
    <button class="btn" onClick="baobao.callConfirm('我是提示資訊')">confirm</button></div>
    <div className="page-dialog">
    <button class="btn" onClick="baobao.callPrompt('我是提示資訊')">prompt</button></div>
        <div className="page-dialog">
    <button class="btn" onClick="baobao.callLoading('使勁載入中...')">loading...</button></div>
            <div className="page-dialog">
    <button class="btn" onClick="baobao.callToast('提交成功')">toast</button></div>
                <div className="page-dialog">
    <button class="btn" onClick="baobao.callActionsheet()">actionsheet</button></div>
                    <div className="page-dialog">
    <button class="btn" onClick="baobao.callChosen()">chosen</button></div>
                        <div className="page-dialog">
    <button class="btn" onClick="baobao.callModal()">modal</button></div>
                            <div className="page-dialog">
    <button class="btn" onClick="baobao.callTimepicker()">timepicker</button></div>
                                <div className="page-dialog">
    <button class="btn" onClick="baobao.callDatepicker()">datepicker</button></div>



</div>

<div className="page-dialog">

    <button class="btn" onClick="baobao.btBack()">返回頁面</button>
<button class="btn" onClick="baobao.btHelp()">幫助</button>
</div>

<div >
    <input class = "title" id="text"><input type="button" value="修改標題" id="btnn" onclick ="getTitle()">
</div>

</body>
<style>
    .btn{background:#00acff; color:#fff; border-radius:0.1em; width:100%;border:0;margin-top:0.5em;}
</style>
<style>
    .title{margin-top:0.5em;}
</style>
</html>

彈窗工具集合我都是自定義做的會有些麻煩,但是可操作性比較高:
package cn.com.bjhj.baseframework.utils;

import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;

import java.util.Calendar;

import cn.com.bjhj.baseframework.R;


/**類介紹(必填): 各種樣式彈窗
 
 */

public class PopAlertStyleUtils {

    private Context context;
    private View parentsView;
    private View mPopView;
    private CustomPopupWindow mAlertWindow;
    private View mPopViewConfirm;
    private CallBackLeftRightButton callBackLeftRightButton;
    private CustomPopupWindow mConfirmWindow;
    private String confirmLeft;
    private String confirmRight;
    private View mPopViewPrompt;
    private CustomPopupWindow mPromptWindow;
    private String promptLeft;
    private String promptRight;
    private CallBackPrompt callBackPrompt;
    private View mPopViewLoading;
    private CustomPopupWindow mLoadingWindow;
    private View mPopViewToast;
    private CustomPopupWindow mToastWindow;
    private TextView tvAlertHint;
    private String title;//標題
    private View mPopViewActionsheet;
    private CustomPopupWindow mActionsheetWindow;
    private CallBackActionSheet callBackActionSheet;
    private View mPopViewChosen;
    private CustomPopupWindow mChosenWindow;
    private CallBackChosen callBackChosen;
    private View mPopViewModal;
    private CustomPopupWindow mModalWindow;
    private String time;

    public PopAlertStyleUtils(Context context,View parentsView) {
        this.context = context;
        this.parentsView = parentsView;
        if (title!=null){
            title="提示";
        }
    }

    /**
     * 獲取提示框 alert
     * @param info 提示資訊
     * @param num  背景透明度
     */
    public void getAlert(final String info, float num){
        mPopView = LayoutInflater.from(context).inflate(R.layout.pop_window_alert, null);
        mAlertWindow = new CustomPopupWindow(parentsView,
                context, mPopView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout
                .LayoutParams.WRAP_CONTENT, true);
//
        /**
         * 初始化懸浮窗 裡面的控制元件
         */
        mAlertWindow.setOnPopupWindowListener(new CustomPopupWindow
                .PopupWindowListener() {

            // TODO 設定活動內容
            @Override
            public void initView() {
                tvAlertHint = (TextView) mPopView.findViewById(R.id.tv_alert_hint);
                TextView tvAlertInfo = (TextView) mPopView.findViewById(R.id.tv_alert_info);
                Button btAlertObtain = (Button) mPopView.findViewById(R.id.bt_alert_obtain);
                tvAlertInfo.setText(info);
                if (title!=null){
                    tvAlertHint.setText(title);
                }
                btAlertObtain.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        popDismiss();
                    }
                });
            }
        });
        mAlertWindow.showView();
        mAlertWindow.setBackgroundAlpha(num);
    }

    /**
     * 設定標題
     * @param title 標題
     */
    public void setTitle(String title){
    this.title = title;
}
    /**
     * 獲取confirm對話方塊
     * @param info
     * @param num
     * @param callBackLeftRightButton
     */
    public void getConfirm(final String info, float num, final CallBackLeftRightButton callBackLeftRightButton){
        this.callBackLeftRightButton = callBackLeftRightButton;
        mPopViewConfirm = LayoutInflater.from(context).inflate(R.layout.pop_window_confirm, null);
        mConfirmWindow = new CustomPopupWindow(parentsView,
                context, mPopViewConfirm, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout
                .LayoutParams.WRAP_CONTENT, true);
//
        /**
         * 初始化懸浮窗 裡面的控制元件
         */
        mConfirmWindow.setOnPopupWindowListener(new CustomPopupWindow
                .PopupWindowListener() {

            // TODO 設定活動內容
            @Override
            public void initView() {
                TextView tvConfirmInfo = (TextView) mPopViewConfirm.findViewById(R.id.tv_confirm_info);
                Button btConfirmLeft = (Button) mPopViewConfirm.findViewById(R.id.bt_confirm_left);
                TextView tvConfirmHint = (TextView) mPopViewConfirm.findViewById(R.id.tv_confirm_hint);
                if (title!=null){
                    tvConfirmHint.setText(title);
                }
                Button btConfirmRight = (Button) mPopViewConfirm.findViewById(R.id.bt_confirm_right);
                tvConfirmInfo.setText(info);
                if (confirmLeft!=null&&confirmRight!=null){
                    btConfirmLeft.setText(confirmLeft);
                    btConfirmRight.setText(confirmRight);
                }
                btConfirmLeft.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                      callBackLeftRightButton.leftButton(v);
                    }
                });
                btConfirmRight.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                    callBackLeftRightButton.rightButton(v);
                    }
                });
            }
        });
        mConfirmWindow.showView();
        mConfirmWindow.setBackgroundAlpha(num);
    }

    /**
     * 設定confirm的左右按鈕名字
     * @param left
     * @param right
     */
    public void seConfirmButtonText(String left,String right){
    confirmLeft = left;
        confirmRight = right;
}

    /**
     * 獲取輸入對話方塊
     * @param info 提示資訊
     * @param num  透明度
     * @param callBackPrompt 回撥函式
     */
    public void getPromptWindow(final String info, float num, final CallBackPrompt callBackPrompt){
    this.callBackPrompt = callBackPrompt;
    mPopViewPrompt = LayoutInflater.from(context).inflate(R.layout.pop_window_prompt, null);
    mPromptWindow = new CustomPopupWindow(parentsView,
            context, mPopViewPrompt, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout
            .LayoutParams.WRAP_CONTENT, true);
//
    /**
     * 初始化懸浮窗 裡面的控制元件
     */
    mPromptWindow.setOnPopupWindowListener(new CustomPopupWindow
            .PopupWindowListener() {

        // TODO 設定活動內容
        @Override
        public void initView() {
            TextView tvPromptInfo = (TextView) mPopViewPrompt.findViewById(R.id.tv_prompt_info);
            TextView tvPromptHint = (TextView) mPopViewPrompt.findViewById(R.id.tv_prompt_hint);
            if (title!=null){
                tvPromptHint.setText(title);
            }
            Button btPromptLeft = (Button) mPopViewPrompt.findViewById(R.id.bt_prompt_left);
            Button btPromptRight = (Button) mPopViewPrompt.findViewById(R.id.bt_prompt_right);
            final EditText etPrompt = (EditText) mPopViewPrompt.findViewById(R.id.et_prompt);

            tvPromptInfo.setText(info);
            if (promptLeft!=null&&promptRight!=null){
                btPromptLeft.setText(promptLeft);
                btPromptRight.setText(promptRight);
            }
            btPromptLeft.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    callBackPrompt.leftButton(v,etPrompt);
                }
            });
            btPromptRight.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    callBackPrompt.rightButton(v,etPrompt);
                }
            });
        }
    });
    mPromptWindow.showView();
    mPromptWindow.setBackgroundAlpha(num);
    
}
    /**
     * 獲取prompt彈窗的左右按鈕名稱
     * @param left
     * @param right
     */
    public void setLeftRightBtText(String left, String right){
        promptLeft = left;
        promptRight = right;
    }
    /**
     * 獲取載入中彈窗
     * @param info 載入資訊
     * @param num 背景透明度
     */
    public void getLoading(final String info, float num){
        mPopViewLoading = LayoutInflater.from(context).inflate(R.layout.pop_window_loading, null);
        mLoadingWindow = new CustomPopupWindow(parentsView,
                context, mPopViewLoading, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout
                .LayoutParams.WRAP_CONTENT, true);
//
        /**
         * 初始化懸浮窗 裡面的控制元件
         */
        mLoadingWindow.setOnPopupWindowListener(new CustomPopupWindow
                .PopupWindowListener() {

            // TODO 設定活動內容
            @Override
            public void initView() {
                TextView tvLoadingInfo = (TextView) mPopViewLoading.findViewById(R.id.tv_load_info);
                tvLoadingInfo.setText(info);

            }
        });
        mLoadingWindow.showView();
        mLoadingWindow.setBackgroundAlpha(num);
    }

    /**
     * 獲取吐司彈窗
     * @param info 提示資訊
     * @param num 背景透明度
     */
    public void getToast(final String info, float num){
        mPopViewToast = LayoutInflater.from(context).inflate(R.layout.pop_window_toast, null);
        mToastWindow = new CustomPopupWindow(parentsView,
                context, mPopViewToast, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout
                .LayoutParams.WRAP_CONTENT, true);
//
        /**
         * 初始化懸浮窗 裡面的控制元件
         */
        mToastWindow.setOnPopupWindowListener(new CustomPopupWindow
                .PopupWindowListener() {

            // TODO 設定活動內容
            @Override
            public void initView() {
                TextView tvToastInfo = (TextView) mPopViewToast.findViewById(R.id.tv_toast_info);
                tvToastInfo.setText(info);

            }
        });
        mToastWindow.showView();
        mToastWindow.setBackgroundAlpha(num);
    }

    /**
     * 獲取 選擇
     * @param num
     * @param callBackActionSheet
     */
    public void getActionsheet(float num, final CallBackActionSheet callBackActionSheet){
        this.callBackActionSheet=callBackActionSheet;
        mPopViewActionsheet = LayoutInflater.from(context).inflate(R.layout.pop_window_actionsheet, null);
        mActionsheetWindow = new CustomPopupWindow(parentsView,
                context, mPopViewActionsheet, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout
                .LayoutParams.WRAP_CONTENT, true);
//
        /**
         * 初始化懸浮窗 裡面的控制元件
         */
        mActionsheetWindow.setOnPopupWindowListener(new CustomPopupWindow
                .PopupWindowListener() {

            // TODO 設定活動內容
            @Override
            public void initView() {
                 TextView tvActionsheetHint = (TextView) mPopViewActionsheet.findViewById(R.id.tv_actionsheet_hint);
                ListView lvActionSheet = (ListView) mPopViewActionsheet.findViewById(R.id.lv_actionsheet);

                Button btActionsheetObtain = (Button) mPopViewActionsheet.findViewById(R.id.bt_actionsheet_obtain);
                if (title!=null){
                    tvActionsheetHint.setText(title);
                }
                callBackActionSheet.backListView(lvActionSheet,btActionsheetObtain);

            }
        });
        mActionsheetWindow.showView();
        mActionsheetWindow.setBackgroundAlpha(num);
    }

    /**
     * 獲取單選項
     * @param num
     * @param callBackChosen
     */
    public void getChosen(float num, final CallBackChosen callBackChosen){
        this.callBackChosen = callBackChosen;
        mPopViewChosen = LayoutInflater.from(context).inflate(R.layout.pop_window_chosen, null);
        mChosenWindow = new CustomPopupWindow(parentsView,
                context, mPopViewChosen, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout
                .LayoutParams.WRAP_CONTENT, true);
//
        /**
         * 初始化懸浮窗 裡面的控制元件
         */
        mChosenWindow.setOnPopupWindowListener(new CustomPopupWindow
                .PopupWindowListener() {

            // TODO 設定活動內容
            @Override
            public void initView() {
                TextView tvHint = (TextView) mPopViewChosen.findViewById(R.id.tv_chosen_hint);
                if (title!=null){
                    tvHint.setText(title);
                }
                ListView radioGroup = (ListView) mPopViewChosen.findViewById(R.id.lv_chosen);
                callBackChosen.backChosen(radioGroup);

            }
        });
        mChosenWindow.showView();
        mChosenWindow.setBackgroundAlpha(num);
    }

    /**
     * 獲取modal
     * @param info
     * @param num
     * @param callBackModal
     */
    public void getModal(final String info, float num, final CallBackModal callBackModal){
        mPopViewModal = LayoutInflater.from(context).inflate(R.layout.pop_window_modal, null);
        mModalWindow = new CustomPopupWindow(parentsView,
                context, mPopViewModal, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout
                .LayoutParams.WRAP_CONTENT, true);
//
        /**
         * 初始化懸浮窗 裡面的控制元件
         */
        mModalWindow.setOnPopupWindowListener(new CustomPopupWindow
                .PopupWindowListener() {

            // TODO 設定活動內容
            @Override
            public void initView() {
                TextView tvModalInfo = (TextView) mPopViewModal.findViewById(R.id.tv_modal_info);
                TextView tvModalHint = (TextView) mPopViewModal.findViewById(R.id.tv_modal_hint);
                ImageView ivPic = (ImageView) mPopViewModal.findViewById(R.id.iv_modal_info);
                if (title!=null){
                    tvModalHint.setText(title);
                }
                Button btModalLeft = (Button) mPopViewModal.findViewById(R.id.bt_modal_left);
                Button btModalRight = (Button) mPopViewModal.findViewById(R.id.bt_modal_right);
                callBackModal.initImag(ivPic);
                tvModalInfo.setText(info);
                if (promptLeft!=null&&promptRight!=null){
                    btModalLeft.setText(promptLeft);
                    btModalRight.setText(promptRight);
                }
                btModalLeft.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        callBackModal.leftButton(v);
                    }
                });
                btModalRight.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        callBackModal.rightButton(v);
                    }
                });
            }
        });
        mModalWindow.showView();
        mModalWindow.setBackgroundAlpha(num);

    }
    public void getDatePicker(){
        final Calendar c = Calendar.getInstance();
        int mYear = c.get(Calendar.YEAR);
        int mMonth = c.get(Calendar.MONTH);
        int mDay = c.get(Calendar.DAY_OF_MONTH);
        new DatePickerDialog(context,
                mDateSetListener,
                mYear, mMonth, mDay).show();
    }
    private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
        public void onDateSet(DatePicker view, int year,
                              int monthOfYear, int dayOfMonth) {

        }
    };
    public void getTimePicker(){
        final Calendar c = Calendar.getInstance();
        int mYear = c.get(Calendar.YEAR);
        int mMonth = c.get(Calendar.MONTH);
        int mDay = c.get(Calendar.DAY_OF_MONTH);
        new TimePickerDialog(context,mTimeSetListener,0,0,true).show();
    }
    private TimePickerDialog.OnTimeSetListener mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
        @Override
        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

        }
    };
    /**
     * 關閉彈窗
     */
    public void popDismiss(){
        if (mAlertWindow!=null){
            mAlertWindow.dismiss();
        }
        if (mConfirmWindow!=null){
            mConfirmWindow.dismiss();
        }
        if (mPromptWindow!=null){
            mPromptWindow.dismiss();
        }
        if (mLoadingWindow!=null){
            mLoadingWindow.dismiss();
        }
        if (mToastWindow!=null){
            mToastWindow.dismiss();
        }
        if (mActionsheetWindow!=null){
            mActionsheetWindow.dismiss();
        }
    }

    /**
     * 沒有輸入框的左右按鈕回撥
     */
    public interface CallBackLeftRightButton {
        public void rightButton(View v);
        public void leftButton(View v);
    }

    /**
     * 有輸入框的左右回撥
     */
    public interface CallBackPrompt {
        public void rightButton(View v,EditText editText);
        public void leftButton(View v,EditText editText);
    }
    public interface CallBackActionSheet{
        void backListView(ListView listView,Button button);
    }
    public interface CallBackChosen{
        void backChosen(ListView listView);
    }
    public interface CallBackModal{
        public void rightButton(View v);
        public void leftButton(View v);
        void initImag(ImageView imageView);
    }
    }
自定義PopWindow:
package cn.com.bjhj.baseframework.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.PopupWindow;

/**
 * 自定義懸浮窗體
 * Created by JIANG on 2016/8/5.
 */
public class CustomPopupWindow implements PopupWindow.OnDismissListener {
    private PopupWindowListener mPopupWindowListener;
    public PopupWindow mPopupWindow;
    private Activity mActivity;
    private Context context;
    private View mParentView;
    private int mWidth;
    private int mHeight;
    private View mPopupWindowView;
    private boolean focusable;
    private View dropDown =null;


    public CustomPopupWindow(View parentView, Context activity, View contentView, int width, int
            height, boolean focusable) {
        this.mActivity = (Activity) activity;
        this.context = activity;
        this.mParentView = parentView;
        this.mWidth = width;
        this.mHeight = height;
        this.focusable = focusable;
        this.mPopupWindowView = contentView;
    }
    public CustomPopupWindow(View dropDown, View parentView, Context activity, View contentView, int width, int
            height, boolean focusable) {
        this.mActivity = (Activity) activity;
        this.context = activity;
        this.mParentView = parentView;
        this.mWidth = width;
        this.mHeight = height;
        this.focusable = focusable;
        this.mPopupWindowView = contentView;
        this.dropDown = dropDown;
    }

    /**
     * 顯示PopupWindow
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void showView() {
        mPopupWindow = new PopupWindow(mPopupWindowView, mWidth, mHeight, focusable);
        if (mPopupWindowListener != null) {
            mPopupWindowListener.initView();
        }

        mPopupWindow.setBackgroundDrawable(new ColorDrawable(0xFFFFFF));

        mPopupWindow.update();
        mPopupWindow.setOnDismissListener(this);
        if (dropDown!=null) {

            // 計算x軸方向的偏移量,使得PopupWindow在Title的正下方顯示,此處的單位是pixels
            float xoffInPixels = ScreenUtils.getScreenWidth(context) / 2 ;
            // 將pixels轉為dip
            int xoffInDip = ScreenUtils.px2dip(context,xoffInPixels);

            mPopupWindow.showAsDropDown(dropDown,0,0);

        }else {
            mPopupWindow.showAtLocation(mParentView, Gravity.CENTER | Gravity.CENTER, 0, 0);
        }

    }

    /**
     * 點選懸浮窗外面時的操作
     */
    @Override
    public void onDismiss() {
        setBackgroundAlpha(1f);
    }

    public interface PopupWindowListener {
        // 初始化PopupWindow的控制元件
        void initView();
    }

    public void setOnPopupWindowListener(PopupWindowListener listener) {
        this.mPopupWindowListener = listener;
    }

    /**
     * 隱藏PopupWindow
     */
    public void dismiss() {
        if (mPopupWindow != null) {
            mPopupWindow.dismiss();
            mPopupWindow = null;
        }
    }

    //設定螢幕背景透明效果
    public void setBackgroundAlpha(final float alpha) {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                WindowManager.LayoutParams lp = mActivity.getWindow().getAttributes();
                mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
                lp.alpha = alpha;
                mActivity.getWindow().setAttributes(lp);
            }
        });

    }
}



效果圖:


各個彈窗的效果如下: