android 透明状态栏方法及其适配键盘上推(二)

在上一篇文章中介绍了一种设置透明状态栏及其适配键盘上推得方法。但是上一篇介绍的方法中有个缺点,就是不能消除掉statusbar的阴影。很多手机如(三星,Nexus都带有阴影)。即使我用了:

<android.support.design.widget.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       app:elevation="0dp"
       android:background="@android:color/transparent"
       android:theme="@style/AppTheme.AppBarOverlay">

       <android.support.v7.widget.Toolbar
           android:id="@+id/toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           android:background="@android:color/transparent"
           app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

  还是不能消除阴影。那怎么办呢?这里介绍一种我觉得还不错的方法,思路是:不用toolbar,直接通过代码设置界面为透明statusbar,在每个界面里增加一个statusbar高度的view用来适配界面的显示,否则界面最顶端会有部分被statusbar覆盖。

方法如下:

1. 修改您应用里每个界面里的最顶端的布局:

    <RelativeLayout
        android:id="@+id/total_tile_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RelativeLayout
            android:id="@+id/actionbar_tile_bg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </RelativeLayout>

       <!--titlebar的其他布局-->
</RelativeLayout>

2. 在activity的onCreate方法中(最好写在baseActivity里),增加如下代码,设置为透明statusbar同时清除背景阴影。

            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//透明状态栏
            // 状态栏字体设置为深色,SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 为SDK23增加
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

//            // 部分机型的statusbar会有半透明的黑色背景
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().setStatusBarColor(Color.TRANSPARENT);// SDK21

  

3.同时在activity的onCreate方法中(最好写在baseActivity里),调用initMarginTopWithStatusBarHeight方法

/**
     * 设置view的margintop高度为statusbar高度
     * @param view 就是上面的 actionbar_tile_bg 这个view
     * @param context
     */
public static void initMarginTopWithStatusBarHeight(View view,Context context){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null){
            view.setVisibility(View.VISIBLE);
            RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(view.getLayoutParams());
            rl.topMargin = getStatusBarHeight(context);
            view.setLayoutParams(rl);
        }else{
            view.setVisibility(View.GONE);
        }
    }

这样就可以实现6.0以上的机型statusbar为透明且没有阴影(6.0以下的没有测试过,我这个应用的需求就是要求6.0以上,有兴趣的同学可以去测试下)。

但是这样设置后,用上一篇的适配键盘上推或是虚拟按键的显示和隐藏适配就不行了,需要重新设置。

增加一个util类:

public class AndroidBug5497Workaround {

    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (final Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(final Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
            mChildOfContent = content.getChildAt(0);
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                public void onGlobalLayout() {
                    possiblyResizeChildOfContent(activity);
                }
            });
            frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
        }

    }

    private void possiblyResizeChildOfContent(Activity activity) {
        int usableHeightNow = computeUsableHeight();

        if (usableHeightNow != usableHeightPrevious) {

            int resourceId = activity.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
            //获取NavigationBar的高度
            int navigateHeight = activity.getResources().getDimensionPixelSize(resourceId);
            boolean hasSoftNavigateBar = navigationBarExist2(activity);
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4) || hasSoftNavigateBar) {
                if (heightDifference == 0){
                    heightDifference = navigateHeight;
                }
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return r.bottom;
    }

    /**
     * 判断是否虚拟按键,这个方法最管用
     * @param activity
     * @return
     */
    private boolean navigationBarExist2(Activity activity) {
        WindowManager windowManager = activity.getWindowManager();
        Display d = windowManager.getDefaultDisplay();

        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            d.getRealMetrics(realDisplayMetrics);
        }

        int realHeight = realDisplayMetrics.heightPixels;
        int realWidth = realDisplayMetrics.widthPixels;

        DisplayMetrics displayMetrics = new DisplayMetrics();
        d.getMetrics(displayMetrics);

        int displayHeight = displayMetrics.heightPixels;
        int displayWidth = displayMetrics.widthPixels;

        return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
    }

}

  在activity里onCreate里调用:

        AndroidBug5497Workaround.assistActivity(this);

  

OK,这两篇是我在开发过程中遇到的问题,记录并分享。

  

