Android 沉浸式状态栏实现, 在Activity和Fragment中

先上代码和效果图

一、 在Activity中

1、activity_immerse.xml 布局中的代码:

    *  隐藏系统自带的标题栏, 在需要实现沉浸式的布局中加入 android:fitsSystemWindows="true", 且该布局在页面需要在顶部显示




    
    
        
        
        
        

    

    

2、ImmerseActivity 中的代码

    *  设置布局后, 添加沉浸式属性

/**
 * 沉浸式状态栏
 */

public class ImmerseActivity extends BaseActivity {
    @Override
    public void setupViewLayout() {
        setContentView(R.layout.activity_immerse);
        //要实现沉浸式的布局, 一般是自定义的标题栏
        LinearLayout ll_immerse_title = getViewNoClickable(R.id.ll_immerse_title);
        //设置沉浸式状态栏效果
        BasisImmerseUtils.setImmerseLayout(mActivity, ll_immerse_title);
    }
}

3、BasisImmerUtils 工具类中 setImmerseLayout 方法

    *  设置沉浸式属性方法

/**
     * 设置沉浸式属性
     *
     * @param view 为实现沉浸式的布局, 需添加属性: android:fitsSystemWindows="true"
     */
    public static void setImmerseLayout(Activity activity, View view) {
        //沉浸式状态栏为Android4.4后特性
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//设置透明状态栏属性
            setPaddingTop(activity, view);
        }
    }

    /**
     * 将布局的PaddingTop增加系统栏的高度
     */
    public static void setPaddingTop(Activity activity, View view) {
        int statusBarHeight = getStatusBarHeight(activity);//获取系统状态栏高度
        view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());//设置view的paddingTop高度, 防止显示错乱
    }

/**
     * 获取系统状态栏高度
     *
     * @return pixel
     */
    public static int getStatusBarHeight(Context context) {
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return context.getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }

4、效果图

    *  状态栏显示的就是我们设置的标题颜色, 其它是自定义标题栏测试

Android 沉浸式状态栏实现, 在Activity和Fragment中_第1张图片

二、Activity 中 ViewPager + Fragment, Fragment布局实现沉浸式

1、activity_immersefragment.xml 布局中的代码

    *  viewpager需要是activity的第一个布局, 且需要设置activity的主题(theme)隐藏标题栏




    
    

    

2、ImmerseFragmentActivity 中代码

    *  设置布局后, 添加沉浸式属性

/**
 * 实现沉浸式状态栏Fragment
 */

public class ImmerseFragmentActivity extends BaseActivity {
    private ViewPager vp_immersefragment;
    private FragmentManager mFragmentManager = getSupportFragmentManager();
    private ArrayList mFragments = new ArrayList<>();
    public FragmentPagerAdapter mFragmentPagerAdapter;
    public FragmentStatePagerAdapter mFragmentStatePagerAdapter;

    @Override
    public void setupViewLayout() {
        setContentView(R.layout.activity_immersefragment);
        BasisImmerseUtils.setImmerseLayout(mActivity);//设置沉浸式状态

//        BasisImmerseUtils.hideStatusBar(mActivity);//隐藏顶部状态栏
//        BasisImmerseUtils.hideNavigationBar(mActivity);//隐藏底部导航栏
//        BasisImmerseUtils.setTransparentWindowBar(mActivity);//设置顶部状态栏和底部导航栏透明, 并使主题布局占据顶部和底部位置
    }

    @Override
    public void initView() {
        vp_immersefragment = getViewNoClickable(R.id.vp_immersefragment);
    }

    @Override
    public void listener() {
    }

    @Override
    public void logicDispose() {
        initFragmentData();
        setVPAdapter();
    }

    /**
     * 初始化Fragment
     */
    private void initFragmentData() {
        mFragments.add(new Test1Fragment());
        mFragments.add(new Test2Fragment());
        mFragments.add(new Test3Fragment());
        mFragments.add(new Test4Fragment());
        mFragments.add(new Test5Fragment());
    }

    /**
     * 设置适配器
     */
    private void setVPAdapter() {
        mFragmentPagerAdapter = new FragmentPagerAdapter(mFragmentManager) {
            @Override
            public Fragment getItem(int position) {
                return mFragments.get(position);
            }

            @Override
            public int getCount() {
                return mFragments == null ? 0 : mFragments.size();
            }
        };

        /**
         * 创建生命周期: onattach  oncreate  oncreateview  onactivitycreated  onstart  onresume
         * 销毁生命周期: onpause  onstop  ondestoryview  ondestory  ondetach
         * 创建时会多执行 onattach oncreate
         * 销毁时会多执行 ondestory ondetach
         */
        mFragmentStatePagerAdapter = new FragmentStatePagerAdapter(mFragmentManager) {
            @Override
            public Fragment getItem(int position) {
                return mFragments.get(position);
            }

            @Override
            public int getCount() {
                return mFragments == null ? 0 : mFragments.size();
            }
        };

        vp_immersefragment.setAdapter(mFragmentStatePagerAdapter);
    }

    @Override
    public void onClick(View v) {

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
//        BasisImmerseUtils.setOnWindowFocusChanged(mActivity, hasFocus);
    }


}

