!!!最佳应用场景:
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>
效果: