0
点赞
收藏
分享

微信扫一扫

android获取状态栏高度

水沐由之 2022-12-16 阅读 172

公司项目中使用了popWindow,并且需求指明了popWindow必须是和Activity类似的全屏模式,并且从页面底部弹出!
当popWindow所有设计完毕后,从底部弹出popWindow,发现设置在popWindow的上的titlebar一部分被压入状态栏的底部了,也就是说全屏是全屏了,但是超过了应有的部分!
解决方案:
为了达到良好的兼容性,我们可以如下变现代码

​​?​​


1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21

​​/**​​


​​* 用于获取状态栏的高度。​​


​​* ​​


​​* @return 返回状态栏高度的像素值。​​


​​*/​​


​​private​​ ​​int​​ ​​getStatusBarHeight() {​​


​​int​​ ​​statusBarHeight = ​​ ​​0​​ ​​;​​


​​try​​ ​​{​​


​​Class<?> c = Class.forName(​​ ​​"com.android.internal.R$dimen"​​ ​​);​​


​​Object o = c.newInstance();​​


​​Field field = c.getField(​​ ​​"status_bar_height"​​ ​​);​​


​​int​​ ​​x = (Integer) field.get(o);​​


​​statusBarHeight = getResources().getDimensionPixelSize(x);​​


​​} ​​ ​​catch​​ ​​(Exception e) {​​


​​e.printStackTrace();​​


​​Rect frame = ​​ ​​new​​ ​​Rect();​​


​​getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);​​


​​statusBarHeight = frame.top;​​


​​}​​


​​return​​ ​​statusBarHeight;​​


​​}​​


还可以使用Resource对象获取(推荐这种方式)

​​?​​


1


2


3


4


5


6


7


8

​​private​​ ​​int​​ ​​getStatusBarHeight() {​​


​​int​​ ​​result = ​​ ​​0​​ ​​;​​


​​int​​ ​​resourceId = getResources().getIdentifier(​​ ​​"status_bar_height"​​ ​​, ​​ ​​"dimen"​​ ​​, ​​ ​​"android"​​ ​​);​​


​​if​​ ​​(resourceId > ​​ ​​0​​ ​​) {​​


​​result = res.getDimensionPixelSize(resourceId);​​


​​}​​


​​return​​ ​​result;​​


​​}​​


-----------------------------------2015-01-29 更新--------------------------------------
公司有测试人员发现,FlymeOS4.x/Android4.4.4出现 了问题,让人一头雾水,因此,这里把问题再次改正一下,目前Android4.4.4的系统不多,只检测到魅族的FlymeOS4.x有问题,所以对FlymeOS着重处理一下。
手写判断是否是Flyme OsS 4.x.x

​​?​​


1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18

​​private​​ ​​boolean​​ ​​isFlymeOs4x()​​


​​{​​


​​String sysVersion = android.os.Build.VERSION.RELEASE;​​


​​if​​ ​​(​​ ​​"4.4.4"​​ ​​.equals(sysVersion))​​


​​{​​


​​String sysIncrement = android.os.Build.VERSION.INCREMENTAL;​​


​​String displayId = android.os.Build.DISPLAY;​​


​​if​​ ​​(!TextUtils.isEmpty(sysIncrement))​​


​​{​​


​​return​​ ​​sysIncrement.contains(​​ ​​"Flyme_OS_4"​​ ​​);​​


​​}​​


​​else​​


​​{​​


​​return​​ ​​displayId.contains(​​ ​​"Flyme OS 4"​​ ​​);​​


​​}​​


​​}​​


​​return​​ ​​false​​ ​​;​​


​​}​​


然后PopWindow改为

​​?​​


1


2


3


4


5


6


7


8


9


10

​​int​​ ​​statusBarHeight = getStatusBarHeight();​​


​​if​​ ​​(isFlymeOs4x())​​


