first commit
Change-Id: Ib7c2ab10a2562044fcaf9879388a6cbc1db6ac61
This commit is contained in:
261
沉浸式顶部修改.txt
Normal file
261
沉浸式顶部修改.txt
Normal file
@@ -0,0 +1,261 @@
|
||||
# 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**: 初始实现沉浸式状态栏和返回按钮功能
|
||||
- 添加返回按钮到布局
|
||||
- 实现状态栏透明
|
||||
- 实现返回按钮位置动态调整
|
||||
|
||||
Reference in New Issue
Block a user