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可以做出完全一樣的效果和位置。
- AlertDialog非阻塞式對話方塊:對話方塊的顯示不影響後臺任務的執行。 PopupWindow阻塞式對話方塊:對話方塊彈出後阻塞後臺任務執行,直到對話方塊消失。
- AlertDialog預設半透明背景,PopupWindow預設沒有半透明背景。 即Popupwindow不會給頁面其他的部分新增蒙層,而Dialog會。
- PopupWindow預設不響應Back鍵,除非設定pw.setBackgroundDrawable(new ColorDrawable(0x00000000));
- PopupWindow預設沒有標題,AlertDialog預設是有標題的,當然可以設定dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);取消標題。
- 二者顯示的時候都要設定Gravity。如果不設定,Dialog預設是Gravity.CENTER。
- 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>
效果: