美文网首页
Android PopupWindow实现弹出菜单

Android PopupWindow实现弹出菜单

作者: itfitness | 来源:发表于2022-03-29 11:04 被阅读0次

目录

效果展示

实现代码

布局文件window_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <LinearLayout
        android:background="@color/white"
        android:orientation="vertical"
        android:layout_width="@dimen/dp_120"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/tv_menuOne"
            android:text="菜单1"
            android:padding="@dimen/dp_10"
            android:gravity="center"
            android:textSize="@dimen/sp_14"
            android:textColor="@color/black"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <View
            android:background="@color/gray_e"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_1"/>
        <TextView
            android:id="@+id/tv_menuTwo"
            android:text="菜单2"
            android:padding="@dimen/dp_10"
            android:gravity="center"
            android:textSize="@dimen/sp_14"
            android:textColor="@color/black"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <View
            android:background="@color/gray_e"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_1"/>
        <TextView
            android:id="@+id/tv_menuThree"
            android:text="菜单3"
            android:padding="@dimen/dp_10"
            android:gravity="center"
            android:textSize="@dimen/sp_14"
            android:textColor="@color/black"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</FrameLayout>

Activity中

public class MenuActivity extends AppCompatActivity {
    private TextView tvMenu;
    private PopupWindow menuPopupWindow;
    private RelativeLayout rlContainer;
    private ValueAnimator menuAnimator;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu);
        tvMenu = (TextView) findViewById(R.id.tv_menu);
        rlContainer = (RelativeLayout) findViewById(R.id.rl_container);
        tvMenu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showTimeFilterWindow();
            }
        });
    }


    private void showTimeFilterWindow() {
        if (menuPopupWindow == null) {
            View view = getLayoutInflater().inflate(R.layout.window_menu, null);
            TextView tvMenuOne = (TextView) view.findViewById(R.id.tv_menuOne);
            TextView tvMenuTwo = (TextView) view.findViewById(R.id.tv_menuTwo);
            TextView tvMenuThree = (TextView) view.findViewById(R.id.tv_menuThree);
            menuPopupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
            menuPopupWindow.setOutsideTouchable(true);
        }
        if (menuPopupWindow.isShowing()) {
            menuPopupWindow.dismiss();
        } else {
            if(menuAnimator == null){
                menuAnimator = ValueAnimator.ofFloat(0.1f, 1);
                menuAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        float animatedValue = (float) animation.getAnimatedValue();
                        menuPopupWindow.getContentView().setScaleX(animatedValue);
                        menuPopupWindow.getContentView().setScaleY(animatedValue);
                    }
                });
                menuAnimator.setDuration(200);
            }
            menuAnimator.start();
            int navigationBarHeightIfRoom = NavigationBarUtil.getNavigationBarHeightIfRoom(this);
            menuPopupWindow.showAtLocation(rlContainer, Gravity.END | Gravity.BOTTOM, rlContainer.getWidth() - tvMenu.getLeft(),rlContainer.getHeight() - tvMenu.getTop() + navigationBarHeightIfRoom);
        }

    }
}

这里重点是菜单位置的计算,案例的菜单展示在按钮的左边,所以首先我们让菜单展示在按钮父容器的右下角,然后根据按钮的位置算出偏移,另外为了适配虚拟按键这里加了一个获取虚拟按键高度的工具类,参照的是这篇文章的代码:Android获取虚拟按键高度(适配全面屏),代码如下:

public class NavigationBarUtil {
    /**
     * 获取虚拟按键的高度
     *      1. 全面屏下
     *          1.1 开启全面屏开关-返回0
     *          1.2 关闭全面屏开关-执行非全面屏下处理方式
     *      2. 非全面屏下
     *          2.1 没有虚拟键-返回0
     *          2.1 虚拟键隐藏-返回0
     *          2.2 虚拟键存在且未隐藏-返回虚拟键实际高度
     */
    public static int getNavigationBarHeightIfRoom(Context context) {
        if(navigationGestureEnabled(context)){
            return 0;
        }
        return getCurrentNavigationBarHeight(((Activity) context));
    }

    /**
     * 全面屏(是否开启全面屏开关 0 关闭  1 开启)
     *
     * @param context
     * @return
     */
    public static boolean navigationGestureEnabled(Context context) {
        int val = Settings.Global.getInt(context.getContentResolver(), getDeviceInfo(), 0);
        return val != 0;
    }

    /**
     * 获取设备信息(目前支持几大主流的全面屏手机,亲测华为、小米、oppo、魅族、vivo都可以)
     *
     * @return
     */
    public static String getDeviceInfo() {
        String brand = Build.BRAND;
        if(TextUtils.isEmpty(brand)) return "navigationbar_is_min";

        if (brand.equalsIgnoreCase("HUAWEI")) {
            return "navigationbar_is_min";
        } else if (brand.equalsIgnoreCase("XIAOMI")) {
            return "force_fsg_nav_bar";
        } else if (brand.equalsIgnoreCase("VIVO")) {
            return "navigation_gesture_on";
        } else if (brand.equalsIgnoreCase("OPPO")) {
            return "navigation_gesture_on";
        } else {
            return "navigationbar_is_min";
        }
    }

    /**
     * 非全面屏下 虚拟键实际高度(隐藏后高度为0)
     * @param activity
     * @return
     */
    public static int getCurrentNavigationBarHeight(Activity activity){
        if(isNavigationBarShown(activity)){
            return getNavigationBarHeight(activity);
        } else{
            return 0;
        }
    }

    /**
     * 非全面屏下 虚拟按键是否打开
     * @param activity
     * @return
     */
    public static boolean isNavigationBarShown(Activity activity){
        //虚拟键的view,为空或者不可见时是隐藏状态
        View view  = activity.findViewById(android.R.id.navigationBarBackground);
        if(view == null){
            return false;
        }
        int visible = view.getVisibility();
        if(visible == View.GONE || visible == View.INVISIBLE){
            return false ;
        }else{
            return true;
        }
    }

    /**
     * 非全面屏下 虚拟键高度(无论是否隐藏)
     * @param context
     * @return
     */
    public static int getNavigationBarHeight(Context context){
        int result = 0;
        int resourceId = context.getResources().getIdentifier("navigation_bar_height","dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
}

相关文章

网友评论

      本文标题:Android PopupWindow实现弹出菜单

      本文链接:https://www.haomeiwen.com/subject/opsvjrtx.html