​​{​​


​​searchFlightListWindow.setHeight(screenMetrics.heightPixels-statusBarHeight*​​ ​​2​​ ​​);​​


​​//至于这里为什么乘以2,我只能说,除了鬼鬼们,只有魅族自己知道,我是发现获得的StatusBarHeight偏小,所以乘以2,实践检验是正确的,但也很无语​​


​​searchFlightListWindow.showAtLocation(findViewById(R.id.main), Gravity.BOTTOM, ​​ ​​0​​ ​​, ​​ ​​0​​ ​​);​​


​​}​​ ​​else​​ ​​{​​


​​searchFlightListWindow.setHeight(screenMetrics.heightPixels-statusBarHeight);​​


​​searchFlightListWindow.showAtLocation(findViewById(R.id.main), Gravity.BOTTOM, ​​ ​​0​​ ​​, ​​ ​​0​​ ​​);​​


​​} ​​


----------------------------
View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
View contentView = getWindow().getDecorView().getChildAt(0);
View titleView = findViewById(Window.ID_ANDROID_CONTENT);
-------------------------2015-05-05更新,沉浸式状态栏---------------------------------

​​?​​


1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53


54


55


56


57


58


59


60


61


62


63


64


65


66


67


68


69


70


71


72


73


74


75


76


77


78


79


80


81


82


83


84


85


86


87


88


89


90


91


92


93


94


95


96


97


98


99


100


101


102


103


104


105


106


107


108


109


110


111


112


113


114


115


116


117


118


119


120


121


122


123


124


125


126


127


128


129


130


131


132


133


134


135


136


137


138


139


140


141


142


143


144


145


146


147


148


149


150


151


152


153


154


155


156


157


158


159


160


161


162


163


164


165


166


167


168


169


170


171


172


173


174


175


176


177


178


179


180


181


182


183


184


185


186


187


188


189


190


191


192


193


194


195


196


197


198


199


200


201


202


203


204


205


206


207


208


209


210


211


212


213


214


215


216


217


218


219


220


221


222


223


224


225


226


227


228


229


230


231


232


233


234


235


236


237


238


239


240


241


242


243


244


245


246


247


248


249


250


251


252


253


254


255


256


257


258


259


260


261


262


263


264


265


266


267


268


269


270


271


272


273


274


275


276


277


278


279


280


281


282


283


284


285


286


287


288


289


290


291


292


293


294


295


296


297


298


299


300


301


302


303


304


305


306


307


308


309


310


311


312


313


314


315


316


317


318


319


320


321


322


323


324


325


326


327


328


329


330


331


332


333


334


335


336


337


338


339


340


341


342


343


344


345


346


347


348


349


350


351


352


353


354


355


356


357


358


359


360


361


362


363


364


365


366


367


368


369


370


371


372


373


374


375


376


377


378


379


380


381


382


383


384


385


386


387


388


389


390


391


392


393


394


395


396


397


398


399


400


401


402


403


404


405


406


407


408


409


410


411


412


413


414


415


416


417


418


419


420


421


422


423


424


425


426


427


428


429


430


431


432


433


434


435


436


437


438


439


440


441


442


443


444


445


446


447


448


449


450


451


452


453


454


455


456


457


458


459


460


461


462


463


464


465


466


467


468


469


470


471


472


473


474


475


476


477


478


479


480


481


482


483


484


485


486


487


488


489


490


491


492


493


494


495


496


497


498


499


500


501


502


503


504


505


506


507


508


509


510


511


512


513


514


515


516


517


518


519


520


521


522


523


524


525


526


527


528


529


530


531


532


533


534


535


536


537


538


539


540


541


542


543


544


545


546

