Android 底部弹窗实现及使用技巧

发布时间:2023-05-14

一、概述

底部弹窗是移动应用中常见的UI组件之一,它能够展示出一些重要的信息或者提供功能入口,而且通常不会打断到用户的当前操作。在本文中,我们将介绍如何在安卓应用中实现一个底部弹窗并提供相应的使用技巧。

二、实现底部弹窗的常见方法

1. 使用DialogFragment

DialogFragmentandroid.support.v4.app 包中的一个类,它允许我们创建复杂的 Dialog,例如底部弹窗。我们可以在 DialogFragment 中添加一个布局文件,实现开发起来非常方便。下面是实现底部弹窗的步骤: 1)创建一个继承自 DialogFragment 的类 BottomDialogFragment

public class BottomDialogFragment extends DialogFragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_bottom_dialog, container, false);
        Button btnDismiss = (Button) view.findViewById(R.id.btn_dismiss);
        btnDismiss.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dismiss();
            }
        });
        return view;
    }
    @Override
    public void onStart() {
        super.onStart();
        getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        getDialog().getWindow().setGravity(Gravity.BOTTOM);
    }
}

2)创建一个布局文件 fragment_bottom_dialog.xml,并在其中添加需要展示的内容,例如按钮或者文字。

<?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="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="这是一个底部弹窗的例子" />
    <Button
        android:id="@+id/btn_dismiss"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="关闭" />
</LinearLayout>

3)在需要弹出底部弹窗的地方,实例化 BottomDialogFragment 并调用 show() 方法即可。

BottomDialogFragment bottomDialogFragment = new BottomDialogFragment();
bottomDialogFragment.show(getSupportFragmentManager(), "bottom_dialog_fragment");

2. 使用PopupMenu

PopupMenuandroid.widget 包中的一个弹出菜单 UI 控件,可以很方便地实现底部弹窗的效果。这种方式比起使用 DialogFragment 来说,更加轻量化、原生,因此也有其独特的优势。下面是实现底部弹窗的步骤: 1)创建一个继承自 PopupMenu 的类 BottomPopupWindow

public class BottomPopupWindow extends PopupMenu {
    public BottomPopupWindow(Context context, View anchorView) {
        super(context, anchorView, Gravity.BOTTOM);
    }
    @Override
    public void show() {
        super.show();
        setPopupWindowTouchModal(this, false);
    }
    public static void setPopupWindowTouchModal(PopupWindow popupWindow, boolean touchModal) {
        if (popupWindow == null) {
            return;
        }
        try {
            Method method = PopupWindow.class.getDeclaredMethod("setTouchModal", boolean.class);
            method.setAccessible(true);
            method.invoke(popupWindow, touchModal);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2)在需要弹出底部弹窗的地方,实例化 BottomPopupWindow,并添加需要展示的菜单项。

BottomPopupWindow bottomPopupWindow = new BottomPopupWindow(this, view);
bottomPopupWindow.getMenuInflater().inflate(R.menu.menu_bottom_popup, bottomPopupWindow.getMenu());
bottomPopupWindow.show();
bottomPopupWindow.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
    @Override
    public boolean onMenuItemClick(MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            case R.id.action_delete:
                Toast.makeText(MainActivity.this, "删除", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_share:
                Toast.makeText(MainActivity.this, "分享", Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_edit:
                Toast.makeText(MainActivity.this, "编辑", Toast.LENGTH_SHORT).show();
                break;
        }
        return false;
    }
});

三、使用技巧

1. 调整宽度

当底部弹窗包含较多内容时,可以调整其宽度以使其不会被内容撑满,这需要在 onStart() 方法中进行设置。

@Override
public void onStart() {
    super.onStart();
    getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}

2. 修改弹窗位置

可以使用 setGravity() 方法来设置弹窗在屏幕中的位置。例如,设置为底部居中:

getDialog().getWindow().setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);

3. 设置背景半透明

当底部弹窗弹出时,为了使其更加突出,可以对其背景进行一定程度的半透明设置。这可以通过在 BottomDialogFragmentonCreateView() 方法中设置其窗口特性实现。

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.bottom_dialog_fragment, container, false);
    getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    return view;
}

四、总结

本篇文章介绍了在安卓应用中实现底部弹窗的两种方式:使用 DialogFragment 和使用 PopupMenu,并提供了一些使用技巧。开发者可以根据实际情况,选择适合自己的方法进行实现,并结合相关技巧进行调整。