简述
本文将简述popupWindow的使用技巧
基础用法效果
pop_below_head.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:paddingTop="18dp"
android:paddingBottom="18dp"
android:text="标题"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="希望弹出该内容放置于标题头部之下"
android:layout_width="match_parent"
android:layout_height="40dp" />
<View
android:layout_margin="10dp"
android:background="@color/red0"
android:layout_gravity="center_horizontal"
android:layout_width="100dp"
android:layout_height="20dp"/>
</LinearLayout>
</FrameLayout>
于头部下显示dialog
// 初始化popup
private void initPopHead(){
View view = LayoutInflater.from(this).inflate(R.layout.pop_below_head, null, false);
mPopupWindow = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
// 设置popup获取焦点
// 解决外部点击获取状态 isShowing都是false的问题
mPopupWindow.setFocusable(true);
mPopupWindow.update();
// 设置点击外部关闭
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setContentView(view);
}
// 点击事件设置隐藏与显示
headView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mPopupWindow.isShowing()){
mPopupWindow.dismiss();
}else {
mPopupWindow.showAsDropDown(headView);
}
}
});
显示效果
好了,已经完成了第一步,让popupwindow显示在我们所指定的布局下面。后续我们需要进行一些优化,比如我们常见的一些顶部筛选效果。需要有遮层而且也是有动画效果的,如下图所示。
进行优化
以下是我自定义的弹窗体,全面蒙层效果含有从底部进入从顶部退出的动画效果。
/**
* Created by apple on 2019-09-11.
* description:适配全面屏解决版本过高,popupWindow的位置不在控件下方的问题
*/
public class LargePopupWindow extends PopupWindow {
private View mRootView;
private Context context;
private Animation animationIn, animationOut;
private boolean isDismiss = false;
public LargePopupWindow(Context context, View view) {
// 设置宽高
super(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
//设置有焦点
setContentView(view);
setFocusable(true);
//设置点击外部可消失
setOutsideTouchable(true);
// 设置窗口样式
this.setAnimationStyle(R.style.WindowStyle);
setBackgroundDrawable(new ColorDrawable(Color.argb(123, 0, 0, 0)));
update();
this.context = context;
this.mRootView = view;
initViews();
}
private void initViews() {
animationIn = AnimationUtils.loadAnimation(context, R.anim.photo_album_show);
animationOut = AnimationUtils.loadAnimation(context, R.anim.photo_album_dismiss);
mRootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
}
@Override
public void showAsDropDown(View anchor) {
if(Build.VERSION.SDK_INT >= 24) {
Rect rect = new Rect();
anchor.getGlobalVisibleRect(rect);
// 适配全面屏....
// 解决全面屏手机使用顶部弹窗带来的问题
if (DisplayHelper.isNavigationBarExist((Activity) context)){
int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom;
setHeight(h);
}else {
//全面屏手机需要获取真实高度....
int h = DisplayHelper.getRealScreenSize(context)[1] - rect.bottom;
setHeight(h);
}
}
super.showAsDropDown(anchor);
mRootView.startAnimation(animationIn);
}
@Override
public void dismiss() {
if (isDismiss){
return;
}
isDismiss = true;
mRootView.startAnimation(animationOut);
animationOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
isDismiss = false;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
dismiss4Pop();
} else {
LargePopupWindow.super.dismiss();
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
/**
* 在android4.1.1和4.1.2版本关闭PopWindow
*/
private void dismiss4Pop() {
new Handler().post(new Runnable() {
@Override
public void run() {
LargePopupWindow.super.dismiss();
}
});
}
}
效果展示
总结
popupwindow应用场景还是挺广的,诸如我们右上角弹出的可供选择的多个菜单,列表长按右击弹出选择菜单,我们顶部的可筛选列表等都是可以用popupwindow来实现的。
我们通过
设置 setFocusable(true) ,让popupWindow把焦点从外部抢夺过来,那么我们点击外部的布局即可获取其开关状态
setOutsideTouchable(true) 设置点击外部让其关闭
setAnimationStyle(),设置窗体的动画效果
setBackgroundDrawable() 设置其整体的灰色蒙层背景
还有,注意适配高版本即 >=24 和全面屏手机,如上代码已经给出。