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