​​public​​ ​​class​​ ​​SystemBarTintManager {​​


​​/**​​


​​* The default system bar tint color value.​​


​​*/​​


​​public​​ ​​static​​ ​​final​​ ​​int​​ ​​DEFAULT_TINT_COLOR = ​​ ​​0x99000000​​ ​​;​​





​​private​​ ​​final​​ ​​SystemBarConfig mConfig;​​


​​private​​ ​​boolean​​ ​​mStatusBarAvailable;​​


​​private​​ ​​boolean​​ ​​mNavBarAvailable;​​


​​private​​ ​​boolean​​ ​​mStatusBarTintEnabled;​​


​​private​​ ​​boolean​​ ​​mNavBarTintEnabled;​​


​​private​​ ​​View mStatusBarTintView;​​


​​private​​ ​​View mNavBarTintView;​​


​​private​​ ​​static​​ ​​boolean​​ ​​sIsMiuiV6;​​


​​private​​ ​​static​​ ​​String sNavBarOverride = ​​ ​​null​​ ​​;​​





​​static​​ ​​{​​


​​Method methodGetter = ​​ ​​null​​ ​​;​​


​​try​​ ​​{​​


​​Class<?> sysClass = Class.forName(​​ ​​"android.os.SystemProperties"​​ ​​);​​


​​methodGetter = sysClass.getDeclaredMethod(​​ ​​"get"​​ ​​, String.​​ ​​class​​ ​​);​​


​​sIsMiuiV6 = ​​ ​​"V6"​​ ​​.equals((String) methodGetter.invoke(sysClass, ​​ ​​"ro.miui.ui.version.name"​​ ​​));​​


​​} ​​ ​​catch​​ ​​(Exception e) {​​


​​e.printStackTrace();​​


​​}​​ ​​finally​​ ​​{​​


​​if​​ ​​(methodGetter!=​​ ​​null​​ ​​)​​


​​{​​


​​try​​ ​​{​​


​​sNavBarOverride = (String) methodGetter.invoke(​​ ​​null​​ ​​, ​​ ​​"qemu.hw.mainkeys"​​ ​​);​​


​​} ​​ ​​catch​​ ​​(Exception e) {​​


​​e.printStackTrace();​​


​​sNavBarOverride = ​​ ​​null​​ ​​;​​


​​}​​


​​}​​


​​}​​


​​}​​


​​/**​​


​​* @param activity The host activity.​​


​​*/​​


​​@TargetApi​​ ​​(​​ ​​19​​ ​​)​​


​​public​​ ​​SystemBarTintManager(Activity activity) {​​








​​Window win = activity.getWindow();​​


​​ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();​​





​​if​​ ​​(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {​​


​​// check theme attrs​​


​​int​​ ​​[] attrs = {android.R.attr.windowTranslucentStatus,android.R.attr.windowTranslucentNavigation};​​


​​TypedArray a = activity.obtainStyledAttributes(attrs);​​


​​try​​ ​​{​​


​​mStatusBarAvailable = a.getBoolean(​​ ​​0​​ ​​, ​​ ​​false​​ ​​);​​


​​mNavBarAvailable = a.getBoolean(​​ ​​1​​ ​​, ​​ ​​false​​ ​​);​​


​​} ​​ ​​finally​​ ​​{​​


​​a.recycle();​​


​​}​​





​​// check window flags​​


​​WindowManager.LayoutParams winParams = win.getAttributes();​​


​​int​​ ​​bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;​​


​​if​​ ​​((winParams.flags & bits) != ​​ ​​0​​ ​​) {​​


​​mStatusBarAvailable = ​​ ​​true​​ ​​;​​


​​}​​


​​bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;​​


​​if​​ ​​((winParams.flags & bits) != ​​ ​​0​​ ​​) {​​


​​mNavBarAvailable = ​​ ​​true​​ ​​;​​


​​}​​


​​}​​





​​mConfig = ​​ ​​new​​ ​​SystemBarConfig(activity, mStatusBarAvailable, mNavBarAvailable);​​


​​// device might not have virtual navigation keys​​


​​if​​ ​​(!mConfig.hasNavigtionBar()) {​​


​​mNavBarAvailable = ​​ ​​false​​ ​​;​​


​​}​​





​​if​​ ​​(mStatusBarAvailable) {​​


​​setupStatusBarView(activity, decorViewGroup);​​


​​}​​


​​if​​ ​​(mNavBarAvailable) {​​


​​setupNavBarView(activity, decorViewGroup);​​


​​}​​





​​}​​





​​/**​​


​​* Enable tinting of the system status bar.​​


​​*​​


​​* @param enabled True to enable tinting, false to disable it (default).​​


​​*/​​


​​public​​ ​​void​​ ​​setStatusBarTintEnabled(​​ ​​boolean​​ ​​enabled) {​​


​​mStatusBarTintEnabled = enabled;​​


​​if​​ ​​(mStatusBarAvailable) {​​


​​mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);​​


​​}​​


​​}​​





​​/**​​


​​* set status bar darkmode​​


​​* @param darkmode​​


​​* @param activity​​


​​*/​​


​​public​​ ​​void​​ ​​setStatusBarDarkMode(​​ ​​boolean​​ ​​darkmode, Activity activity) {​​


​​if​​ ​​(sIsMiuiV6) {​​


​​Class<? ​​ ​​extends​​ ​​Window> clazz = activity.getWindow().getClass();​​


​​try​​ ​​{​​


​​int​​ ​​darkModeFlag = ​​ ​​0​​ ​​;​​


​​Class<?> layoutParams = Class.forName(​​ ​​"android.view.MiuiWindowManager$LayoutParams"​​ ​​);​​


​​Field field = layoutParams.getField(​​ ​​"EXTRA_FLAG_STATUS_BAR_DARK_MODE"​​ ​​);​​


​​darkModeFlag = field.getInt(layoutParams);​​


​​Method extraFlagField = clazz.getMethod(​​ ​​"setExtraFlags"​​ ​​, ​​ ​​int​​ ​​.​​ ​​class​​ ​​, ​​ ​​int​​ ​​.​​ ​​class​​ ​​);​​


​​extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : ​​ ​​0​​ ​​, darkModeFlag);​​


​​} ​​ ​​catch​​ ​​(Exception e) {​​


​​e.printStackTrace();​​


​​}​​


​​}​​


​​}​​





