Get the height of the bottom navigation bar, there are many tripartite libraries have been implemented, but some libraries have not been updated for several years. There are indeed some problems in the use of some libraries, I here extract the tripartite library EasyFloat library in the library of two classes tested by other models are no problems, now release these two classes:

DisplayUtils

object DisplayUtils {
    private const val TAG = "DisplayUtils--->"

    fun px2dp(context: Context, pxVal: Float): Int {
        val density = context.resources.displayMetrics.density
        return (pxVal / density + 0.5 f).toInt()
    }

    fun dp2px(context: Context, dpVal: Float): Int {
        val density = context.resources.displayMetrics.density
        return (dpVal * density + 0.5 f).toInt()
    }

    fun px2sp(context: Context, pxValue: Float): Int {
        val fontScale = context.resources.displayMetrics.scaledDensity
        return (pxValue / fontScale + 0.5 f).toInt()
    }

    fun sp2px(context: Context, spValue: Float): Int {
        val fontScale = context.resources.displayMetrics.scaledDensity
        return (spValue * fontScale + 0.5 f).toInt()
    }

    /** * Gets the screen width (display width, which may be smaller than the physical pixel value in landscape) */
    fun getScreenWidth(context: Context): Int {
        val manager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val metrics = DisplayMetrics()
        manager.defaultDisplay.getRealMetrics(metrics)
        return if (context.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
            metrics.widthPixels
        } else {
            metrics.widthPixels - getNavigationBarCurrentHeight(context)
        }
    }

    /** * Gets the screen height (the height of the physical pixel value) */
    fun getScreenHeight(context: Context) = getScreenSize(context).y

    /** * Get the screen width */
    fun getScreenSize(context: Context) = Point().apply {
        val windowManager = context.getSystemService(Service.WINDOW_SERVICE) as WindowManager
        val display = windowManager.defaultDisplay
        display.getRealSize(this)}/** * Get the status bar height */
    fun getStatusBarHeight(context: Context): Int {
        var result = 0
        val resources = context.resources
        val resourceId = resources.getIdentifier("status_bar_height"."dimen"."android")
        if (resourceId > 0) result = resources.getDimensionPixelSize(resourceId)
        return result
    }

    fun statusBarHeight(view: View) = getStatusBarHeight(view.context.applicationContext)

    /** * Gets the true height of the navigation bar (which may not be shown) */
    fun getNavigationBarHeight(context: Context): Int {
        var result = 0
        val resources = context.resources
        val resourceId =
            resources.getIdentifier("navigation_bar_height"."dimen"."android")
        if (resourceId > 0) result = resources.getDimensionPixelSize(resourceId)
        return result
    }

    /** * Gets the current height of the navigation bar */
    fun getNavigationBarCurrentHeight(context: Context) =
        if (hasNavigationBar(context)) getNavigationBarHeight(context) else 0

    /** * Check whether ** is displayed in the virtual navigation bar@paramContext Context object *@returnTrue (displays virtual navigation), false(does not display or does not support virtual navigation) */
    fun hasNavigationBar(context: Context) = when {
        getNavigationBarHeight(context) == 0 -> false
        RomUtils.checkIsHuaweiRom() && isHuaWeiHideNav(context) -> false
        RomUtils.checkIsMiuiRom() && isMiuiFullScreen(context) -> false
        RomUtils.checkIsVivoRom() && isVivoFullScreen(context) -> false
        else -> isHasNavigationBar(context)
    }

    /** * does not contain the effective height of the navigation bar (there is no navigation bar, or the height of the navigation bar has been removed) */
    fun rejectedNavHeight(context: Context): Int {
        val point = getScreenSize(context)
        if (point.x > point.y) return point.y
        return point.y - getNavigationBarCurrentHeight(context)
    }

