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的内容延伸到状态栏/导航栏的主要内容,如果未能解决你的问题,请参考以下文章