​​/**​​


​​* Enable tinting of the system navigation bar.​​


​​* @param enabled True to enable tinting, false to disable it (default).​​


​​*/​​


​​public​​ ​​void​​ ​​setNavigationBarTintEnabled(​​ ​​boolean​​ ​​enabled) {​​


​​mNavBarTintEnabled = enabled;​​


​​if​​ ​​(mNavBarAvailable) {​​


​​mNavBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);​​


​​}​​


​​}​​





​​/**​​


​​* Apply the specified color tint to all system UI bars.​​


​​*​​


​​* @param color The color of the background tint.​​


​​*/​​


​​public​​ ​​void​​ ​​setTintColor(​​ ​​int​​ ​​color) {​​


​​setStatusBarTintColor(color);​​


​​setNavigationBarTintColor(color);​​


​​}​​





​​/**​​


​​* Apply the specified drawable or color resource to all system UI bars.​​


​​*​​


​​* @param res The identifier of the resource.​​


​​*/​​


​​public​​ ​​void​​ ​​setTintResource(​​ ​​int​​ ​​res) {​​


​​setStatusBarTintResource(res);​​


​​setNavigationBarTintResource(res);​​


​​}​​





​​/**​​


​​* Apply the specified drawable to all system UI bars.​​


​​*​​


​​* @param drawable The drawable to use as the background, or null to remove it.​​


​​*/​​


​​public​​ ​​void​​ ​​setTintDrawable(Drawable drawable) {​​


​​setStatusBarTintDrawable(drawable);​​


​​setNavigationBarTintDrawable(drawable);​​


​​}​​





​​/**​​


​​* Apply the specified alpha to all system UI bars.​​


​​*​​


​​* @param alpha The alpha to use​​


​​*/​​


​​public​​ ​​void​​ ​​setTintAlpha(​​ ​​float​​ ​​alpha) {​​


​​setStatusBarAlpha(alpha);​​


​​setNavigationBarAlpha(alpha);​​


​​}​​





​​/**​​


​​* Apply the specified color tint to the system status bar.​​


​​*​​


​​* @param color The color of the background tint.​​


​​*/​​


​​public​​ ​​void​​ ​​setStatusBarTintColor(​​ ​​int​​ ​​color) {​​


​​if​​ ​​(mStatusBarAvailable) {​​


​​mStatusBarTintView.setBackgroundColor(color);​​


​​}​​


​​}​​





​​/**​​


​​* Apply the specified drawable or color resource to the system status bar.​​


​​*​​


​​* @param res The identifier of the resource.​​


​​*/​​


​​public​​ ​​void​​ ​​setStatusBarTintResource(​​ ​​int​​ ​​res) {​​


​​if​​ ​​(mStatusBarAvailable) {​​


​​mStatusBarTintView.setBackgroundResource(res);​​


​​}​​


​​}​​





​​/**​​


​​* Apply the specified drawable to the system status bar.​​


​​*​​


​​* @param drawable The drawable to use as the background, or null to remove it.​​


​​*/​​


​​@SuppressWarnings​​ ​​(​​ ​​"deprecation"​​ ​​)​​


