凌霄的博客
popwindow,一篇就够啦
popwindow,一篇就够啦

popwindow,一篇就够啦

Android 中的弹窗基本有两种,一种是AlertDialog,另一种是PopupWindow,AlertDialog的显示位置是固定的,PopWindow 的显示位置是我们可以设置和调整的。在项目中使用哪一个,就看具体的需求了。

popwindow的主要函数

构造函数
//方法一:  
public PopupWindow (Context context)  
//方法二:  
public PopupWindow(View contentView)  
//方法三:  
public PopupWindow(View contentView, int width, int height)  
//方法四:  
public PopupWindow(View contentView, int width, int height, boolean focusable)

上面有四个构造函数,但是生成一个PopupWindow最基本的三个条件是一定要设置的:View contentView,int width, int height,如果要使用第一个,可以用一下的方法:

View contentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.popuplayout, null);  
PopupWindwo popWnd = PopupWindow (context);  
popWnd.setContentView(contentView);  
popWnd.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);  
popWnd.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); 
显示函数
showAsDropDown(View anchor):    
showAsDropDown(View anchor, int xoff, int yoff):  
showAtLocation(View parent, int gravity, int x, int y):

前面两个方法都是指定相对某个控件的位置,不过第二个方法可以设置偏移量。第三个方式可以指定相对父控件的位置,Gravity.TOP和Gravity.RIGHT等等。

其他函数
public void setFocusable(boolean focusable)  
public void setTouchable(boolean touchable)  
public void setOutsideTouchable(boolean touchable)  
public void setBackgroundDrawable(Drawable background)  

这些函数可以说顾名思义,通过名字就知道它的作用了。主要讲一下第三个函数和最后一个,有时侯我们希望触摸PopupWindow 以外区域就隐藏PopupWindow,理论上我们只需要调用 setOutsideTouchable(ture)设置为ture就可以了,但是实际上只设置这个属性是不行的,必须设置背景,也就是说要和setBackgroundDrawable(Drawable background)同时使用才有效。

popwindow的简单示例

下面做一个简单的示例演示如何使用popwindow:

如图所示,我们动手做一个类似qq的popwindow。

首先是布局文件,问题不大:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical">
    <TextView
        android:id="@+id/pop_update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"
        android:textColor="#000"
        android:text="版本更新"
        android:background="@drawable/pop_bottom_text"
        android:padding="10dp"/>
    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="#e5e3e4"
        android:layout_alignParentTop="true"/>
    <TextView
        android:id="@+id/pop_feedback"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"
        android:textColor="#000"
        android:text="反馈"
        android:background="@drawable/pop_bottom_text"
        android:padding="10dp"/>
    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="#e5e3e4"
        android:layout_alignParentTop="true"/>
    <TextView
        android:id="@+id/pop_quit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"
        android:textColor="#000"
        android:text="退出"
        android:background="@drawable/pop_bottom_text"
        android:padding="10dp"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:background="#e5e3e4"
        android:layout_alignParentTop="true"/>
    <TextView
        android:id="@+id/pop_cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="20sp"
        android:textColor="#000"
        android:text="取消"
        android:background="@drawable/pop_bottom_text"
        android:padding="10dp"/>
</LinearLayout>

显示预览效果:

https://s1.ax1x.com/2018/06/06/C7jQQs.png

接下来是代码:

private void showPopupWindow() {
        //设置contentView
        View contentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.pop_pp_bottom, null);
        mPopWindow = new PopupWindow(contentView,
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT, true);
        mPopWindow.setContentView(contentView);
        //设置各个控件的点击响应
        TextView tv1 = contentView.findViewById(R.id.pop_update);
        TextView tv2 = contentView.findViewById(R.id.pop_feedback);
        TextView tv3 = contentView.findViewById(R.id.pop_quit);
        TextView tv4 = contentView.findViewById(R.id.pop_cancel);
        //显示PopupWindow
        mPopWindow.setBackgroundDrawable(new BitmapDrawable());
        View rootview = LayoutInflater.from(MainActivity.this)
                .inflate(R.layout.activity_main, null);
        mPopWindow.showAtLocation(rootview, Gravity.BOTTOM, 0, 0);
    }

