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>

效果:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值