沉浸式的封装(状态栏和底部导航同时实现)

我在使用沉浸式的时候遇到很多坑,最典型的就是兼容性问题,有的效果5.0以上很容易实现,但在4.4使用同样的方法就不可取了,有的机型底部有虚拟导航按钮,有的却没有,所有我们不仅要区分手机的版本,也要区分底部是否有导航栏。只有在4.4及以上才有沉浸式这么一说的,在本次封装中,我们要同时实现顶部状态栏和底部导航栏的沉浸式,需要的童鞋可以当做工具类,直接copy到自己的BaseActivity中进行使用。

之前写过实现沉浸式方法的文章,详情见http://blog.csdn.net/sinat_35159441/article/details/76839484 ,首先我们来分析一下,不是所有的Activity都需要实现沉浸式,所以设置沉浸式的方法没必要做成抽象的,需要使用的Activity重写一下即可。该方法实现步骤如下:

  • 如果当前版本为4.4,我们首先设置状态栏和导航栏透明,5.0不用
 //判断手机的版本,如果是4.4的版本,则设置状态栏和导航栏透明,5.0以上不用设置,已经实现
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
                Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }

在布局里加入这里写图片描述
* 判断版本,4.4以下可以忽略,4.4使用反射机制动态设置Toolbar的高度,再设置其颜色,同样使用反射设置导航栏的高度,再设置其颜色,5.0以上直接使用官方提供的API设置其颜色,高度使用默认的。

    /**
     * 设置顶部及底部的沉浸式,这个方法需要子类来调,必须在setContentView()之后调用
     */
    public void setTranslucentBar(final Toolbar toolbar, final View navigationView, int barColor) {
        //当手机的版本在4.4的时候,设置透明之后,再设置高度,然后再设置显示的颜色
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
                Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            if (toolbar != null) {
                toolbar.post(new Runnable() {
                    @Override
                    public void run() {
                        ViewGroup.LayoutParams layoutParams = toolbar.getLayoutParams();
                        layoutParams.height += getBarHeight("status_bar_height");
                        toolbar.setLayoutParams(layoutParams);
                    }
                });

                toolbar.setBackgroundColor(barColor);
            }
            if (navigationView != null) {
                //这时还要判断当前手机有没有底部虚拟导航栏,如果没有的话,我们不做处理
                if (hasNavigationView(getWindowManager())) {
                    navigationView.post(new Runnable() {
                        @Override
                        public void run() {
                            ViewGroup.LayoutParams layoutParams = navigationView.getLayoutParams();
                            layoutParams.height += getBarHeight("navigation_bar_height");
                            navigationView.setLayoutParams(layoutParams);
                        }
                    });
                    navigationView.setBackgroundColor(barColor);
                }
            }
            //5.0及以上
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setStatusBarColor(barColor);
            getWindow().setNavigationBarColor(barColor);
            toolbar.setBackgroundColor(barColor);
        } else {
            //4.4以下,没有沉浸式这一说,我们不做任何处理
        }
    }

最终我的基类的代码如下:

/**
 * 实现顶部及底部沉浸式导航栏的基类
 */
public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //判断手机的版本,如果是4.4的版本,则设置状态栏和导航栏透明,5.0以上不用设置,已经实现
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
                Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }

    /**
     * 设置顶部及底部的沉浸式,这个方法需要子类来调,必须在setContentView()之后调用
     */
    public void setTranslucentBar(final Toolbar toolbar, final View navigationView, int barColor) {
        //当手机的版本在4.4的时候,设置透明之后,再设置高度,然后再设置显示的颜色
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
                Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            if (toolbar != null) {
                toolbar.post(new Runnable() {
                    @Override
                    public void run() {
                        ViewGroup.LayoutParams layoutParams = toolbar.getLayoutParams();
                        layoutParams.height += getBarHeight("status_bar_height");
                        toolbar.setLayoutParams(layoutParams);
                    }
                });

                toolbar.setBackgroundColor(barColor);
            }
            if (navigationView != null) {
                //这时还要判断当前手机有没有底部虚拟导航栏,如果没有的话,我们不做处理
                if (hasNavigationView(getWindowManager())) {
                    navigationView.post(new Runnable() {
                        @Override
                        public void run() {
                            ViewGroup.LayoutParams layoutParams = navigationView.getLayoutParams();
                            layoutParams.height += getBarHeight("navigation_bar_height");
                            navigationView.setLayoutParams(layoutParams);
                        }
                    });
                    navigationView.setBackgroundColor(barColor);
                }
            }
            //5.0及以上
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setStatusBarColor(barColor);
            getWindow().setNavigationBarColor(barColor);
            toolbar.setBackgroundColor(barColor);
        } else {
            //4.4以下,没有沉浸式这一说,我们不做任何处理
        }
    }

    /**
     * 判断当前手机是否含有底部导航栏,如果没有的话返回false,有的话返回true
     *
     * @return
     */
    private boolean hasNavigationView(WindowManager wm) {
        Display display = wm.getDefaultDisplay();
        DisplayMetrics outMetrics = new DisplayMetrics();
        display.getRealMetrics(outMetrics);
        //获取屏幕实际的高度,实际的高度包括内容的高度和底部导航的高度
        int realHeight = outMetrics.heightPixels;

        outMetrics = new DisplayMetrics();
        display.getMetrics(outMetrics);
        //屏幕中内容的高度
        int heightPixels = outMetrics.heightPixels;
        //如果实际的高度和大于内容的高度说明该手机含有底部导航,否则没有
        return realHeight - heightPixels > 0;
    }

    /**
     * 获取状态栏或是底部导航栏的高度
     *
     * @return
     */
    public int getBarHeight(String dimenName) {
        int height = 0;
        try {
            Class clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            String s = clazz.getField(dimenName).get(object).toString();
            int heightId = Integer.parseInt(s);
            //dp 2 px
            height = getResources().getDimensionPixelSize(heightId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return height;
    }
}

它的子类的代码如下:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        navigationView = findViewById(R.id.navi);
        setTranslucentBar(toolbar, navigationView, getResources().getColor(R.color.barcolor));
    }

最终效果如下:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值