​​public​​ ​​void​​ ​​setStatusBarTintDrawable(Drawable drawable) {​​


​​if​​ ​​(mStatusBarAvailable) {​​


​​mStatusBarTintView.setBackgroundDrawable(drawable);​​


​​}​​


​​}​​





​​/**​​


​​* Apply the specified alpha to the system status bar.​​


​​*​​


​​* @param alpha The alpha to use​​


​​*/​​


​​@TargetApi​​ ​​(​​ ​​11​​ ​​)​​


​​public​​ ​​void​​ ​​setStatusBarAlpha(​​ ​​float​​ ​​alpha) {​​


​​if​​ ​​(mStatusBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {​​


​​mStatusBarTintView.setAlpha(alpha);​​


​​}​​


​​}​​





​​/**​​


​​* Apply the specified color tint to the system navigation bar.​​


​​*​​


​​* @param color The color of the background tint.​​


​​*/​​


​​public​​ ​​void​​ ​​setNavigationBarTintColor(​​ ​​int​​ ​​color) {​​


​​if​​ ​​(mNavBarAvailable) {​​


​​mNavBarTintView.setBackgroundColor(color);​​


​​}​​


​​}​​





​​/**​​


​​* Apply the specified drawable or color resource to the system navigation bar.​​


​​*​​


​​* @param res The identifier of the resource.​​


​​*/​​


​​public​​ ​​void​​ ​​setNavigationBarTintResource(​​ ​​int​​ ​​res) {​​


​​if​​ ​​(mNavBarAvailable) {​​


​​mNavBarTintView.setBackgroundResource(res);​​


​​}​​


​​}​​





​​/**​​


​​* Apply the specified drawable to the system navigation bar.​​


​​*​​


​​* @param drawable The drawable to use as the background, or null to remove it.​​


​​*/​​


​​@SuppressWarnings​​ ​​(​​ ​​"deprecation"​​ ​​)​​


​​public​​ ​​void​​ ​​setNavigationBarTintDrawable(Drawable drawable) {​​


​​if​​ ​​(mNavBarAvailable) {​​


​​mNavBarTintView.setBackgroundDrawable(drawable);​​


​​}​​


​​}​​





​​/**​​


​​* Apply the specified alpha to the system navigation bar.​​


​​*​​


​​* @param alpha The alpha to use​​


​​*/​​


​​@TargetApi​​ ​​(​​ ​​11​​ ​​)​​


​​public​​ ​​void​​ ​​setNavigationBarAlpha(​​ ​​float​​ ​​alpha) {​​


​​if​​ ​​(mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {​​


​​mNavBarTintView.setAlpha(alpha);​​


​​}​​


​​}​​





​​/**​​


​​* Get the system bar configuration.​​


​​* @return The system bar configuration for the current device configuration.​​


​​*/​​


​​public​​ ​​SystemBarConfig getConfig() {​​


​​return​​ ​​mConfig;​​


​​}​​





​​/**​​


​​* Is tinting enabled for the system status bar?​​


​​* @return True if enabled, False otherwise.​​


​​*/​​


​​public​​ ​​boolean​​ ​​isStatusBarTintEnabled() {​​


​​return​​ ​​mStatusBarTintEnabled;​​


​​}​​





​​/**​​


​​* Is tinting enabled for the system navigation bar?​​


​​* @return True if enabled, False otherwise.​​


​​*/​​


​​public​​ ​​boolean​​ ​​isNavBarTintEnabled() {​​


​​return​​ ​​mNavBarTintEnabled;​​


​​}​​





​​private​​ ​​void​​ ​​setupStatusBarView(Context context, ViewGroup decorViewGroup) {​​


​​mStatusBarTintView = ​​ ​​new​​ ​​View(context);​​


​​LayoutParams params = ​​ ​​new​​ ​​LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight());​​


​​params.gravity = Gravity.TOP;​​


​​if​​ ​​(mNavBarAvailable && !mConfig.isNavigationAtBottom()) {​​


​​params.rightMargin = mConfig.getNavigationBarWidth();​​


​​}​​


​​mStatusBarTintView.setLayoutParams(params);​​


​​mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);​​


​​mStatusBarTintView.setVisibility(View.GONE);​​


​​decorViewGroup.addView(mStatusBarTintView);​​


​​}​​





