Android 将App的内容延伸到状态栏/导航栏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 将App的内容延伸到状态栏/导航栏相关的知识,希望对你有一定的参考价值。

参考技术A

来自我的CSDN博客: http://blog.csdn.net/dahaohan/article/details/52175190

看过Android的桌面应用都是介样的:

如何让自己的应用也达到这般效果呢?这里就介绍几种常用的方法以及它们之间的区别。

首先展示下此次demo的布局和初始状态:

初始效果图如下:

使用这个方式首先要理解几个概念,窗口层级以及窗口background/窗口透明:
Google在API-19 以及API-21新增对状态栏/导航栏窗口透明和颜色的控制:

对应的在主题内即可控制:

这里首先要明了这里状态栏和导航栏窗口是系统级窗口而Activity对应的时应用窗口,它们属于不同的窗口层级;
然后状态栏/导航栏系统级窗口是在App应用窗口之上,故而Activity应用窗口虽然有整个屏幕的大小,但是可显示内容的区域得除去其上叠加的不透明的窗口区域。详细的窗口计算绘制可参考大神老罗的博文:
android窗口管理服务WindowManagerService计算Activity窗口大小的过程分析

下面来使用主题控制导航栏/状态栏透明,同时看看上述两种设置透明的方式效果有何不同:

初始桌面和启动Activity效果图:

可以看到虽然导航栏/状态栏透明了,当时应用窗口显示的内容依然只是除去了两个系统窗口之外的区域,并没有衍生到导航栏/状态栏之下。

效果如下:

可以看到已经将应用的内容布局延伸到导航栏/状态栏下方了,来看看关于android:windowTranslucentStatus
android:windowTranslucentNavigation的官方说明看看来理解其与设置color transparent的区别:

根据FLAG的说明,可以看出设置该标志位等同于View申请设置:

PS:从效果图看,虽然布局延伸到状态栏导航栏区域,但是相应的内容“hello world”文字也被状态栏/导航栏遮住了。在布局根视图设置fitsSystemWindows为true可以使得,系统自动为视图添加一个状态栏/导航栏高度的padding:

效果如下:

查看SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 和 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN的说明,可以发现其实还有两个非常接近的FLAG:

根据官方的说明提示,SYSTEM_UI_FLAG_FULLSCREEN / SYSTEM_UI_FLAG_HIDE_NAVIGATION主要用于动态切换隐藏/显示系统导航栏/状态栏;例如书籍阅读应用/视频播放应用等。而像游戏类的全屏应用则推荐使用window flag。

上述的透明导航栏/状态栏等API基本是需要API-19或是API-21才能使用的,这里还有一种API-1的方案能够实现布局内容全屏:

实际上只需要设置FLAG_LAYOUT_NO_LIMITS就足够了;这FLAG是看Android原生的Launcher / Keyguard源码,看到有用到如此设置,其窗口设置具体原理我也没有弄清..... 有大神了解可以指点下。

PS:这个套路下,使用fitsSystemWindows="true"是无效的,智能自己控制号布局位置。

Android第十二讲笔记(视频,音频播放,开源控件)

1.播放音频

1.新建文件夹用来存放音频文件

在这里插入图片描述
在放入音频文件在文件夹之后

2.配置

主要步骤和解释在图中标出
在这里插入图片描述
MainActivity.java代码

package com.hnucm.android_05_28;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.view.View;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    MediaPlayer mediaPlayer= new MediaPlayer();
//    限制setDataSource只能在   Build.VERSION_CODE.N  api使用
    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
//            加载音乐资源
            mediaPlayer.setDataSource(getAssets().openFd("a1.mp3"));
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                播放音乐
                mediaPlayer.start();
            }
        });
        findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                暂停音乐
                mediaPlayer.pause();
            }
        });
    }
}

2.播放视频

在这里插入图片描述

新建的文件夹名字需要叫做raw
在这里插入图片描述
然后在该文件夹种放入视频资源

示例如下

在这里插入图片描述

package com.hnucm.android_05_28;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.MediaController;
import android.widget.VideoView;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    MediaPlayer mediaPlayer= new MediaPlayer();

    VideoView videoView;
