文章目录
一、前言
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 显示的 ViewgetContentView()获得 PopupWindow 显示的 ViewshowAsDropDown(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)设置动画效果
范例
作为基础教程,很多方法就不深入了,我们直接上最简单的代码吧
- 创建一个 空的 Android 项目
cn.twle.android.PopupWindow
- 修改
activity_main.xml
创建一个按钮弹出PopupWindow``````<?xml version="1.0" encoding="utf-8" ?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="16dp"android:orientation="vertical"><Buttonandroid:id="@+id/btn_pop"android:text="弹出 PopupWindow"android:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout>
- 创建一个悬浮框弹出的动画,在
res
新建一个目录anim
,然后在res/anim
目录下新建一个文件anim_pop.xml``````<?xml version="1.0" encoding="utf-8"?><setxmlns:android="http://schemas.android.com/apk/res/android"><alphaandroid:fromAlpha="0"android:toAlpha="1"android:duration="2000"></alpha></set>
- 然后创建悬浮框的布局,在
res/layout
目录下新建文件popwin_layout.xml``````<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/btn_web"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="5dp"android:text="简单教程"android:textSize="18sp"/><Buttonandroid:id="@+id/btn_wap"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="5dp"android:text="简单编程"android:textSize="18sp"/></LinearLayout>
- 修改
MainActivity.java``````packagecn.twle.android.popupwindow;importandroid.graphics.drawable.ColorDrawable;importandroid.support.v7.app.AppCompatActivity;importandroid.os.Bundle;importandroid.view.LayoutInflater;importandroid.view.MotionEvent;importandroid.view.ViewGroup;importandroid.view.View;importandroid.widget.Button;importandroid.widget.PopupWindow;importandroid.widget.Toast;importandroid.content.Context;publicclassMainActivityextendsAppCompatActivity{privateContext mContext;@OverrideprotectedvoidonCreate(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(newView.OnClickListener(){@OverridepublicvoidonClick(View v){initPopWindow(v);}});}privatevoidinitPopWindow(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,宽高finalPopupWindow popWindow =newPopupWindow(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(newView.OnTouchListener(){@OverridepublicbooleanonTouch(View v,MotionEvent event){returnfalse;// 这里如果返回true的话,touch事件将被拦截// 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss}}); popWindow.setBackgroundDrawable(newColorDrawable(0x00000000));//要为popWindow设置一个背景才有效//设置 popupWindow 显示的位置,参数依次是参照 View,x轴的偏移量,y轴的偏移量 popWindow.showAsDropDown(v,50,0);//设置 popupWindow 里的按钮的事件 btn_web.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(View v){Toast.makeText(MainActivity.this,"你点击了简单教程",Toast.LENGTH_SHORT).show();}}); btn_wap.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(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(newOnKeyListener(){@OverridepublicbooleanonKey(View v,int keyCode,KeyEvent event){// TODO Auto-generated method stubif(keyCode ==KeyEvent.KEYCODE_DPAD_RIGHT){returntrue;}returnfalse;}});
参考
Android PopupWindow
Android PopupWindow 的使用和分析
Android PopupWindow详解
版权归原作者 Fu_Lin_ 所有, 如有侵权,请联系我们删除。