​​private​​ ​​void​​ ​​setupNavBarView(Context context, ViewGroup decorViewGroup) {​​


​​mNavBarTintView = ​​ ​​new​​ ​​View(context);​​


​​LayoutParams params;​​


​​if​​ ​​(mConfig.isNavigationAtBottom()) {​​


​​params = ​​ ​​new​​ ​​LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight());​​


​​params.gravity = Gravity.BOTTOM;​​


​​} ​​ ​​else​​ ​​{​​


​​params = ​​ ​​new​​ ​​LayoutParams(mConfig.getNavigationBarWidth(), LayoutParams.MATCH_PARENT);​​


​​params.gravity = Gravity.RIGHT;​​


​​}​​


​​mNavBarTintView.setLayoutParams(params);​​


​​mNavBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);​​


​​mNavBarTintView.setVisibility(View.GONE);​​


​​decorViewGroup.addView(mNavBarTintView);​​


​​}​​





​​/**​​


​​* Class which describes system bar sizing and other characteristics for the current​​


​​* device configuration.​​


​​*​​


​​*/​​


​​public​​ ​​static​​ ​​class​​ ​​SystemBarConfig {​​





​​private​​ ​​static​​ ​​final​​ ​​String STATUS_BAR_HEIGHT_RES_NAME = ​​ ​​"status_bar_height"​​ ​​;​​


​​private​​ ​​static​​ ​​final​​ ​​String NAV_BAR_HEIGHT_RES_NAME = ​​ ​​"navigation_bar_height"​​ ​​;​​


​​private​​ ​​static​​ ​​final​​ ​​String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = ​​ ​​"navigation_bar_height_landscape"​​ ​​;​​


​​private​​ ​​static​​ ​​final​​ ​​String NAV_BAR_WIDTH_RES_NAME = ​​ ​​"navigation_bar_width"​​ ​​;​​


​​private​​ ​​static​​ ​​final​​ ​​String SHOW_NAV_BAR_RES_NAME = ​​ ​​"config_showNavigationBar"​​ ​​;​​





​​private​​ ​​final​​ ​​boolean​​ ​​mTranslucentStatusBar;​​


​​private​​ ​​final​​ ​​boolean​​ ​​mTranslucentNavBar;​​


​​private​​ ​​final​​ ​​int​​ ​​mStatusBarHeight;​​


​​private​​ ​​final​​ ​​int​​ ​​mActionBarHeight;​​


​​private​​ ​​final​​ ​​boolean​​ ​​mHasNavigationBar;​​


​​private​​ ​​final​​ ​​int​​ ​​mNavigationBarHeight;​​


​​private​​ ​​final​​ ​​int​​ ​​mNavigationBarWidth;​​


​​private​​ ​​final​​ ​​boolean​​ ​​mInPortrait;​​


​​private​​ ​​final​​ ​​float​​ ​​mSmallestWidthDp;​​





​​private​​ ​​SystemBarConfig(Activity activity, ​​ ​​boolean​​ ​​translucentStatusBar, ​​ ​​boolean​​ ​​traslucentNavBar) {​​


​​Resources res = activity.getResources();​​


​​mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);​​


​​mSmallestWidthDp = getSmallestWidthDp(activity);​​


​​mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);​​


​​mActionBarHeight = getActionBarHeight(activity);​​


​​mNavigationBarHeight = getNavigationBarHeight(activity);​​


​​mNavigationBarWidth = getNavigationBarWidth(activity);​​


​​mHasNavigationBar = (mNavigationBarHeight > ​​ ​​0​​ ​​);​​


​​mTranslucentStatusBar = translucentStatusBar;​​


​​mTranslucentNavBar = traslucentNavBar;​​


​​}​​





​​@TargetApi​​ ​​(​​ ​​14​​ ​​)​​


​​private​​ ​​int​​ ​​getActionBarHeight(Context context) {​​


​​int​​ ​​result = ​​ ​​0​​ ​​;​​


​​if​​ ​​(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {​​


​​TypedValue tv = ​​ ​​new​​ ​​TypedValue();​​


​​context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, ​​ ​​true​​ ​​);​​


​​result = context.getResources().getDimensionPixelSize(tv.resourceId);​​


​​}​​


​​return​​ ​​result;​​


​​}​​