//    限制setDataSource只能在   Build.VERSION_CODE.N  api使用
    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        videoView=findViewById(R.id.videoView);
        //            加载视频资源
        videoView.setVideoPath("android.resource://" + getPackageName() + "/" + R.raw.a2);
//        添加播放控制
        videoView.setMediaController(new MediaController(this));
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                播放音乐
//                mediaPlayer.start();
//                播放视频
                videoView.start();
            }
        });
        findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                暂停音乐
//                mediaPlayer.pause();
//                暂停视频
                videoView.pause();
            }
        });
    }
}

3.开源控件

1.drawerlayout实现抽屉效果

在这里插入图片描述

我们新建了一个MainActivity2进行演示

将布局先改为drawerlayout如果不改,则无法实现抽屉效果
在这里插入图片描述
在该布局中又放入了两个布局,作为初始界面和点出来的抽屉界面
在这里插入图片描述
在这里插入图片描述

activity2_main.xml代码如下

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity2">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="144dp"
            android:text="右边布局"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

        </Button>

    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_gravity="left"
        android:background="@color/purple_200"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/text3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:text="左边布局"
            android:layout_marginTop="344dp">

        </TextView>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.drawerlayout.widget.DrawerLayout>

在这里插入图片描述
MainActivity2.java

package com.hnucm.android_05_28;

import androidx.appcompat.app.AppCompatActivity;
import androidx.drawerlayout.widget.DrawerLayout;

import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;

public class MainActivity2 extends AppCompatActivity {

    DrawerLayout drawerLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        drawerLayout = findViewById(R.id.drawlayout);
        findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                弹出左边隐藏的区域
                drawerLayout.openDrawer(Gravity.LEFT);
            }
        });
    }
}

效果

在这里插入图片描述

2.沉浸式状态栏

开源代码官网

1.导入依赖

implementation 'com.jaeger.statusbarutil:library:1.5.1'

2.去掉标题栏

在这里插入图片描述

3.简单示例(将状态栏和顶层的颜色设置一致)

activity_main3.xml
在这里插入图片描述
核心代码
在这里插入图片描述

StatusBarUtil.setColor(this,getColor(R.color.purple_200));

MainActivity3.java

package com.hnucm.android_05_28;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Build;
import android.os.Bundle;

import com.jaeger.library.StatusBarUtil;

public class MainActivity3 extends AppCompatActivity {

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        StatusBarUtil.setColor(this,getColor(R.color.purple_200));
    }
}

4.将APP顶层的图片延伸到状态栏

activity_main3.xml

界面要展示的内容需要用一个布局包起来,这里使用的是约束布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity3">

<!--    background设置图片会让图片占满
src不会
scaleType="fitEnd/fitXY/fitStart"  居右,拉满,居左
-->
    <ImageView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@drawable/tri"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" >
        <Button
            android:id="@+id/button4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent">
        </Button>

        <Button
            android:id="@+id/button5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="@id/button4">
        </Button>
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

核心代码

StatusBarUtil.setTransparentForImageView(this,constraintLayout);

在这里插入图片描述

3.轮播图

开源代码官网

1.导入依赖

implementation 'com.youth.banner:banner:2.1.0'
implementation 'com.github.bumptech.glide:glide:4.12.0'

2.在布局文件中加入banner

在这里插入图片描述

3.我们要用到网络图片,所以我们要加入网络访问的权限

<uses-permission android:name="android.permission.INTERNET" />

4.MainActivity.java中设置轮播图的属性

更多属性的设置,可以取github官网查看相关信息。
在这里插入图片描述

最后就可以完成了!
开源框架在这里只介绍了部分,在后续的学习过程中会不断补充!

以上是关于Android 将App的内容延伸到状态栏/导航栏的主要内容,如果未能解决你的问题,请参考以下文章

Android:虚拟按键/导航键遮挡内容的解决方案

android中状态栏怎么布局

安卓 /android 手机 隐藏 状态栏 怎么操作啊

Android第十二讲笔记(视频,音频播放,开源控件)

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

android 透明状态栏是怎样实现的