检测导航栏可见性



我正在尝试检查导航栏的可见性。在三星Galaxy S8上,我可以切换导航栏可见性。

我尝试了许多不同的方法来检查可见性,但是它们都无法在Galaxy S8上使用。

一些示例:(无论显示什么或隐藏,它们都将始终返回相同的值)

ViewConfiguration.get(getBaseContext()).hasPermanentMenuKey()总是返回false KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK)总是返回false KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME)总是返回true

即使弄清楚导航栏高度(我如何以编程方式获得Android导航栏的高度和宽度?)

也许这对某人很有用。用户可以隐藏导航栏,因此检测可见性的最佳方法是订阅此事件。它有效。

 object NavigationBarUtils {
    // Location of navigation bar
    const val LOCATION_BOTTOM = 0
    const val LOCATION_RIGHT = 1
    const val LOCATION_LEFT = 2
    const val LOCATION_NONE = 3
    fun addLocationListener(activity: Activity, listener: (location: Int) -> Unit) {
        ViewCompat.setOnApplyWindowInsetsListener(activity.window.decorView) { view, insets ->
            val location = when {
                insets.systemWindowInsetBottom != 0 -> LOCATION_BOTTOM
                insets.systemWindowInsetRight != 0 -> LOCATION_RIGHT
                insets.systemWindowInsetLeft != 0 -> LOCATION_LEFT
                else -> LOCATION_NONE
            }
            listener(location)
            ViewCompat.onApplyWindowInsets(view, insets)
        }
    }
}

由于写作时唯一的答案是kotlin,这是Java替代方案:

import android.content.res.Resources;
import android.support.v4.view.OnApplyWindowInsetsListener;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.WindowInsetsCompat;
import android.view.View;
public class NavigationBar {
    final int BOTTOM = 0;
    final int RIGHT = 1;
    final int LEFT = 2;
    final int NONE = 3;
    private int LOCATION = NONE;
    private View view;
    NavigationBar(View view) {
        this.view = view;
    }
    int getNavBarLocation() {
        ViewCompat.setOnApplyWindowInsetsListener(view, new OnApplyWindowInsetsListener() {
            public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
                if (insets.getSystemWindowInsetBottom() != 0)
                    LOCATION = BOTTOM;
                else if (insets.getSystemWindowInsetRight() != 0)
                    LOCATION = RIGHT;
                else if (insets.getSystemWindowInsetLeft() != 0)
                    LOCATION = LEFT;
                else
                    LOCATION = NONE;
                return insets;
            }
        });
        return LOCATION;
    }
    int getNavBarHeight() {
        Resources resources = view.getResources();
        int resourceId = resources.getIdentifier(
                "navigation_bar_height", "dimen", "android");
        if (resourceId > 0)
            return resources.getDimensionPixelSize(resourceId);
        return 0;
    }
}

我还包括如何获得高度,因为那通常是下一步。

在您的活动中,您将使用基于视图的参考来调用方法:

    NavigationBar navigationBar = new NavigationBar(snackbarLayout);
    if (navigationBar.getNavBarLocation() == navigationBar.BOTTOM) {
        FrameLayout.LayoutParams parentParams =
                (FrameLayout.LayoutParams) snackbarLayout.getLayoutParams();
        parentParams.setMargins(0, 0, 0, 0 - navigationBar.getNavBarHeight());
        snackbarLayout.setLayoutParams(parentParams);
    }

(此示例是基于不一致的Snackbar边缘的常见问题)

最新更新