上效果图:

http://oqz3bypff.bkt.clouddn.com/popwindow/pop1.gif

嗯,是成功显示出来了,但是背景怎么没有变?等等动画呢?你tm动画都没有还好意思拿出来?

http://omsaa4hdo.bkt.clouddn.com/face/01E8A62C3D0C704BF2E481FB170F1D77.jpg

大兄弟不要慌,这个问题很easy解决,就设置一个背景度的事儿+补间动画。

设置背景透明度

先看设置背景透明度的方法:

/**
     * 设置添加屏幕的背景透明度
     * @param bgAlpha
     */
    public void backgroundAlpha(float bgAlpha) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = bgAlpha; //0.0-1.0
        getWindow().setAttributes(lp);
    }

然后在showPopupWindow函数最前面加上:

backgroundAlpha(0.5f);

重写popwindow的setOnDismissListener方法监听是否被dismiss了,如果被dismiss了需要改变回原来的颜色:

mPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                backgroundAlpha(1);
            }
        });
设置动画

显示动画:

<set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="@android:integer/config_shortAnimTime"
            android:fromXDelta="0"
            android:fromYDelta="100%p"
            android:interpolator="@android:anim/accelerate_decelerate_interpolator"
            android:toXDelta="0"
            android:toYDelta="0"/>
</set>

隐藏动画:

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:toXDelta="0"
        android:toYDelta="100%p" />
</set>

然后在style里添加相应的style:

<!--popwindow anim-->
    <style name="contextMenuAnim" parent="@android:style/Animation.Activity">
        <item name="android:windowEnterAnimation">@anim/pop_bottom_enter</item>
        <item name="android:windowExitAnimation">@anim/pop_bottom_exit</item>
    </style>

最后给popwindow设置动画效果:

//动画效果
        mPopWindow.setAnimationStyle(R.style.contextMenuAnim);

贴上改变之后的代码:

private void showPopupWindow() {
        backgroundAlpha(0.5f);
        //设置contentView
        View contentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.pop_pp_bottom, null);
        mPopWindow = new PopupWindow(contentView,
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT, true);
        //动画效果
        mPopWindow.setAnimationStyle(R.style.contextMenuAnim);
        mPopWindow.setContentView(contentView);
        //设置各个控件的点击响应
        TextView tv1 = contentView.findViewById(R.id.pop_update);
        TextView tv2 = contentView.findViewById(R.id.pop_feedback);
        TextView tv3 = contentView.findViewById(R.id.pop_quit);
        TextView tv4 = contentView.findViewById(R.id.pop_cancel);
        //显示PopupWindow
        mPopWindow.setBackgroundDrawable(new BitmapDrawable());
        View rootview = LayoutInflater.from(MainActivity.this)
                .inflate(R.layout.activity_main, null);
        mPopWindow.showAtLocation(rootview, Gravity.BOTTOM, 0, 0);

        mPopWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                backgroundAlpha(1);
            }
        });

        tv1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        tv2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        tv3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        tv4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPopWindow.dismiss();
            }
        });
    }

改变之后的效果图:

http://oqz3bypff.bkt.clouddn.com/popwindow/pop2.gif

好了,本篇文章到此结束,以上就是PopupWindow的一些介绍和简单示例。要源码的同学,请看 Github地址:selfViewDemo

发表评论

textsms
account_circle
email

popwindow,一篇就够啦
popwindow,一篇就够啦 Android 中的弹窗基本有两种,一种是AlertDialog,另一种是PopupWindow,AlertDialog的显示位置是固定的,PopWindow 的显示位置是我们可以设置和调整的。在项目中…
扫描二维码继续阅读
2018-06-10