3、Fragment 的布局 fragment_test1.xml 的代码

    *  在需要实现沉浸式的布局中加入 android:fitsSystemWindows="true"




    
    

        
    


4、Fragment 中需添加下面的方法

    *  设置沉浸式布局ll_fragment_test1的paddingtop, 防止显示异常

//设置沉浸式布局ll_fragment_test1的paddingtop, 防止显示异常
        BasisImmerseUtils.setPaddingTop(mActivity, ll_fragment_test1);

5、BasisImmerUtils 工具类中 setPaddingTop 方法

/**
     * 将布局的PaddingTop增加系统栏的高度
     */
    public static void setPaddingTop(Activity activity, View view) {
        int statusBarHeight = getStatusBarHeight(activity);//获取系统状态栏高度
        view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());//设置view的paddingTop高度, 防止显示错乱
    }

/**
     * 获取系统状态栏高度
     *
     * @return pixel
     */
    public static int getStatusBarHeight(Context context) {
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return context.getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }

6、效果图

    *  其它Fragment类似, 在需要实现沉浸式的布局中加入 android:fitsSystemWindows="true"

Android 沉浸式状态栏实现, 在Activity和Fragment中_第2张图片

三、说明

1、沉浸式原理,说明, 解说等已经有好多人进行了说明, 这里不再详细解说,只是简单给出实现沉浸式代码,在关联文章中也给出了两篇, 有兴趣可以看看

2、全屏大图的沉浸式类似,大家可自行尝试

3、Fragment 的沉浸式是为了不同 Fragment 需要不同自定义标题准备的, 若共用一个自定义标题, 使用Activity实现沉浸式更为简单

4、工具类 BasisImmerseUtils 中还包含一些隐藏导航栏, 全屏等方法,完整代码如下

package com.gingold.basislibrary.utils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

/**
 * 沉浸式状态栏工具类
 *
 * @note viewPager中的Fragment自己使用沉浸式效果时, 占据状态栏的布局和标题布局需分开, 否则会引起标题显示错乱
 */

public class BasisImmerseUtils {

    /**
     * 设置沉浸式属性
     *
     * @param view 为实现沉浸式的布局, 需添加属性: android:fitsSystemWindows="true"
     */
    public static void setImmerseLayout(Activity activity, View view) {
        //沉浸式状态栏为Android4.4后特性
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//设置透明状态栏属性
            setPaddingTop(activity, view);
        }
    }

    /**
     * 将布局的PaddingTop增加系统栏的高度
     */
    public static void setPaddingTop(Activity activity, View view) {
        int statusBarHeight = getStatusBarHeight(activity);//获取系统状态栏高度
        view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());//设置view的paddingTop高度, 防止显示错乱
    }

    /**
     * 设置沉浸式属性
     */
    public static void setImmerseLayout(Activity activity) {
        //沉浸式状态栏为Android4.4后特性
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//设置透明状态栏属性
        }
    }

    /**
     * 取消沉浸式属性
     *
     * @param view 为实现沉浸式的布局, 需添加属性: android:fitsSystemWindows="true"
     */
    public static void clearImmerseLayout(Activity activity, View view) {
        //沉浸式状态栏为Android4.4后特性
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            int statusBarHeight = getStatusBarHeight(activity);//获取系统状态栏高度
            view.setPadding(view.getPaddingLeft(), view.getPaddingTop() - statusBarHeight, view.getPaddingRight(), view.getPaddingBottom());//设置view的paddingTop高度, 防止显示错乱
        }
    }

    /**
     * 取消沉浸式属性
     */
    public static void clearImmerseLayout(Activity activity) {
        //沉浸式状态栏为Android4.4后特性
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    /**
     * 获取系统状态栏高度
     *
     * @return pixel
     */
    public static int getStatusBarHeight(Context context) {
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return context.getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }

    /**
     * 设置顶部状态栏和底部导航栏透明, 并使主题布局占据顶部和底部位置
     * 

* 效果: 顶部状态栏和底部导航栏悬空在界面上 */ public static void setTransparentWindowBar(Activity activity) { //支持Android5.0以上版本 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { View decorView = activity.getWindow().getDecorView(); int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; decorView.setSystemUiVisibility(option); activity.getWindow().setNavigationBarColor(Color.TRANSPARENT); activity.getWindow().setStatusBarColor(Color.TRANSPARENT); } } /** * 隐藏顶部状态栏 */ public static void hideStatusBar(Activity activity) { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN); } /** * 隐藏底部导航栏 */ public static void hideNavigationBar(Activity activity) { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); } /** * 隐藏底部导航栏和顶部状态栏(点击任意位置效果消失) */ public static void hideStatusBarAndNavigationBar(Activity activity) { activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); } /** * 设置完全沉浸式效果(游戏和视频播放需求) *

* 需要在onWindowFocusChanged方法中调用 */ public static void setOnWindowFocusChanged(Activity activity, boolean hasFocus) { if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } } }

四、相关文章

1、Android状态栏微技巧,带你真正理解沉浸式模式

2、Android沉浸式状态栏(透明状态栏)最佳实现

五、GitHup项目地址

https://github.com/GinGod/BasisDependency

你可能感兴趣的:(Java/Android)