簡述
本文將簡述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 和全面屏手機,如上代碼已經給出。