Android PopupWindow 悬浮框

Android PopupWindow (悬浮框) 是一个弹出窗口控件,可以用来显示任意 View,而且会浮动在当前 activity 的顶部,一般用于悬浮在其它 UI 控件旁边,如果你经常使用过 QQ ,那么一定见过,就是在某个列表上长按弹出的那个

和 AlertDialog 对话框不同的是,PopupWindow 的位置可以是随意的

而且 AlertDialog 是非堵塞线程的,而 PopupWindow 则是堵塞线程的

PopupWindow

可以通过 XML 代码来创建一个悬浮框,还可以通过实例化 PopupWindow 来实现,不过,这货的构造方法也太多了吧

构造函数

PopupWindow()

PopupWindow(Context context)

PopupWindow(Context context, AttributeSet attrs)

PopupWindow(Context context, AttributeSet attrs, int defStyleAttr)

PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

PopupWindow(View contentView)

PopupWindow(int width, int height)

PopupWindow(View contentView, int width, int height)

PopupWindow(View contentView, int width, int height, boolean focusable)

参数简直就是简单明了,这里就不再解释了

方法

这货的构造方法很多,但是,它的方法更多...泪崩了,我们只挑几个重要的讲讲

方法 说明
setContentView(View contentView) 设置 PopupWindow 显示的 View
getContentView() 获得 PopupWindow 显示的 View
showAsDropDown(View anchor) 相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff) 相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y) 相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移 parent这个参数只要是activity中的view就可以了!
setWidth/setHeight 设置宽高,也可以在构造方法那里指定好宽高,除了可以写具体的值,还可以用WRAP_CONTENT或MATCH_PARENT,popupWindow的width和height属性直接和第一层View相对应。
setFocusable(true) 设置焦点,PopupWindow 弹出后,所有的触屏和物理按键都由 PopupWindow 处理。其他任何事件的响应都必须发生在PopupWindow消失之后,(home 等系统层面的事件除外)
所以,当 PopupWindow 出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出 activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back PopupWindow都会消失,必须在PopupWindow设置了背景的情况下
setAnimationStyle(int) 设置动画效果

范例

作为基础教程,很多方法就不深入了,我们直接上最简单的代码吧


效果图上没有三角形,因为我不想用图片来解决,等后面学了 Canvas 再弄一次

  1. 创建一个 空的 Android 项目 cn.twle.android.PopupWindow

  2. 修改 activity_main.xml 创建一个按钮弹出 PopupWindow

    <?xml version="1.0" encoding="utf-8" ?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        android:orientation="vertical" >
    
        <Button 
            android:id="@+id/btn_pop"
            android:text="弹出 PopupWindow"
            android:layout_width="match_parent" 
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    
  3. 创建一个悬浮框弹出的动画,在 res 新建一个目录 anim ,然后在 res/anim 目录下新建一个文件 anim_pop.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <alpha android:fromAlpha="0"
            android:toAlpha="1"
            android:duration="2000">
        </alpha>
    </set>
    
  4. 然后创建悬浮框的布局,在 res/layout 目录下新建文件 popwin_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/btn_web"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="简单教程"
            android:textSize="18sp" />
    
        <Button
            android:id="@+id/btn_wap"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="简单编程"
            android:textSize="18sp" />
    
    </LinearLayout>
    
  5. 修改 MainActivity.java

    package cn.twle.android.popupwindow;
    
    import android.graphics.drawable.ColorDrawable;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.ViewGroup;
    import android.view.View;
    
    import android.widget.Button;
    import android.widget.PopupWindow;
    import android.widget.Toast;
    
    import android.content.Context;
    
    public class MainActivity extends AppCompatActivity {
    
        private Context mContext;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mContext = MainActivity.this;
    
            Button btn_pop = (Button) findViewById(R.id.btn_pop);
            btn_pop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    initPopWindow(v);
                }
            });
        }
    
        private void initPopWindow(View v) {
            View view = LayoutInflater.from(mContext).inflate(R.layout.popwin_layout, null, false);
    
            Button btn_web = (Button) view.findViewById(R.id.btn_web);
            Button btn_wap = (Button) view.findViewById(R.id.btn_wap);
    
            //1.构造一个PopupWindow,参数依次是加载的 View,宽高
    
            final PopupWindow popWindow = new PopupWindow(view,
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
    
            popWindow.setAnimationStyle(R.anim.anim_pop);  //设置加载动画
    
            //这些为了点击非PopupWindow区域PopupWindow会消失的,如果没有下面的
            //代码的话,你会发现,当你把PopupWindow显示出来了,无论你按多少次后退键
            //PopupWindow并不会关闭,而且退不出程序,加上下述代码可以解决这个问题
    
            popWindow.setTouchable(true);
            popWindow.setTouchInterceptor(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return false;
                    // 这里如果返回true的话touch事件将被拦截
                    // 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss
                }
            });
    
            popWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));    //要为popWindow设置一个背景才有效
    
            //设置 popupWindow 显示的位置,参数依次是参照 Viewx轴的偏移量y轴的偏移量
            popWindow.showAsDropDown(v, 50, 0);
    
            //设置 popupWindow 里的按钮的事件
            btn_web.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "你点击了简单教程", Toast.LENGTH_SHORT).show();
                }
            });
            btn_wap.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(MainActivity.this, "你点击了简单编程", Toast.LENGTH_SHORT).show();
                    popWindow.dismiss();
                }
            });
        }
    }
    

参考文档

  1. Android PopupWindow

  2. Android PopupWindow 的使用和分析

  3. Android PopupWindow详解

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.