262 lines
9.3 KiB
Plaintext
262 lines
9.3 KiB
Plaintext
|
|
# PengyouquanActivity 沉浸式状态栏修改文档
|
|||
|
|
|
|||
|
|
## 一、目标
|
|||
|
|
- 实现状态栏透明,让背景图延伸到状态栏区域,实现沉浸式效果
|
|||
|
|
- 在左上角添加返回按钮,点击后关闭页面
|
|||
|
|
- 确保返回按钮在状态栏下方可见,不被遮挡
|
|||
|
|
|
|||
|
|
## 二、修改文件清单
|
|||
|
|
|
|||
|
|
### 1. 布局文件
|
|||
|
|
**文件路径**: `uikit/src/main/res/layout/activity_pengyouquan.xml`
|
|||
|
|
|
|||
|
|
**修改内容**:
|
|||
|
|
- 在 `RelativeLayout` 中添加返回按钮 `ImageView`(`id="@+id/iv_back"`)
|
|||
|
|
- 返回按钮位置:左上角,使用 `layout_alignParentTop="true"` 和 `layout_alignParentLeft="true"`
|
|||
|
|
- 返回按钮样式:
|
|||
|
|
- 图标:`@mipmap/ic_back`
|
|||
|
|
- 内边距:`16dp`
|
|||
|
|
- 左边距:`8dp`
|
|||
|
|
- 可点击和可获取焦点
|
|||
|
|
- 使用 `selectableItemBackgroundBorderless` 背景,提供点击反馈
|
|||
|
|
|
|||
|
|
**关键代码**:
|
|||
|
|
```xml
|
|||
|
|
<!-- 返回按钮 -->
|
|||
|
|
<ImageView
|
|||
|
|
android:id="@+id/iv_back"
|
|||
|
|
android:layout_width="wrap_content"
|
|||
|
|
android:layout_height="wrap_content"
|
|||
|
|
android:layout_alignParentTop="true"
|
|||
|
|
android:layout_alignParentLeft="true"
|
|||
|
|
android:src="@mipmap/ic_back"
|
|||
|
|
android:padding="16dp"
|
|||
|
|
android:layout_marginLeft="8dp"
|
|||
|
|
android:background="?attr/selectableItemBackgroundBorderless"
|
|||
|
|
android:clickable="true"
|
|||
|
|
android:focusable="true"
|
|||
|
|
android:contentDescription="返回" />
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Java 代码文件
|
|||
|
|
**文件路径**: `uikit/src/main/java/cn/wildfire/chat/kit/user/PengyouquanActivity.java`
|
|||
|
|
|
|||
|
|
**修改内容**:
|
|||
|
|
|
|||
|
|
#### 2.1 添加必要的导入
|
|||
|
|
```java
|
|||
|
|
import android.os.Build;
|
|||
|
|
import android.view.Window;
|
|||
|
|
import android.view.WindowManager;
|
|||
|
|
import cn.wildfire.chat.kit.third.utils.UIUtils;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.2 添加成员变量
|
|||
|
|
```java
|
|||
|
|
private ImageView ivBack;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.3 添加 `beforeViews()` 方法
|
|||
|
|
在 `setContentView()` 之前设置状态栏透明:
|
|||
|
|
```java
|
|||
|
|
@Override
|
|||
|
|
protected void beforeViews() {
|
|||
|
|
super.beforeViews();
|
|||
|
|
// 设置状态栏透明,让背景图显示出来
|
|||
|
|
setTransparentStatusBar();
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.4 在 `bindViews()` 中绑定返回按钮
|
|||
|
|
```java
|
|||
|
|
ivBack = findViewById(R.id.iv_back);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.5 在 `afterViews()` 中设置返回按钮事件和位置
|
|||
|
|
```java
|
|||
|
|
@Override
|
|||
|
|
protected void afterViews() {
|
|||
|
|
super.afterViews();
|
|||
|
|
// 设置返回按钮点击事件
|
|||
|
|
if (ivBack != null) {
|
|||
|
|
ivBack.setOnClickListener(new View.OnClickListener() {
|
|||
|
|
@Override
|
|||
|
|
public void onClick(View v) {
|
|||
|
|
finish();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
// 调整返回按钮位置,考虑状态栏高度
|
|||
|
|
ivBack.post(new Runnable() {
|
|||
|
|
@Override
|
|||
|
|
public void run() {
|
|||
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|||
|
|
int statusBarHeight = getStatusBarHeight();
|
|||
|
|
android.view.ViewGroup.MarginLayoutParams params =
|
|||
|
|
(android.view.ViewGroup.MarginLayoutParams) ivBack.getLayoutParams();
|
|||
|
|
if (params != null) {
|
|||
|
|
params.topMargin = statusBarHeight + UIUtils.dip2Px(mContext, 8);
|
|||
|
|
ivBack.setLayoutParams(params);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
// ... 其他初始化代码
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.6 添加 `setTransparentStatusBar()` 方法
|
|||
|
|
**核心方法**,实现沉浸式状态栏:
|
|||
|
|
```java
|
|||
|
|
/**
|
|||
|
|
* 设置状态栏透明,让背景图显示出来
|
|||
|
|
*/
|
|||
|
|
private void setTransparentStatusBar() {
|
|||
|
|
Window window = getWindow();
|
|||
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|||
|
|
// 设置状态栏透明
|
|||
|
|
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
|||
|
|
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
|||
|
|
window.setStatusBarColor(android.graphics.Color.TRANSPARENT);
|
|||
|
|
|
|||
|
|
// 关键:让内容布局延伸到状态栏下方,实现沉浸式效果
|
|||
|
|
View decorView = window.getDecorView();
|
|||
|
|
int flags = decorView.getSystemUiVisibility();
|
|||
|
|
// 让内容延伸到状态栏区域
|
|||
|
|
flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
|||
|
|
flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
|||
|
|
|
|||
|
|
// 设置状态栏图标为深色(因为背景图较亮)
|
|||
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|||
|
|
flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
decorView.setSystemUiVisibility(flags);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**关键点说明**:
|
|||
|
|
- `FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS`: 允许绘制系统栏背景
|
|||
|
|
- `SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`: **核心标志**,让内容布局延伸到状态栏下方
|
|||
|
|
- `SYSTEM_UI_FLAG_LAYOUT_STABLE`: 保持布局稳定,避免内容跳动
|
|||
|
|
- `SYSTEM_UI_FLAG_LIGHT_STATUS_BAR`: 设置状态栏图标为深色(适合浅色背景)
|
|||
|
|
|
|||
|
|
#### 2.7 添加 `getStatusBarHeight()` 辅助方法
|
|||
|
|
```java
|
|||
|
|
/**
|
|||
|
|
* 获取状态栏高度
|
|||
|
|
*/
|
|||
|
|
private int getStatusBarHeight() {
|
|||
|
|
int result = 0;
|
|||
|
|
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
|||
|
|
if (resourceId > 0) {
|
|||
|
|
result = getResources().getDimensionPixelSize(resourceId);
|
|||
|
|
}
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 三、技术要点
|
|||
|
|
|
|||
|
|
### 1. 沉浸式状态栏实现原理
|
|||
|
|
- **Android 5.0+ (API 21+)**: 使用 `Window.setStatusBarColor()` 设置状态栏颜色
|
|||
|
|
- **关键标志**:
|
|||
|
|
- `SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`: 让内容延伸到状态栏下方(**最重要**)
|
|||
|
|
- `SYSTEM_UI_FLAG_LAYOUT_STABLE`: 保持布局稳定
|
|||
|
|
- **状态栏图标颜色**:
|
|||
|
|
- Android 6.0+ (API 23+): 使用 `SYSTEM_UI_FLAG_LIGHT_STATUS_BAR` 设置深色图标
|
|||
|
|
- Android 11+ (API 30+): 可使用 `WindowInsetsController`(本实现未使用,保持兼容性)
|
|||
|
|
|
|||
|
|
### 2. 返回按钮位置调整
|
|||
|
|
- 由于内容延伸到状态栏下方,返回按钮需要使用 `post()` 在布局完成后动态调整位置
|
|||
|
|
- 计算公式:`topMargin = statusBarHeight + 8dp`
|
|||
|
|
- 确保返回按钮在状态栏下方可见,不被遮挡
|
|||
|
|
|
|||
|
|
### 3. 生命周期时机
|
|||
|
|
- `beforeViews()`: 在 `setContentView()` 之前调用,设置 Window flags
|
|||
|
|
- `afterViews()`: 在布局完成后调用,设置返回按钮位置和事件
|
|||
|
|
|
|||
|
|
## 四、适配说明
|
|||
|
|
|
|||
|
|
### Android 版本适配
|
|||
|
|
- **Android 5.0+ (API 21+)**: 支持设置状态栏透明
|
|||
|
|
- **Android 6.0+ (API 23+)**: 支持设置状态栏图标颜色(深色/浅色)
|
|||
|
|
- **Android 11+ (API 30+)**: 可以使用 `WindowInsetsController`(本实现未使用,保持兼容性)
|
|||
|
|
|
|||
|
|
### 注意事项
|
|||
|
|
1. **必须在 `setContentView()` 之前设置 Window flags**,否则可能不生效
|
|||
|
|
2. **返回按钮位置调整需要在布局完成后**,使用 `post()` 或 `ViewTreeObserver`
|
|||
|
|
3. **不同 ROM 可能有差异**(MIUI、ColorOS 等),可能需要额外处理
|
|||
|
|
4. **状态栏图标颜色**需要根据背景图亮度调整,本实现设置为深色(适合浅色背景)
|
|||
|
|
|
|||
|
|
## 五、效果验证
|
|||
|
|
|
|||
|
|
### 预期效果
|
|||
|
|
1. ✅ 状态栏完全透明,可以看到背景图
|
|||
|
|
2. ✅ 背景图延伸到状态栏区域,实现沉浸式效果
|
|||
|
|
3. ✅ 返回按钮位于左上角,在状态栏下方可见
|
|||
|
|
4. ✅ 点击返回按钮可以正常关闭页面
|
|||
|
|
5. ✅ 状态栏图标为深色,在背景图上清晰可见
|
|||
|
|
|
|||
|
|
### 验证步骤
|
|||
|
|
1. 启动应用,进入 `PengyouquanActivity` 页面
|
|||
|
|
2. 检查状态栏是否透明,背景图是否延伸到状态栏区域
|
|||
|
|
3. 检查返回按钮是否在左上角可见,位置是否正确
|
|||
|
|
4. 点击返回按钮,确认可以正常关闭页面
|
|||
|
|
5. 检查状态栏图标是否为深色(适合浅色背景)
|
|||
|
|
|
|||
|
|
## 六、常见问题
|
|||
|
|
|
|||
|
|
### Q1: 状态栏仍然显示白条
|
|||
|
|
**原因**:
|
|||
|
|
- `SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN` 标志未设置或设置时机不对
|
|||
|
|
- Activity 主题可能覆盖了设置
|
|||
|
|
|
|||
|
|
**解决方案**:
|
|||
|
|
- 确保在 `beforeViews()` 中调用 `setTransparentStatusBar()`
|
|||
|
|
- 检查 Activity 主题是否设置了状态栏颜色
|
|||
|
|
- 确认 `FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS` 已设置
|
|||
|
|
|
|||
|
|
### Q2: 返回按钮被状态栏遮挡
|
|||
|
|
**原因**:
|
|||
|
|
- 返回按钮位置未考虑状态栏高度
|
|||
|
|
- 布局中的 `marginTop` 是固定值
|
|||
|
|
|
|||
|
|
**解决方案**:
|
|||
|
|
- 移除布局中的固定 `marginTop`
|
|||
|
|
- 在代码中动态设置 `topMargin = statusBarHeight + 8dp`
|
|||
|
|
- 使用 `post()` 确保在布局完成后调整
|
|||
|
|
|
|||
|
|
### Q3: 状态栏图标颜色不正确
|
|||
|
|
**原因**:
|
|||
|
|
- Android 版本低于 6.0,不支持设置图标颜色
|
|||
|
|
- `SYSTEM_UI_FLAG_LIGHT_STATUS_BAR` 未设置
|
|||
|
|
|
|||
|
|
**解决方案**:
|
|||
|
|
- 检查 Android 版本,6.0+ 才支持图标颜色设置
|
|||
|
|
- 确认 `SYSTEM_UI_FLAG_LIGHT_STATUS_BAR` 已正确设置
|
|||
|
|
|
|||
|
|
## 七、后续扩展
|
|||
|
|
|
|||
|
|
### 可能的优化方向
|
|||
|
|
1. **动态调整状态栏图标颜色**: 根据背景图亮度自动调整(深色/浅色)
|
|||
|
|
2. **支持不同 ROM**: 针对 MIUI、ColorOS 等做特殊处理
|
|||
|
|
3. **动画效果**: 添加返回按钮的点击动画效果
|
|||
|
|
4. **其他页面**: 将沉浸式效果应用到其他需要类似效果的页面
|
|||
|
|
|
|||
|
|
## 八、参考资源
|
|||
|
|
|
|||
|
|
- Android 官方文档: [System UI Visibility](https://developer.android.com/reference/android/view/View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
|
|||
|
|
- Android 官方文档: [Status Bar](https://developer.android.com/training/system-ui/status)
|
|||
|
|
- 项目内参考: `app/src/main/java/com/xunpaisoft/social/im/main/MainActivity.java` (状态栏颜色设置)
|
|||
|
|
- 项目内参考: `baselibrary/src/main/java/com/app/longguan/baselibrary/utils/BarUtils.java` (状态栏工具类)
|
|||
|
|
|
|||
|
|
## 九、变更历史
|
|||
|
|
|
|||
|
|
- **2025-11-04**: 初始实现沉浸式状态栏和返回按钮功能
|
|||
|
|
- 添加返回按钮到布局
|
|||
|
|
- 实现状态栏透明
|
|||
|
|
- 实现返回按钮位置动态调整
|
|||
|
|
|