zoukankan      html  css  js  c++  java
  • 为应用加上Android4.4新特性的全屏模式沉浸模式(Fullscreen Immersive Mode)。

    Android4.4的发布带来了新的特性-沉浸模式(Full-screen Immersive Mode),开启后应用占据全屏,虚拟按钮和系统栏隐藏,提高屏幕的利用率和冲击力。

    那么怎样为我们的应用加入这个模式呢?先查看下Google的官方文档,里面有完整的示例代码。

     1 // This snippet hides the system bars.
     2 private void hideSystemUI() {
     3     // Set the IMMERSIVE flag.
     4     // Set the content to appear under the system bars so that the content
     5     // doesn't resize when the system bars hide and show.
     6     //开启全屏模式
     7     mDecorView.setSystemUiVisibility(
     8             View.SYSTEM_UI_FLAG_LAYOUT_STABLE
     9             | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    10             | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    11             | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
    12             | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
    13             | View.SYSTEM_UI_FLAG_IMMERSIVE);
    14 }
    15 
    16 // This snippet shows the system bars. It does this by removing all the flags
    17 // except for the ones that make the content appear under the system bars.
    18 //取消全屏模式
    19 private void showSystemUI() {
    20     mDecorView.setSystemUiVisibility(
    21             View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    22             | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    23             | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    24 }

    进入全屏后从屏幕上下放往里滑可重新唤出系统栏和虚拟按钮,但是唤出后系统栏会盖住一小部分内容,这个时候要给根layout设置一个高度为系统栏高度的Padding才能解决,后面会讲到。

    而且要再进入全屏模式还要再点击一次按钮。所以我比较推荐下面的模式,唤出的是透明的系统栏和虚拟按钮,短暂的时间后系统栏和虚拟按钮会自动隐藏。

    只需要把View.SYSTEM_UI_FLAG_IMMERSIVE改为View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY。

     1 @Override
     2 public void onWindowFocusChanged(boolean hasFocus) {
     3         super.onWindowFocusChanged(hasFocus);
     4     if (hasFocus) {
     5         decorView.setSystemUiVisibility(
     6                 View.SYSTEM_UI_FLAG_LAYOUT_STABLE
     7                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
     8                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
     9                 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    10                 | View.SYSTEM_UI_FLAG_FULLSCREEN
    11                 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
    12 }

    如果你的应用有ActionBar的话也会被隐藏掉,退出全屏模式后ActionBar会重新出现,但是和系统栏一样会覆盖在你的布局上。

    这是开启前:                                  这是开启后:                                   关闭全屏后按钮被标题栏覆盖掉了

                      

    这时候就需要用到ActionBar的覆盖模式了(Overlaying the Action Bar),具体设置请看Google的文档

    如果你用的是support v7兼容包的ActionBar可能会设置不了样式,请看我之前的一篇随笔来解决这个问题。

    要解决被覆盖的问题需要动态设置根布局的内边距,请看下面的设置:

     1 public class MainActivity extends Activity implements OnClickListener {
     2     private RelativeLayout rlLayout;
     3 
     4     @Override
     5     protected void onCreate(Bundle savedInstanceState) {
     6         super.onCreate(savedInstanceState);
     7         setContentView(R.layout.activity_main);
     8         //设置ACtionBar
     9         ActionBar actionBar = getActionBar();
    10         actionBar.setDisplayHomeAsUpEnabled(true);
    11         actionBar.setHomeButtonEnabled(true);
    12 
    13         rlLayout = (RelativeLayout) findViewById(R.id.rlayout);
    14         Button mButtonOn = (Button) findViewById(R.id.button_on);
    15         Button mButtonOff = (Button) findViewById(R.id.button_off);
    16         mButtonOn.setOnClickListener(this);
    17         mButtonOff.setOnClickListener(this);
    18     }
    19 
    20     public void onClick(View v) {
    21         //获得根视图
    22         View view = getWindow().getDecorView();
    23         switch (v.getId()) {
    24         case R.id.button_on:
    25             //进入沉浸模式
    26             hideSystemUI(view);
    27             //把内边距设为0
    28             rlLayout.setPadding(0, 0, 0, 0);
    29             break;
    30         case R.id.button_off:
    31             //退出沉浸模式
    32             showSystemUI(view);
    33             //获得系统栏高度
    34             Rect frame = new Rect();
    35             view.getWindowVisibleDisplayFrame(frame);
    36             //需要设置的内边距为ActionBar高度和系统栏高度相加
    37             int paddingTop = getActionBar().getHeight() + frame.top;
    38             rlLayout.setPadding(0, paddingTop, 0, 0);
    39             break;
    40         }
    41 
    42     }
    43 
    44     @Override
    45     public boolean onCreateOptionsMenu(Menu menu) {
    46         getMenuInflater().inflate(R.menu.main, menu);
    47         return true;
    48     }
    49 
    50     @SuppressLint("NewApi")
    51     public static void hideSystemUI(View view) {
    52         view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    53                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    54                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    55                 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    56                 | View.SYSTEM_UI_FLAG_FULLSCREEN
    57                 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    58     }
    59 
    60     @SuppressLint("NewApi")
    61     public static void showSystemUI(View view) {
    62         view.setSystemUiVisibility(
    63                 View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    64                 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    65                 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    66     }
    67 }
    1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2     xmlns:tools="http://schemas.android.com/tools"
    3     android:id="@+id/rlayout"
    4     android:layout_width="match_parent"
    5     android:layout_height="match_parent"
    6     android:paddingTop="?android:attr/actionBarSize"
    7     tools:context=".MainActivity" >

    如果我需要把一个应用里的所有activity都设为沉浸模式呢?只需要重写activity的onResume()方法,然后把这个activity设为父类,让所有的activity继承它就可以了。

    因为每创建一个新的activity都要检测是否开启全屏模式,而如果在后一个activity里设为全屏后返回上一个activity时也要检测是否变成全屏模式。

    下面是我的应用里onResume()的设置,因为我的应用要兼容android2.1所以Actionbar用的是support v7包,获取Actionbar是用getSupportActionBar();

    如果你的应用需要在进入沉浸模式后通知其他UI改变的话可以加入一个监听器View.OnSystemUiVisibilityChangeListener()。

    检测当前activity是否为沉浸模式的方法是

    1 int status = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    2       | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    3       | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    4       | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    5       | View.SYSTEM_UI_FLAG_FULLSCREEN
    6       | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    7 view.getSystemUiVisibility() == status;

    如果在后面的activity里退出了沉浸模式。那么返回前一个activity的时候,前一个activity要检查下是否要退出沉浸模式。在onResume()里面检查就可以。

     1 protected void onResume() {
     2          // 判断是否是android4.4
     3          if (SystemInfo.getSystemVersion() > 18) {
     4              SharedPreferences sPreferences = getSharedPreferences("AppBrightness", 0);
     5              // 读取存在SharedPreferences里的设置
     6              boolean Fullscreen = sPreferences.getBoolean("Fullscreen", false);
     7              ActionBar actionBar = getSupportActionBar();
     8              // 获得根视图
     9              View view = getWindow().getDecorView();
    10              // 获得根布局
    11              ViewGroup vGroup = (ViewGroup) (view.findViewById(android.R.id.content));
    12              // 用于判断应用是否已经退出沉浸模式了。
    13              int status = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    14                         | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    15                         | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    16                         | View.SYSTEM_UI_FLAG_VISIBLE
    17                         | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    18              // 判断是否要开启沉浸模式
    19              if (Fullscreen) {
    20                  // 需要开启沉浸模式则把actionbar先隐藏掉,不然在Activity跳转时会闪出来。
    21                  actionBar.hide();
    22                  // 进入沉浸模式
    23                  SystemUI.hideSystemUI(view);
    24                  // 在根布局获得第一个控件,也就是最上层的layout。把内边距设为0
    25                  vGroup.getChildAt(0).setPadding(0, 0, 0, 0);
    26              } else if (view.getSystemUiVisibility() == status){          
    27                  // 如果应用已经退出沉浸模式,但是这个activity还是在沉浸模式内,则退出沉浸模式。
    28                  actionBar.show();
    29                  SystemUI.showSystemUI(view);
    30                  // 获得系统栏高度和actionbar高度,设置内边距。
    31                  Rect frame = new Rect();
    32                  view.getWindowVisibleDisplayFrame(frame);
    33                  vGroup.getChildAt(0).setPadding(0, actionBar.getHeight() + frame.top, 0, 0);
    34              }
    35          }
    36          super.onResume();
    37      }
    1 public static int getSystemVersion() { //这是获取系统版本的方法
    2         int ver = android.os.Build.VERSION.SDK_INT;
    3         return ver;
    4     }
  • 相关阅读:
    关于SubSonic3.0查询或更新时出现System.NullReferenceException异常的处理
    SubSonic3.0使用例子
    Hive:ORC File Format存储格式详解
    HiveQL之Sort by、Distribute by、Cluster by、Order By详解
    Hive之import和export使用详解
    手动安装cloudera manager 5.x(tar包方式)详解
    初次安装hive-2.1.0启动报错问题解决方法
    LAMP下安装zabbix流水
    ESXI虚拟机磁盘管理(精简-厚置-精简)
    VMware esxi 5.5装机方案
  • 原文地址:https://www.cnblogs.com/zhengxt/p/3508485.html
Copyright © 2011-2022 走看看