    /** * Whether huawei mobile phone hides the virtual navigation bar *@returnTrue means hidden, false means not hidden */
    private fun isHuaWeiHideNav(context: Context) =
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            Settings.System.getInt(context.contentResolver, "navigationbar_is_min".0)}else {
            Settings.Global.getInt(context.contentResolver, "navigationbar_is_min".0)}! =0

    /** * Whether to enable gesture operation on xiaomi phone *@returnFalse indicates that the virtual NavigationBar is used, true indicates that the gesture is used, and the default is false */
    private fun isMiuiFullScreen(context: Context) =
        Settings.Global.getInt(context.contentResolver, "force_fsg_nav_bar".0) != 0

    /** * Whether to enable gesture operation in Vivo mobile phone *@returnFalse indicates that the virtual NavigationBar is used, true indicates that the gesture is used, and the default is false */
    private fun isVivoFullScreen(context: Context): Boolean =
        Settings.Secure.getInt(context.contentResolver, "navigation_gesture_on".0) != 0

    /** * Other phones are judged according to whether the real screen height is the same as the display height */
    private fun isHasNavigationBar(context: Context): Boolean {
        val windowManager: WindowManager =
            context.getSystemService(Service.WINDOW_SERVICE) as WindowManager
        val d = windowManager.defaultDisplay

        val realDisplayMetrics = DisplayMetrics()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            d.getRealMetrics(realDisplayMetrics)
        }
        val realHeight = realDisplayMetrics.heightPixels
        val realWidth = realDisplayMetrics.widthPixels

        val displayMetrics = DisplayMetrics()
        d.getMetrics(displayMetrics)
        val displayHeight = displayMetrics.heightPixels
        val displayWidth = displayMetrics.widthPixels

        // The display height + navigation bar height is greater than the physical height. In this case, the navigation bar is directly disabled by default
        if (displayHeight + getNavigationBarHeight(context) > realHeight) return false

        return realWidth - displayWidth > 0 || realHeight - displayHeight > 0}}Copy the code
RomUtils
object RomUtils {

    private const val TAG = "RomUtils--->"

    /** * Get the emui version number */
    @JvmStatic
    fun getEmuiVersion(a): Double {
        try {
            val emuiVersion = getSystemProperty("ro.build.version.emui")
            valversion = emuiVersion!! .substring(emuiVersion.indexOf("_") + 1)
            return version.toDouble()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return 4.0
    }

    @JvmStatic
    fun getSystemProperty(propName: String): String? {
        val line: String
        var input: BufferedReader? = null
        try {
            val p = Runtime.getRuntime().exec("getprop $propName")
            input = BufferedReader(InputStreamReader(p.inputStream), 1024)
            line = input.readLine()
            input.close()
        } catch (ex: Exception) {
            Log.e(TAG, "Unable to read sysprop $propName", ex)
            return null
        } finally {
            if(input ! =null) {
                try {
                    input.close()
                } catch (e: IOException) {
                    Log.e(TAG, "Exception while closing InputStream", e)
                }
            }
        }
        return line
    }

    fun checkIsHuaweiRom(a) = Build.MANUFACTURER.contains("HUAWEI")

    fun checkIsMiuiRom(a) = !TextUtils.isEmpty(getSystemProperty("ro.miui.ui.version.name"))

    fun checkIsMeizuRom(a): Boolean {
        val systemProperty = getSystemProperty("ro.build.display.id")
        return if (TextUtils.isEmpty(systemProperty)) false
        elsesystemProperty!! .contains("flyme") || systemProperty.toLowerCase().contains("flyme")}fun checkIs360Rom(a): Boolean =
        Build.MANUFACTURER.contains("QiKU") || Build.MANUFACTURER.contains("360")

    fun checkIsOppoRom(a) =
        Build.MANUFACTURER.contains("OPPO") || Build.MANUFACTURER.contains("oppo")

    fun checkIsVivoRom(a) =
        Build.MANUFACTURER.contains("VIVO") || Build.MANUFACTURER.contains("vivo")}Copy the code

Dependencies: DisplayUtils since RomUtils