Files
zhini_im/PublishActivity发布帖子页面逻辑分析.txt
rw0067680 c01808ac21 first commit
Change-Id: Ib7c2ab10a2562044fcaf9879388a6cbc1db6ac61
2025-12-23 10:00:49 +08:00

372 lines
12 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PublishActivity 发布帖子页面逻辑分析
## 📋 页面概述
**文件位置**: `uikit/src/main/java/cn/wildfire/chat/kit/user/PublishActivity.java`
**布局文件**: `uikit/src/main/res/layout/activity_publish.xml`
**页面类型**: Activity继承自 WfcBaseActivity
**主要功能**: 发布朋友圈动态,支持文字和图片内容发布
---
## 🎯 核心功能模块
### 1. 页面初始化 (`afterViews()`)
#### 1.1 UI组件初始化
```java
mRecyPicItem = findViewById(R.id.rcy_pic_item); // 图片选择RecyclerView
mEdtContent = findViewById(R.id.edt_content); // 内容输入框
oiv_show = findViewById(R.id.oiv_show); // 可见范围设置(默认隐藏)
```
#### 1.2 状态栏设置
```java
setTitleBackgroundResource(R.color.white, false); // 白色状态栏,深色图标
```
#### 1.3 初始化操作
- ✅ 获取七牛云Token`getQnToken()` - 用于图片上传
- ✅ 初始化图片选择器:`initWidget()` - 设置RecyclerView和适配器
- ✅ 设置默认可见范围:`oiv_show.setDesc("公开")` - 默认值为"公开"`mShowType = "1"`
---
### 2. 图片选择功能 (`initWidget()`)
#### 2.1 RecyclerView配置
```java
// 网格布局3列垂直方向
FunctionBackGridLayoutManager manager = new FunctionBackGridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false);
mRecyPicItem.setLayoutManager(manager);
// 适配器配置
adapter = new FunctionBackImageAdapter(this, onAddPicClickListener);
adapter.setList(selectList); // 设置图片列表
adapter.setSelectMax(MAX_SELECT_NUM); // 最大选择数量9张
mRecyPicItem.setAdapter(adapter);
```
#### 2.2 关键常量
- `MAX_SELECT_NUM = 9`最多选择9张图片
- `MIN_SELECT_NUM = 1`最少选择1张图片
- `SPAN_COUNT_NUM = 3`每行显示3张图片
#### 2.3 图片选择回调 (`onAddPicClickListener`)
当用户点击"添加图片"按钮时:
1. 计算可选择的图片数量:`number = MAX_SELECT_NUM - selectList.size()`
2. 显示选择对话框:`CameraSelectDialog` - 提供"拍照"和"从相册选择"两个选项
---
### 3. 图片上传流程
#### 3.1 上传步骤
**步骤1选择图片**
- **拍照**`PictureSelector.create().openCamera()` - 调用系统相机
- **相册选择**`PictureSelector.create().openGallery()` - 打开相册选择
**步骤2图片压缩**
```java
Luban.with(mContext)
.load(realPath) // 加载原始图片路径
.setCompressListener(...) // 设置压缩监听器
.launch(); // 启动压缩
```
- 使用 `Luban` 库进行图片压缩,减小上传文件大小
**步骤3上传到七牛云**
```java
QiniuUploadFile.uploadFile(
file.getName(), // 文件名
mQnToken, // 七牛云Token从服务器获取
file, // 压缩后的文件
new UploadCallBack() { // 上传回调
@Override
public void result(boolean isSuccess, String address) {
// 上传成功address为图片URL
// 创建PhotoInfoEntity并添加到列表
PhotoInfoEntity photoInfoEntity = new PhotoInfoEntity()
.setUrl(address) // 完整URL
.setMinUrl(address); // 缩略图URL当前使用相同URL
arrayListPhoto.add(photoInfoEntity);
adapter.setList(arrayListPhoto);
adapter.notifyDataSetChanged();
}
}
);
```
#### 3.2 数据结构
```java
PhotoInfoEntity {
String url; // 图片完整URL
String minUrl; // 图片缩略图URL
}
```
---
### 4. 发布功能 (`setToolbarSave` 点击事件)
#### 4.1 数据收集
```java
String content = mEdtContent.getText().toString().trim(); // 获取文字内容
HashMap<String, String> headMaps = new HashMap<>();
// 1. 添加文字内容
headMaps.put("content", content);
// 2. 添加可见范围1:公开, 2:仅好友可见)
headMaps.put("ispravite", mShowType);
// 3. 添加图片URL列表逗号分隔
if(adapter != null) {
List<PhotoInfoEntity> list = adapter.getList();
StringBuffer listBuffer = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
PhotoInfoEntity photoInfoEntity = list.get(i);
if ((list.size() - 1) == i) {
listBuffer.append(photoInfoEntity.getUrl()); // 最后一张不加逗号
} else {
listBuffer.append(photoInfoEntity.getUrl()).append(","); // 其他加逗号
}
}
headMaps.put("images", listBuffer.toString()); // 图片URL列表格式url1,url2,url3
}
// 4. 添加定位信息从本地SharedPreferences读取如果存在
String latitude = SharedPreferencesUtils.getString("location_latitude", "");
String longitude = SharedPreferencesUtils.getString("location_longitude", "");
String poi = SharedPreferencesUtils.getString("location_poi", "");
// 5. 添加省市区信息(优先使用定位获取的,如果为空则使用用户手动设置的)
String province = SharedPreferencesUtils.getString("location_province", "");
String city = SharedPreferencesUtils.getString("location_city", "");
String district = SharedPreferencesUtils.getString("location_district", "");
// 如果定位的省市区为空,则使用用户手动设置的省市区
if (TextUtils.isEmpty(province)) {
province = SharedPreferencesUtils.getString("user_province", "");
}
if (TextUtils.isEmpty(city)) {
city = SharedPreferencesUtils.getString("user_city", "");
}
if (TextUtils.isEmpty(district)) {
district = SharedPreferencesUtils.getString("user_district", "");
}
// 添加定位信息(如果存在)
if (!TextUtils.isEmpty(latitude)) {
headMaps.put("lat", latitude);
}
if (!TextUtils.isEmpty(longitude)) {
headMaps.put("lng", longitude);
}
if (!TextUtils.isEmpty(poi)) {
headMaps.put("poi", poi);
}
// 添加省市区信息(如果存在)
if (!TextUtils.isEmpty(province)) {
headMaps.put("province", province);
}
if (!TextUtils.isEmpty(city)) {
headMaps.put("city", city);
}
if (!TextUtils.isEmpty(district)) {
headMaps.put("district", district);
}
```
#### 4.2 数据验证
```java
if (TextUtils.isEmpty(content) && TextUtils.isEmpty(listBuffer.toString())) {
ToastUtils.showToast(PublishActivity.this, "发布内容为空!");
return; // 文字和图片都为空,不允许发布
}
```
#### 4.3 提交发布请求
```java
AppService.Instance().publishContent(headMaps, new SimpleCallback() {
@Override
public void onUiSuccess(Object o) {
showToast("发布成功");
finish(); // 发布成功,关闭页面
}
@Override
public void onUiFailure(int code, String msg) {
showToast(msg); // 显示错误信息
}
});
```
---
### 5. 可见范围设置 (`bindEvents()`)
#### 5.1 可见范围选项
- **"公开"** (`mShowType = "1"`):所有人可见
- **"仅好友可见"** (`mShowType = "2"`):仅好友可见
#### 5.2 交互流程
1. 用户点击 `oiv_show`"谁可以看"
2. 显示对话框:`PublishShowTypeDialog`
3. 用户选择可见范围:
- 点击"公开"`mShowType = "1"`, `oiv_show.setDesc("公开")`
- 点击"仅好友可见"`mShowType = "2"`, `oiv_show.setDesc("仅好友可见")`
4. 关闭对话框
---
### 6. 七牛云Token获取 (`getQnToken()`)
```java
AppService.Instance().getQnToken(new SimpleCallback<GetQnTokenResult>() {
@Override
public void onUiSuccess(GetQnTokenResult getQnTokenResult) {
GetQnTokenResult data = getQnTokenResult.getData();
mQnToken = data.getToken(); // 保存Token用于后续图片上传
}
@Override
public void onUiFailure(int code, String msg) {
// Token获取失败不影响页面显示但图片无法上传
}
});
```
**说明**
- Token在页面初始化时获取`afterViews()`
- Token用于七牛云图片上传认证
- 如果Token获取失败图片上传功能将无法使用
---
## 🔄 完整业务流程
```
用户打开PublishActivity
初始化UI输入框、图片列表、可见范围
获取七牛云TokengetQnToken
用户输入文字内容(可选)
用户选择图片(拍照/相册)
图片压缩Luban
上传图片到七牛云QiniuUploadFile
图片URL添加到列表arrayListPhoto
用户点击"发布"按钮
验证内容(文字或图片至少有一个)
收集数据content、images、ispravite
调用发布接口AppService.publishContent
发布成功 → 关闭页面
发布失败 → 显示错误信息
```
---
## 📊 数据结构
### 发布请求参数
```java
HashMap<String, String> {
"content": "文字内容", // 可选,文字内容
"images": "url1,url2,url3", // 可选图片URL列表逗号分隔
"ispravite": "1", // 必填可见范围1:公开, 2:仅好友可见)
"province": "省份", // 可选,省份(从定位或用户设置获取)
"city": "城市", // 可选,城市(从定位或用户设置获取)
"district": "区县", // 可选,区县(从定位或用户设置获取)
"lat": "纬度", // 可选,纬度(从定位获取)
"lng": "经度", // 可选,经度(从定位获取)
"poi": "地点" // 可选,地点/详细地址(从定位获取)
}
```
### 图片实体
```java
PhotoInfoEntity {
String url; // 图片完整URL从七牛云获取
String minUrl; // 图片缩略图URL当前使用相同URL
}
```
---
## 🛠️ 技术要点
### 1. 图片选择
- **库**`PictureSelector` - 强大的图片选择库
- **功能**:支持拍照、相册选择、多选等
### 2. 图片压缩
- **库**`Luban` - 图片压缩库
- **目的**:减小图片文件大小,提高上传速度
### 3. 图片上传
- **云存储**七牛云Qiniu
- **流程**:本地文件 → 压缩 → 上传到七牛云 → 获取URL
### 4. RecyclerView适配器
- **适配器**`FunctionBackImageAdapter`
- **布局管理器**`FunctionBackGridLayoutManager`自定义支持3列网格布局
---
## ⚠️ 注意事项
1. **内容验证**:文字和图片至少需要有一个,否则不允许发布
2. **Token获取**必须在图片上传前获取Token否则上传会失败
3. **图片数量限制**最多选择9张图片
4. **可见范围**:默认为"公开"`mShowType = "1"`),用户可手动修改为"仅好友可见"
5. **图片上传异步**:图片选择后立即开始压缩和上传,上传成功后自动添加到列表
---
## 🔍 相关文件
- **布局文件**`uikit/src/main/res/layout/activity_publish.xml`
- **网络服务**`AppService.publishContent()` - 发布接口
- **网络服务**`AppService.getQnToken()` - 获取七牛云Token
- **图片上传**`QiniuUploadFile.uploadFile()` - 七牛云上传方法
- **适配器**`FunctionBackImageAdapter` - 图片列表适配器
---
## 📝 代码关键位置
### 发布按钮点击第96-134行
```java
setToolbarSave("发布", new View.OnClickListener() {
// 收集数据并提交发布请求
});
```
### 图片选择回调第204-369行
```java
private FunctionBackImageAdapter.onAddPicClickListener onAddPicClickListener = new ... {
// 处理图片选择、压缩、上传逻辑
};
```
### 可见范围设置第143-162行
```java
findViewById(R.id.oiv_show).setOnClickListener(view -> {
// 显示可见范围选择对话框
});
```