​​@TargetApi​​ ​​(​​ ​​14​​ ​​)​​


​​private​​ ​​int​​ ​​getNavigationBarHeight(Context context) {​​


​​Resources res = context.getResources();​​


​​int​​ ​​result = ​​ ​​0​​ ​​;​​


​​if​​ ​​(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {​​


​​if​​ ​​(!hasNavBar(context)) {​​


​​String key;​​


​​if​​ ​​(mInPortrait) {​​


​​key = NAV_BAR_HEIGHT_RES_NAME;​​


​​} ​​ ​​else​​ ​​{​​


​​key = NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME;​​


​​}​​


​​return​​ ​​getInternalDimensionSize(res, key);​​


​​}​​


​​}​​


​​return​​ ​​result;​​


​​}​​





​​@TargetApi​​ ​​(​​ ​​14​​ ​​)​​


​​private​​ ​​int​​ ​​getNavigationBarWidth(Context context) {​​


​​Resources res = context.getResources();​​


​​int​​ ​​result = ​​ ​​0​​ ​​;​​


​​if​​ ​​(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {​​


​​if​​ ​​(!hasNavBar(context)) ​​


​​{​​


​​return​​ ​​getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);​​


​​}​​


​​}​​


​​return​​ ​​result;​​


​​}​​





​​private​​ ​​int​​ ​​getInternalDimensionSize(Resources res, String key) {​​


​​int​​ ​​result = ​​ ​​0​​ ​​;​​


​​int​​ ​​resourceId = res.getIdentifier(key, ​​ ​​"dimen"​​ ​​, ​​ ​​"android"​​ ​​);​​


​​if​​ ​​(resourceId > ​​ ​​0​​ ​​) {​​


​​result = res.getDimensionPixelSize(resourceId);​​


​​}​​


​​return​​ ​​result;​​


​​}​​





​​@SuppressLint​​ ​​(​​ ​​"NewApi"​​ ​​)​​


​​private​​ ​​float​​ ​​getSmallestWidthDp(Activity activity) {​​


​​DisplayMetrics metrics = ​​ ​​new​​ ​​DisplayMetrics();​​


​​if​​ ​​(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {​​


​​activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);​​


​​} ​​ ​​else​​ ​​{​​


​​// TODO this is not correct, but we don't really care pre-kitkat​​


​​activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);​​


​​}​​


​​float​​ ​​widthDp = metrics.widthPixels / metrics.density;​​


​​float​​ ​​heightDp = metrics.heightPixels / metrics.density;​​


​​return​​ ​​Math.min(widthDp, heightDp);​​


​​}​​





​​/**​​


​​* Should a navigation bar appear at the bottom of the screen in the current​​


​​* device configuration? A navigation bar may appear on the right side of​​


​​* the screen in certain configurations.​​


​​*​​


​​* @return True if navigation should appear at the bottom of the screen, False otherwise.​​


​​*/​​


​​public​​ ​​boolean​​ ​​isNavigationAtBottom() {​​


​​return​​ ​​(mSmallestWidthDp >= ​​ ​​600​​ ​​|| mInPortrait);​​


​​}​​





​​/**​​


​​* Get the height of the system status bar.​​


​​*​​


​​* @return The height of the status bar (in pixels).​​


​​*/​​


​​public​​ ​​int​​ ​​getStatusBarHeight() {​​


​​return​​ ​​mStatusBarHeight;​​


​​}​​





​​/**​​


​​* Get the height of the action bar.​​


​​*​​


​​* @return The height of the action bar (in pixels).​​


​​*/​​


​​public​​ ​​int​​ ​​getActionBarHeight() {​​


​​return​​ ​​mActionBarHeight;​​


​​}​​





​​/**​​


​​* Does this device have a system navigation bar?​​


​​*​​


​​* @return True if this device uses soft key navigation, False otherwise.​​


​​*/​​


​​public​​ ​​boolean​​ ​​hasNavigtionBar() {​​


​​return​​ ​​mHasNavigationBar;​​


​​}​​





​​/**​​


​​* Get the height of the system navigation bar.​​


​​*​​


​​* @return The height of the navigation bar (in pixels). If the device does not have​​


​​* soft navigation keys, this will always return 0.​​


​​*/​​


