android 沉浸式状态栏(2)

上篇介绍api21以上的沉浸式状态栏,这篇介绍状态栏以及导航栏


使用DecorView的setSystemUiVisibility方法

package com.whuthm.immersive;

import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by DELL on 2015/7/20.
 */
public class FullScreenActivity extends BaseActivity implements View.OnClickListener {

    private static final String TAG = "FullScreenActivity";

    private TextView mShowTips;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_fullscreen);
        initToolbar();

        mShowTips = (TextView) findViewById(R.id.tv_show_tips);

        findViewById(R.id.btn_clear).setOnClickListener(this);
        findViewById(R.id.btn_show_status_bar).setOnClickListener(this);
        findViewById(R.id.btn_hide_status_bar).setOnClickListener(this);
        findViewById(R.id.btn_show_nav_bar).setOnClickListener(this);
        findViewById(R.id.btn_hide_nav_bar).setOnClickListener(this);
        findViewById(R.id.btn_full_screen).setOnClickListener(this);
        findViewById(R.id.btn_full_screen_imm).setOnClickListener(this);
        findViewById(R.id.btn_full_screen_imm_sticky).setOnClickListener(this);
        findViewById(R.id.btn_layout_stable).setOnClickListener(this);

        setOnSystemUiVisibilityChangeListener();
    }

    public void setOnSystemUiVisibilityChangeListener() {
        if (Build.VERSION.SDK_INT >= 14) {
            final View decorView = getDecorView();
            decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
                @Override
                public void onSystemUiVisibilityChange(int visibility) {
                    FullScreenActivity.this.onSystemUiVisibilityChange(visibility);
                }
            });
        }
    }

    private void clear() {
        final View decorView = getDecorView();
        if (decorView != null) {
            if (Build.VERSION.SDK_INT >= 14) {
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
            }
        } else {
            Toast.makeText(this, "Need API 14 at least", Toast.LENGTH_SHORT).show();
        }
    }

    private void showStatusBar() {
        final View decorView = getDecorView();

        if (decorView != null) {
            if (Build.VERSION.SDK_INT >= 14) {
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
            }
        } else {
            Toast.makeText(this, "Need API 14 at least", Toast.LENGTH_SHORT).show();
        }
    }

    private void hideStatusBar() {

    }

    private void showNavigationBar() {

    }

    /**
     * Api 14 及以上才有用
     * SYSTEM_UI_FLAG_HIDE_NAVIGATION使用此Flag后,导航栏隐藏,点击屏幕的任何区域,取消导航栏的隐藏
     * 在全屏后不能有任何操作(4.4之前)
     */
    private void hideNavigationBar() {
        final View decorView = getDecorView();

        if (decorView != null) {
            if (Build.VERSION.SDK_INT >= 14) {
                int flag = decorView.getSystemUiVisibility();
                Log.i(TAG, "hideStatusBar flag = " + flag);
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
                Log.i(TAG, "hideStatusBar flag = " + decorView.getSystemUiVisibility());
            } else {
                Toast.makeText(this, "Need API 14 at least", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : 让view显示在状态栏之下 API16
     * SYSTEM_UI_FLAG_FULLSCREEN:隐藏状态栏 API 16
     * SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏导航栏 API 14
     * SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:让view显示在导航栏之下
     * 当在根布局使用属性android:fitsSystemWindows="true"时,在5.0之前,布局始终跟着状态栏或者导航栏(隐藏或者显示),但是5.0中contentView没有在状态栏处全屏显示
     * 打出的log显示当系统UI变化(onSystemUiVisibilityChange)时,根布局的paddingTop有变化,状态栏的高度,但是5.0中没有变化
     * 在api16 之前android:fitsSystemWindows属性不要和SYSTEM_UI_FLAG_HIDE_NAVIGATION状态栏一起显示
     */
    private void fullScreen() {
        final View decorView = getDecorView();

        if (decorView != null) {
            if (Build.VERSION.SDK_INT >= 16) {
                int flag = decorView.getSystemUiVisibility();
                Log.i(TAG, "hideStatusBar flag = " + flag);
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
                Log.i(TAG, "hideStatusBar flag = " + decorView.getSystemUiVisibility());
            } else {
                Toast.makeText(this, "Need API 16 at least", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * 沉浸模式android 4.4(API 19)及以上
     * SYSTEM_UI_FLAG_IMMERSIVE和SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_FULLSCREEN一起使用,用户可以全屏状态下拦截所有的触摸时间
     * 注意,immersive类的标签只有在与SYSTEM_UI_FLAG_HIDE_NAVIGATION,SYSTEM_UI_FLAG_FULLSCREEN中一个或两个一起使用的时候才会生效。你可以只使用其中的一个,但是一般情况下你需要同时隐藏状态栏和导航栏以达到沉浸的效果。
     */
    private void fullScreenImmersive() {
        final View decorView = getDecorView();

        if (decorView != null) {
            if (Build.VERSION.SDK_INT >= 19) {
                int flag = decorView.getSystemUiVisibility();
                Log.i(TAG, "hideStatusBar flag = " + flag);
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_IMMERSIVE);
                Log.i(TAG, "hideStatusBar flag = " + decorView.getSystemUiVisibility());
            } else {
                Toast.makeText(this, "Need API 14 at least", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * 使用粘性的沉浸模式
     * SYSTEM_UI_FLAG_IMMERSIVE_STICKY:使用后,向下滑动显示状态栏和导航栏,五秒后隐藏,但是锁屏后在解锁,不会消失
     * 和theme android:windowFullscreen 使用时,不管是否使用粘性的模式,状态栏都会自动消失,导航栏不会,导航栏只在粘性模式下自动消失
     */
    private void fullScreenImmersiveSticky() {
        final View decorView = getDecorView();

        if (decorView != null) {
            if (Build.VERSION.SDK_INT >= 19) {
                int flag = decorView.getSystemUiVisibility();
                Log.i(TAG, "hideStatusBar flag = " + flag);
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
                Log.i(TAG, "hideStatusBar flag = " + decorView.getSystemUiVisibility());
            } else {
                Toast.makeText(this, "Need API 14 at least", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void layoutStable() {
        final View decorView = getDecorView();

        if (decorView != null) {
            if (Build.VERSION.SDK_INT >= 16) {
                int flag = decorView.getSystemUiVisibility();
                Log.i(TAG, "hideStatusBar flag = " + flag);
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                Log.i(TAG, "hideStatusBar flag = " + decorView.getSystemUiVisibility());
            } else {
                Toast.makeText(this, "Need API 16 at least", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private View getDecorView() {
        final Window window = getWindow();
        View decorView = window != null ? window.getDecorView() : null;
        return decorView;
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.btn_clear:
                clear();
                break;
            case R.id.btn_show_status_bar:
                showStatusBar();
                break;
            case R.id.btn_hide_status_bar:
                hideStatusBar();
                break;
            case R.id.btn_show_nav_bar:
                showNavigationBar();
                break;
            case R.id.btn_hide_nav_bar:
                hideNavigationBar();
                break;
            case R.id.btn_full_screen:
                fullScreen();
                break;
            case R.id.btn_full_screen_imm:
                fullScreenImmersive();
                break;
            case R.id.btn_full_screen_imm_sticky:
                fullScreenImmersiveSticky();
                break;
            case R.id.btn_layout_stable:
                layoutStable();
                break;
            default:
                break;
        }

        if (v instanceof Button) {
            mShowTips.setText(((Button) v).getText());
        }

    }


    public void onSystemUiVisibilityChange(int visibility) {
        Log.e(TAG, "onSystemUiVisibilityChange visibility = " + visibility);
        View rootView = findViewById(R.id.fullscreen_layout);
        Log.e(TAG, rootView.getPaddingTop() + "  " + rootView.getPaddingBottom());
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        Log.e(TAG, "onWindowFocusChanged hasFocus = " + hasFocus);
    }
}



透明状态栏和导航栏

package com.whuthm.immersive;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ListView;
import android.widget.TextView;

import com.whuthm.base.view.BaseAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by DELL on 2015/7/22.
 */
public class TranslucentSystemUIActivity extends BaseActivity {

    private static final String TAG = "TranslucentSystemUI";

    private ListView mListView;
    private List<Integer> mDatas;
    private MyAdapter mAdapter;

    /**
     * 透明状态下是真正的全屏显示,除非在根布局下使用android:fitsSystemWindows="true",则布局现在状态栏和导航栏中间
     */

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //translucentSystemUI();

        //colorSystemUI();

        setContentView(R.layout.activity_translucent_system_ui);
        initToolbar();

        mListView = (ListView) findViewById(R.id.list_view);

        mDatas = new ArrayList<Integer>();
        for (int i = 0; i < 80; i++) {
            mDatas.add(i);
        }

        mAdapter = new MyAdapter(this, mDatas);
        mListView.setAdapter(mAdapter);

        Log.e(TAG, getNavigationBarHeight(this) + "  " + checkDeviceHasNavigationBar(this));
    }

    /**
     * 使用style来控制
     * <item name="android:windowTranslucentStatus">true</item>
     * <item name="android:windowTranslucentNavigation">true</item>
     * 使用代码来控制状态栏和导航栏的透明
     * API 19
     */
    private void translucentSystemUI() {
        if (Build.VERSION.SDK_INT >= 19) {
            Window window = getWindow();
            window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }

    private void colorSystemUI() {
        if (Build.VERSION.SDK_INT >= 21) {
            Window window = getWindow();
            //window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            //window.setFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.BLUE);
            window.setNavigationBarColor(Color.BLUE);
        }
    }

    public static int getNavigationBarHeight(Context context) {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height",
                "dimen", "android");
        //获取NavigationBar的高度
        int height = resources.getDimensionPixelSize(resourceId);
        return height;
    }

    public static boolean checkDeviceHasNavigationBar(Context context) {

        if (Build.VERSION.SDK_INT >= 14) {
            //通过判断设备是否有返回键、菜单键(不是虚拟键,是手机屏幕外的按键)来确定是否有navigation bar
            boolean hasMenuKey = ViewConfiguration.get(context)
                    .hasPermanentMenuKey();
            boolean hasBackKey = KeyCharacterMap
                    .deviceHasKey(KeyEvent.KEYCODE_BACK);

            if (!hasMenuKey && !hasBackKey) {
                // 做任何你需要做的,这个设备有一个导航栏
                return true;
            }
        }

        return false;
    }

    class MyAdapter extends BaseAdapter<Integer> {

        public MyAdapter(Context context, List<Integer> list) {
            super(context, list);
        }

        public View createView(Context context, ViewGroup parent) {
            return new TextView(context);
        }

        public BaseAdapter.ViewHolder<Integer> createViewHolder() {
            return new MyHolder();
        }
    }

    class MyHolder extends BaseAdapter.ViewHolder<Integer> {

        TextView tv;

        @Override
        public void init(Context context, View convertView) {
            tv = (TextView) convertView;
        }

        @Override
        public void update(Context context, Integer data) {
            tv.setText("Item " + data);
        }
    }
}

使用主题实现 api19

<resources>

    <style name="TranslucentSystemUITheme" parent="AppBaseTheme">
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>
</resources>




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值