时间: 2024-10-12 04:54:56

android 透明状态栏方法及其适配键盘上推(二)的相关文章

android 透明状态栏方法及其适配键盘上推(一)

android的状态栏(statusBar)版本的差异化比较大.在android 4.4 以上和5.x可以设置状态栏背景颜色,但是不可以设置状态栏中字和图标的颜色.而系统默认的statusbar的字体和图标颜色为白色.如果在6.0以下的要实现透明状态栏(也就是把整个界面延伸到statusbar),就要考虑到如果您的应用背景颜色为白色的时候,会出现statusbar里的内容都看不清楚,这一点暂时是没办法去适配的.但是6.0以上的是既能修改statusbar的背景颜色,也可以修改statusbar的

Android透明状态栏

Android透明状态栏只有在4.4之后有. 其中设置有两种方式: 1. if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //透明状态栏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //透明导航栏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_

Android透明状态栏。适用于 4.4 以上及 5.0以上设备

概述 有时候我们想在 andorid 手机上实现一种 跨越 顶部状态栏的效果,比如一张图片直接显示在 状态栏内.比如下图: 这个页面里有张图片,这个图片显示在整个页面的上部分.状态栏是 漂浮在这个图片上的. 实现透明状态栏的方法 适配Android 4.4 +的方法: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { Window window = activity.getWindow(); // Translucent sta

Android 透明状态栏&amp;着色状态栏

Android 5.0 及以上实现方式(android在5.0之后引入Material Design 实现方式相对简单) 透明状态栏,背景浸入状态栏 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } 在布局文件中View 默认f

Android 透明状态栏

if(VERSION.SDK_INT >= VERSION_CODES.KITKAT) {    //4.4以上                                 //透明状态栏                                 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);                                 //透明导航栏        

【Android】透明状态栏在App中的实现与接口设计

By Sodino 文章目录 1. 认识透明状态栏 2. 透明状态栏Api及特性 3. 设置透明状态栏 4. 处理消失的系统状态栏区域 5. fitsSystemWindows 6. Activity中的接口设计 7. Fragment中的接口设计 8. 白色Titlebar的处理 9. 小米 与 魅族 与 (莫名其妙的)华为 10. 腾讯优测UTest GitHub源码:TransparentStatusbar源码中分两个app TestBasic: 透明状态栏实现的示例,方便debug 白色

Android 透明的状态栏有渐变的阴影效果

前言 欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处: CSDN:http://www.csdn.net 雨季o莫忧离:http://blog.csdn.net/luckkof 正文 状态栏透明后有渐变的阴影效果,如何去除? 这是google default设计,如果桌面壁纸是白色的时候比较明显,这个渐进的效果是通过背景图来设置的,在frameworks/base/packages/systemui/res/ 里面drawable-hdpi(如果是其

Android最佳实践之SystemBar状态栏全版本适配方案

前言 自从MD设计规范出来后,关于系统状态栏的适配越受到关注,因为MD在5.0以后把系统状态栏的颜色改为可由开发者配置的,而在5.0之前则无法指定状态栏的颜色,所以这篇就说说使用Toolbar对系统状态栏的适配策略 主流App的适配效果 手Q在这方面适配非常好,将标题栏和状态栏合为一起了,和iOS效果一模一样,如下: 4.4.5.0+ 4.4以下版本 4.4以下版本则是系统默认的黑色状态栏,因为4.4以下没办法对状态栏进行改变和配置. 关于手Q的适配,对4.4以上所有版本都保留着一致的UI效果,

透明状态栏(StatusBar)的全适配

透明状态栏(StatusBar)的全适配 状态栏指定android手机上顶部显示手机状态信息的位置. 透明状态栏是android 自4.4开始新加入的功能,他可以是状态栏根据我们自己想要的颜色进行定义,使titleBar能够和状态栏融为一体,增加沉浸感. 实现中遇到的阻碍 因为状态栏是在4.4加入的,所以在4.4以前的系统上无法实现.现在世面上的手机android4.4一下的占比不是很大,所以不是太影响. 网上有很多关于透明状态栏实现的技术博客,以及我之前的博客透明状态栏(沉浸式状态栏)中,实现