​​public​​ ​​int​​ ​​getNavigationBarHeight() {​​


​​return​​ ​​mNavigationBarHeight;​​


​​}​​





​​/**​​


​​* Get the width of the system navigation bar when it is placed vertically on the screen.​​


​​*​​


​​* @return The width of the navigation bar (in pixels). If the device does not have​​


​​* soft navigation keys, this will always return 0.​​


​​*/​​


​​public​​ ​​int​​ ​​getNavigationBarWidth() {​​


​​return​​ ​​mNavigationBarWidth;​​


​​}​​





​​/**​​


​​* Get the layout inset for any system UI that appears at the top of the screen.​​


​​*​​


​​* @param withActionBar True to include the height of the action bar, False otherwise.​​


​​* @return The layout inset (in pixels).​​


​​*/​​


​​public​​ ​​int​​ ​​getPixelInsetTop(​​ ​​boolean​​ ​​withActionBar) {​​


​​return​​ ​​(mTranslucentStatusBar ? mStatusBarHeight : ​​ ​​0​​ ​​) + (withActionBar ? mActionBarHeight : ​​ ​​0​​ ​​);​​


​​}​​





​​/**​​


​​* Get the layout inset for any system UI that appears at the bottom of the screen.​​


​​*​​


​​* @return The layout inset (in pixels).​​


​​*/​​


​​public​​ ​​int​​ ​​getPixelInsetBottom() {​​


​​if​​ ​​(mTranslucentNavBar && isNavigationAtBottom()) {​​


​​return​​ ​​mNavigationBarHeight;​​


​​} ​​ ​​else​​ ​​{​​


​​return​​ ​​0​​ ​​;​​


​​}​​


​​}​​





​​/**​​


​​* Get the layout inset for any system UI that appears at the right of the screen.​​


​​*​​


​​* @return The layout inset (in pixels).​​


​​*/​​


​​public​​ ​​int​​ ​​getPixelInsetRight() {​​


​​if​​ ​​(mTranslucentNavBar && !isNavigationAtBottom()) {​​


​​return​​ ​​mNavigationBarWidth;​​


​​} ​​ ​​else​​ ​​{​​


​​return​​ ​​0​​ ​​;​​


​​}​​


​​}​​





​​private​​ ​​boolean​​ ​​hasNavBar(Context context) {​​


​​Resources res = context.getResources();​​


​​int​​ ​​resourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME, ​​ ​​"bool"​​ ​​, ​​ ​​"android"​​ ​​);​​


​​if​​ ​​(resourceId != ​​ ​​0​​ ​​) {​​


​​boolean​​ ​​hasNav = res.getBoolean(resourceId);​​


​​// check override flag (see static block)​​


​​if​​ ​​(​​ ​​"1"​​ ​​.equals(sNavBarOverride)) {​​


​​hasNav = ​​ ​​false​​ ​​;​​


​​} ​​ ​​else​​ ​​if​​ ​​(​​ ​​"0"​​ ​​.equals(sNavBarOverride)) {​​


​​hasNav = ​​ ​​true​​ ​​;​​


​​}​​


​​return​​ ​​hasNav;​​


​​} ​​ ​​else​​ ​​{ ​​ ​​// fallback​​


​​return​​ ​​!hasPermanentMenuKey(context);​​


​​}​​


​​}​​





​​private​​ ​​boolean​​ ​​hasPermanentMenuKey(Context cxt) {​​


​​try​​ ​​{​​


​​WindowManager wm = (WindowManager) cxt.getSystemService(Context.WINDOW_SERVICE);​​





​​ViewConfiguration config = ViewConfiguration.get(cxt);​​


​​Field menuKeyField = ViewConfiguration.​​ ​​class​​


​​.getDeclaredField(​​ ​​"sHasPermanentMenuKey"​​ ​​);​​


​​if​​ ​​(menuKeyField != ​​ ​​null​​ ​​) {​​


​​menuKeyField.setAccessible(​​ ​​true​​ ​​);​​


​​return​​ ​​menuKeyField.getBoolean(config);​​


​​}​​


​​} ​​ ​​catch​​ ​​(Exception e) {​​


​​e.printStackTrace();​​


​​}​​





​​return​​ ​​false​​ ​​;​​


​​}​​





​​}​​





​​}​​

举报

相关推荐

0 条评论