android原生 PopupWindow 的基本使用

Posted Fu_Lin_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android原生 PopupWindow 的基本使用相关的知识,希望对你有一定的参考价值。

文章目录

一、前言

android 中的弹窗基本有两种,一种是 AlertDialog,另一种是 PopupWindow,AlertDialog 的显示位置是固定的,PopWindow 的显示位置是我们可以设置和调整的,因此,像项目中的一些场景如:某个功能的提示说明、点击按钮在按钮上方或者下方弹出菜单、新功能弹窗引导等。

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设置宽高,也可以在构造方法那里指定好宽高,除了可
setFocusable(true)设置焦点,PopupWindow 弹出后,所有的触屏和物理按键都由 PopupWindow 处理。其他任何事件的响应都必须发生在PopupWindow消失之后,(home 等系统层面的事件除外)所以,当 PopupWindow 出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出 activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back PopupWindow都会消失,必须在PopupWindow设置了背景的情况下
setAnimationStyle(int)设置动画效果

范例

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

  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 显示的位置,参数依次是参照 View,x轴的偏移量,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();
                
            );
        
    
    

设置popupWindow的按键监听

用自定以的View的PopupWindow的时候,例如其中有两个按钮,一个响应向左按键,一个响应向右按键。所以要加一个按键监听,或者有时候要监听扫码枪的扫码完成监听也行

但是在popupWindow所在的Activity里监听,在popupWindow弹出时候,是不会触发

修改的地方就是在popupWindow主View 上,我这里变量为View popView,设置一个参数,如下

ps 这里的主View popView 就是上述代码的 View view = LayoutInflater.from(mContext).inflate(R.layout.popwin_layout, null, false);
popView = view;

popView.setFocusableInTouchMode(true);

这样就可以添加popupWindow的按键监听事件了,如下:

popView.setOnKeyListener(new OnKeyListener() 

	@Override
	public boolean onKey(View v, int keyCode, KeyEvent event) 
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) 
			return true;
		
		return false;
	
);

参考

Android PopupWindow

Android PopupWindow 的使用和分析

Android PopupWindow详解

以上是关于android原生 PopupWindow 的基本使用的主要内容,如果未能解决你的问题,请参考以下文章

android原生 PopupWindow 的基本使用

android原生 PopupWindow 的基本使用

Android原生控件 -- PopupWindow(选项菜单)

Android 使用PopupWindow实现弹出更多的菜单

Android-PopupWindow

Android PopupWindow使用方法小结