最接做需求的时候,碰到了 PopUpWindow,但是也没做过多了解,就是照搬别人的代码改改逻辑。后面视觉看了之后,说让我加一些动画效果,使用起来更加舒服。可是我看别人以前也没有写,于是就开始捣鼓 PopUpWindow。同时也写一篇文章记录下,后续忘了也可以查看。
相关方法解读 1)几个常用的构造方法我们在文档中可以看到,提供给我们的PopupWindow的构造方法有九种之多,这里只贴实际 开发中用得较多的几个构造方法:
public PopupWindow (Context context)
public PopupWindow(View contentView, int width, int height)
public PopupWindow(View contentView)
public PopupWindow(View contentView, int width, int height, boolean focusable)
参数就不用多解释了吧,contentView是PopupWindow显示的View,focusable是否显示焦点
2)常用的一些方法下面介绍几个用得较多的一些方法,其他的可自行查阅文档:
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等),可以设置偏移或无偏移 PS:parent这个参数只要是activity中的view就可以了!
setWidth/setHeight:设置宽高,也可以在构造方法那里指定好宽高, 除了可以写具体的值,还可以用WRAP_CONTENT或MATCH_PARENT, popupWindow的width和height属性直接和第一层View相对应。
setFocusable(true):设置焦点,PopupWindow弹出后,所有的触屏和物理按键都由PopupWindows 处理。其他任何事件的响应都必须发生在PopupWindow消失之后,(home 等系统层面的事件除外)。 比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出 activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back PopupWindow都会消失,必须在PopupWindow设置了背景的情况下 。
setAnimationStyle(int):设置动画效果
创建布局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:clipChildren="false" android:orientation="vertical"> <View android:id="@+id/empty_view" android:layout_width="match_parent" android:layout_height="100dp" android:layout_weight="1" /> <LinearLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="200dp" android:background="@color/colorPrimary" android:orientation="vertical" android:gravity="center_vertical"> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="60dp" android:text="test" /> </LinearLayout> </LinearLayout>
注意其中这行代码:
android:layout_weight="1"
由于其他 view 没有使用这个属性,默认为0,使用该属性的view将剩余的空间铺满。这样就相当于为我们设置了一个蒙层了。
写好布局后,需要将布局文件传到容器中去。
PopUpWindow 使用由于相关代码比较长,直接附上完整代码,方便大家查看。
完整代码如下:
public class TestActivity extends AppCompatActivity implements View.OnClickListener { private PopupWindow mPopupWindow; private ViewGroup mContentView; private Button mBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); mBtn = (Button) findViewById(R.id.result); mPopupWindow = new PopupWindow(this); mPopupWindow.setContentView(getContentView(this)); mPopupWindow.setHeight(ViewGroup.LayoutParams.MATCH_PARENT); mPopupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); mPopupWindow.setClippingEnabled(false); // 如果不设置PopupWindow的背景,有些版本就会出现一个问题:无论是点击外部区域还是Back键都无法dismiss弹框 mPopupWindow.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color .empty_view_background))); mPopupWindow.setOutsideTouchable(true); mPopupWindow.setFocusable(true); mPopupWindow.update(); mBtn.setOnClickListener(this); } /** * popup window view 初始化 * * @return View */ private View getContentView(Context ctx) { mContentView = (ViewGroup) LayoutInflater.from(ctx) .inflate(R.layout.popup, null); View emptyViewAbovePanel = mContentView.findViewById(R.id.empty_view); emptyViewAbovePanel.setOnClickListener(this); return mContentView; } @Override public void onClick(View v) { int i = v.getId(); if (i == R.id.empty_view) { Animation animation = AnimationUtils.loadAnimation(this, R.anim.pop_gone); mContentView.startAnimation(animation); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mPopupWindow.dismiss(); } @Override public void onAnimationRepeat(Animation animation) { } }); } else if (i == R.id.result) { mContentView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.pop_in)); mPopupWindow.showAsDropDown(mBtn, 50, 50); } } }
上面的代码设置了蒙层,出场入场的动画效果。
动画设置出场动画文件xml: