Android popupwindow技術儲備

簡述

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

項目地址

Android 彈窗案例總結(仿淘寶彈窗 鹹魚菜單 篩選列表)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章