1. 程式人生 > >android實現彈窗的方式彙總

android實現彈窗的方式彙總

近期公司人事調整,自己也從之前的基礎部門轉到了商業產品部門,整體的業務有了不小的變動,最近閱讀相關業務程式碼的時候,發現商業方向的產品需求較多的涉及android的彈窗,所以自己有必要在這裡做以總結和整理。

!!!最佳應用場景:
popupwindow、dialog、dialogfragment
dialog pk  dialogfragment:
Dialog已經不推薦使用了,因為使用它在橫豎屏切換等場合容易發生窗體洩漏;Dialog的替代是DialogFragment,它不會出現窗體洩漏的問題,而且兼具Dialog和Fragment的特點,即你既可以通過重寫onCreateDialog來建立,也可以通過重寫onCreateView來建立;但是注意不能同時重寫這兩個方法

popupwindow pk dialogfragment:
popupwindow一般以關聯某一個控制元件的彈窗,你看它的顯示方法,    public void showAsDropDown(View anchor) {,anchor相對這個控制元件顯示,恩,明白了,需要關聯一個控制元件,顯示在這個控制元件的某個位置時用popupwindow。dialogfragment是整個頁面的彈窗

  android中實現彈窗的方式如下:

一.Dialog

不設定style,預設的樣式很醜。

一個小例子:

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoadingDialog</span>  <span class="hljs-keyword">extends</span> <span class="hljs-title">android</span>.<span class="hljs-title">app</span>.<span class="hljs-title">Dialog</span> {</span>
    <span class="hljs-keyword">private</span> Activity activity;

    <span class="hljs-keyword">protected</span> <span class="hljs-title">LoadingDialog</span>(Activity activity) {
        <span class="hljs-keyword">super</span>(activity, R.style.FloadNormalDialogStyle);
        <span class="hljs-keyword">this</span>.activity = activity;
        View view = LayoutInflater.from(activity).inflate(R.layout.layout_loading_dialog, <span class="hljs-keyword">null</span>);
        setContentView(view);
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showLoading</span>() {
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">null</span> == activity || activity.isFinishing()) {
            <span class="hljs-keyword">return</span>;
        }
        setCancelable(<span class="hljs-keyword">false</span>);
        show();
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">hideLoading</span>() {
        <span class="hljs-keyword">if</span> (isShowing()) {
            dismiss();
        }
    }
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

二.PopUpWindow

  雖然AlertDialog對話方塊基本夠滿足吊絲程式設計師日常開發了,但是 AlertDialog對話方塊還是不夠靈活,因此出現了一個完全自定義,靈活度高的PopupWindow彈出式對話方塊。

一個小例子:

<code class="hljs cs has-numbering"> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">dialog6</span>() {
        View view = LayoutInflater.<span class="hljs-keyword">from</span>(<span class="hljs-keyword">this</span>).inflate(R.layout.items, <span class="hljs-keyword">null</span>);
        final PopupWindow popupWindow = <span class="hljs-keyword">new</span> PopupWindow(view, WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.WRAP_CONTENT, <span class="hljs-keyword">true</span>);

        <span class="hljs-keyword">int</span> x = <span class="hljs-number">0</span>;
        <span class="hljs-keyword">int</span> y = getStatusBarHeight() + getActionBarHeight();

        popupWindow.showAsDropDown(mDialog1, Gravity.TOP, x, y);

        <span class="hljs-comment">//pw對話方塊設定半透明背景。原理:pw顯示時,改變整個視窗的透明度為0.7,當pw消失時,透明度為1</span>
        final WindowManager.LayoutParams <span class="hljs-keyword">params</span> = DialogActivity.<span class="hljs-keyword">this</span>.getWindow().getAttributes();
        <span class="hljs-keyword">params</span>.alpha = <span class="hljs-number">0.7</span>f;
        DialogActivity.<span class="hljs-keyword">this</span>.getWindow().setAttributes(<span class="hljs-keyword">params</span>);

        view.findViewById(R.id.btn).setOnClickListener(<span class="hljs-keyword">new</span> View.OnClickListener() {
            @Override
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onClick</span>(View v) {
                isExit = <span class="hljs-keyword">true</span>;
                popupWindow.dismiss();
                <span class="hljs-keyword">params</span>.alpha = <span class="hljs-number">1</span>f;
                DialogActivity.<span class="hljs-keyword">this</span>.getWindow().setAttributes(<span class="hljs-keyword">params</span>);
            }
        });

        <span class="hljs-comment">//pw對話方塊消失監聽事件</span>
        popupWindow.setOnDismissListener(<span class="hljs-keyword">new</span> PopupWindow.OnDismissListener() {
            @Override
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onDismiss</span>() {
                <span class="hljs-keyword">params</span>.alpha = <span class="hljs-number">1</span>f;
                DialogActivity.<span class="hljs-keyword">this</span>.getWindow().setAttributes(<span class="hljs-keyword">params</span>);
            }
        });
    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

三.Dialog和PopUpWindow的區別

  就效果上來說:dialog和popupwindow可以做出完全一樣的效果和位置。

  1. AlertDialog非阻塞式對話方塊:對話方塊的顯示不影響後臺任務的執行。 PopupWindow阻塞式對話方塊:對話方塊彈出後阻塞後臺任務執行,直到對話方塊消失。
  2. AlertDialog預設半透明背景,PopupWindow預設沒有半透明背景。 即Popupwindow不會給頁面其他的部分新增蒙層,而Dialog會。
  3. PopupWindow預設不響應Back鍵,除非設定pw.setBackgroundDrawable(new ColorDrawable(0x00000000));
  4. PopupWindow預設沒有標題,AlertDialog預設是有標題的,當然可以設定dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);取消標題。
  5. 二者顯示的時候都要設定Gravity。如果不設定,Dialog預設是Gravity.CENTER。
  6. Dialog沒法設定寬為整個螢幕寬,總有點邊界。Popupwindow可以(PopupWindow也可以設定有邊界)。
    我們在寫程式的過程中可以根據自己的需要選擇使用Popupwindow或者是Dialog。

四.DialogFragment

為何推薦dialogfragment

  DialogFragment在android 3.0時被引入。是一種特殊的Fragment,用於在Activity的內容之上展示一個模態的對話方塊。典型的用於:展示警告框,輸入框,確認框等等。在DialogFragment產生之前,我們建立對話方塊:一般採用AlertDialog和Dialog。注:官方不推薦直接使用Dialog建立對話方塊。
  使用DialogFragment來管理對話方塊,當旋轉螢幕和按下後退鍵時可以更好的管理其宣告週期,它和Fragment有著基本一致的宣告週期。且DialogFragment也允許開發者把Dialog作為內嵌的元件進行重用,類似Fragment(可以在大螢幕和小螢幕顯示出不同的效果)。上面會通過例子展示這些好處~
使用DialogFragment至少需要實現onCreateView或者onCreateDIalog方法。onCreateView即使用定義的xml佈局檔案展示Dialog。onCreateDialog即利用AlertDialog或者Dialog創建出Dialog。

存在的一些問題

1.去掉預設標題

<code class="hljs avrasm has-numbering">        getDialog()<span class="hljs-preprocessor">.requestWindowFeature</span>(Window<span class="hljs-preprocessor">.FEATURE</span>_NO_TITLE)<span class="hljs-comment">;  </span>
</code><ul class="pre-numbering"><li>1</li><li>2</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

2.如何加動畫

<code class="hljs avrasm has-numbering"> //設定dialog的 進出 動畫  
        getDialog()<span class="hljs-preprocessor">.getWindow</span>()<span class="hljs-preprocessor">.setWindowAnimations</span>(R<span class="hljs-preprocessor">.style</span><span class="hljs-preprocessor">.animate</span>_dialog)<span class="hljs-comment">;  </span></code><ul class="pre-numbering"><li>1</li><li>2</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>
    http://blog.csdn.net/lmj623565791/article/details/37815413

3.如何把dialog fragment選擇的值傳遞給activity
介面回撥

4.設定DialogFragment 的寬高
設定DialogFragment 的寬高,在 onCreatView中設定是沒有效果的,需要在onStart方法中設定。

<code class="hljs avrasm has-numbering">@Override  
    public void onStart() {  
        <span class="hljs-comment">/*設定對話方塊的寬高*/</span>  
        getDialog()<span class="hljs-preprocessor">.getWindow</span>()<span class="hljs-preprocessor">.getAttributes</span>()<span class="hljs-preprocessor">.width</span>=getResources()<span class="hljs-preprocessor">.getDisplayMetrics</span>()<span class="hljs-preprocessor">.widthPixels</span>-<span class="hljs-number">200</span><span class="hljs-comment">;  </span>
        <span class="hljs-comment">/*下面的方式設定也行*/</span>  
//      getDialog()<span class="hljs-preprocessor">.getWindow</span>()<span class="hljs-preprocessor">.setLayout</span>(getResources()<span class="hljs-preprocessor">.getDisplayMetrics</span>()<span class="hljs-preprocessor">.widthPixels</span>-<span class="hljs-number">200</span>, getDialog()<span class="hljs-preprocessor">.getWindow</span>()<span class="hljs-preprocessor">.getAttributes</span>()<span class="hljs-preprocessor">.height</span>)<span class="hljs-comment">;  </span>
        super<span class="hljs-preprocessor">.onStart</span>()<span class="hljs-comment">;  </span>
    }  </code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

5.推薦的用法

<code class="hljs java has-numbering">    <span class="hljs-javadoc">/**
     * 這種封裝方式非常的好,可以給給外界提供一個數據訪問的入口
     *
     *<span class="hljs-javadoctag"> @return</span>
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> DialogFragmentTest <span class="hljs-title">getInstance</span>(List<DialogFragmentTestDemo> demoList) {
        DialogFragmentTest dialogFragmentTest = <span class="hljs-keyword">new</span> DialogFragmentTest();
        Bundle b = <span class="hljs-keyword">new</span> Bundle();
        b.putSerializable(<span class="hljs-string">"demoList"</span>, (Serializable) demoList);
        dialogFragmentTest.setArguments(b);
        <span class="hljs-keyword">return</span> dialogFragmentTest;
    }
</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

例子:

dialogFragment:

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DialogFragmentTest</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">DialogFragment</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">View</span>.<span class="hljs-title">OnClickListener</span> {</span>

    <span class="hljs-keyword">private</span> GridView mGridview;
    <span class="hljs-keyword">private</span> ImageView mCloseDialog;
    <span class="hljs-keyword">private</span> List<DialogFragmentTestDemo> demoList;
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String DIALOGFRAGMENTTEST = <span class="hljs-string">"dialogfragmenttest"</span>;
    <span class="hljs-keyword">private</span> CallBack mCallBack;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCallBack</span>(CallBack callBack) {
        mCallBack = callBack;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">CallBack</span> {</span>
        <span class="hljs-keyword">void</span> getChoicedTxt(String str);
    }

    <span class="hljs-javadoc">/**
     * 這種封裝方式非常的好,可以給給外界提供一個數據訪問的入口
     *
     *<span class="hljs-javadoctag"> @return</span>
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> DialogFragmentTest <span class="hljs-title">getInstance</span>(List<DialogFragmentTestDemo> demoList) {
        DialogFragmentTest dialogFragmentTest = <span class="hljs-keyword">new</span> DialogFragmentTest();
        Bundle b = <span class="hljs-keyword">new</span> Bundle();
        b.putSerializable(<span class="hljs-string">"demoList"</span>, (Serializable) demoList);
        dialogFragmentTest.setArguments(b);
        <span class="hljs-keyword">return</span> dialogFragmentTest;
    }


    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
        <span class="hljs-keyword">this</span>.setCancelable(<span class="hljs-keyword">true</span>);
    }

    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onStart</span>() {
        <span class="hljs-keyword">super</span>.onStart();
        <span class="hljs-comment">// 設定dialog的layout</span>
        DisplayMetrics dm = <span class="hljs-keyword">new</span> DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
        WindowManager.LayoutParams layoutParams = getDialog().getWindow().getAttributes();
        layoutParams.width = dm.widthPixels;
        layoutParams.height = layoutParams.WRAP_CONTENT;
        layoutParams.gravity = Gravity.BOTTOM;
        getDialog().getWindow().setAttributes(layoutParams);
    }

    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> View <span class="hljs-title">onCreateView</span>(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        getDialog().getWindow().setWindowAnimations(R.style.animate_dialog);
        View view = inflater.inflate(R.layout.dialogfragment_test, container);
        mGridview = (GridView) view.findViewById(R.id.gdv_content);
        mCloseDialog = (ImageView) view.findViewById(R.id.cancel_dialog);
        mCloseDialog.setOnClickListener(<span class="hljs-keyword">this</span>);
        handleArgs();
        getDialog().getWindow().setBackgroundDrawable(<span class="hljs-keyword">new</span> ColorDrawable(Color.WHITE));
        <span class="hljs-keyword">return</span> view;
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">handleArgs</span>() {
        Bundle bundle = getArguments();
        demoList = (List<DialogFragmentTestDemo>) bundle.getSerializable(<span class="hljs-string">"demoList"</span>);
        GridViewAdapter gridViewAdapter = <span class="hljs-keyword">new</span> GridViewAdapter(getActivity(), demoList);
        mGridview.setAdapter(gridViewAdapter);

        mGridview.setOnItemClickListener(<span class="hljs-keyword">new</span> AdapterView.OnItemClickListener() {
            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onItemClick</span>(AdapterView<?> parent, View view, <span class="hljs-keyword">int</span> position, <span class="hljs-keyword">long</span> id) {
                Toast.makeText(getActivity(), demoList.get(position).getStr(), Toast.LENGTH_LONG).show();
                mCallBack.getChoicedTxt(demoList.get(position).getStr());
            }
        });

    }

    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onClick</span>(View v) {
        <span class="hljs-keyword">switch</span> (v.getId()) {
            <span class="hljs-keyword">case</span> R.id.cancel_dialog:
                dismissDialog();
                <span class="hljs-keyword">break</span>;
            <span class="hljs-keyword">default</span>:
        }

    }


    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">dismissDialog</span>() {
        android.app.Fragment prev = getFragmentManager().findFragmentByTag(DIALOGFRAGMENTTEST);
        <span class="hljs-keyword">if</span> (prev != <span class="hljs-keyword">null</span>) {
            DialogFragment df = (DialogFragment) prev;
            df.dismiss();
        }
    }



}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li><li>54</li><li>55</li><li>56</li><li>57</li><li>58</li><li>59</li><li>60</li><li>61</li><li>62</li><li>63</li><li>64</li><li>65</li><li>66</li><li>67</li><li>68</li><li>69</li><li>70</li><li>71</li><li>72</li><li>73</li><li>74</li><li>75</li><li>76</li><li>77</li><li>78</li><li>79</li><li>80</li><li>81</li><li>82</li><li>83</li><li>84</li><li>85</li><li>86</li><li>87</li><li>88</li><li>89</li><li>90</li><li>91</li><li>92</li><li>93</li><li>94</li><li>95</li><li>96</li><li>97</li><li>98</li><li>99</li><li>100</li><li>101</li></ul><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a target=_blank href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

Activity:

<code class="hljs java has-numbering"> <span class="hljs-keyword">final</span> Button viewById = (Button) findViewById(R.id.btn_dialogfragment_test);
        viewById.setOnClickListener(<span class="hljs-keyword">new</span> View.OnClickListener() {
            <span class="hljs-annotation">@Override</span>
            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onClick</span>(View v) {
                ArrayList<DialogFragmentTestDemo> demos = <span class="hljs-keyword">new</span> ArrayList<DialogFragmentTestDemo>();
                <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">3</span>; i++) {
                    DialogFragmentTestDemo demo = <span class="hljs-keyword">new</span> DialogFragmentTestDemo();
                    demo.setStr(<span class="hljs-string">"我是"</span> + i);
                    demos.add(demo);
                }
                ;
                DialogFragmentTest instance = DialogFragmentTest.getInstance(demos);
                instance.setCallBack(<span class="hljs-keyword">new</span> DialogFragmentTest.CallBack() {
                    <span class="hljs-annotation">@Override</span>
                    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">getChoicedTxt</span>(String str) {
                        viewById.setText(str);
                    }
                });
                instance.show(getFragmentManager(), DialogFragmentTest.DIALOGFRAGMENTTEST);
            }
        });</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a target=_blank href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>

效果:
這裡寫圖片描述