|
|
|
@ -1,17 +1,12 @@
|
|
|
|
|
// ignore_for_file: use_build_context_synchronously
|
|
|
|
|
|
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
|
import 'package:music_player_miao/widget/text_field.dart';
|
|
|
|
|
import 'package:image_picker/image_picker.dart';
|
|
|
|
|
import '../../api/api_client.dart';
|
|
|
|
|
import '../../api/api_client_info.dart';
|
|
|
|
|
import '../../common_widget/app_data.dart';
|
|
|
|
|
import '../../models/getInfo_bean.dart';
|
|
|
|
|
import '../../models/universal_bean.dart';
|
|
|
|
|
import '../../view_model/home_view_model.dart';
|
|
|
|
|
import 'package:image_picker/image_picker.dart';
|
|
|
|
|
import '../../view/main_tab_view/main_tab_view.dart';
|
|
|
|
|
|
|
|
|
|
class UserInfo extends StatefulWidget {
|
|
|
|
|
const UserInfo({super.key});
|
|
|
|
@ -23,7 +18,7 @@ class UserInfo extends StatefulWidget {
|
|
|
|
|
class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
final listVM = Get.put(HomeViewModel());
|
|
|
|
|
final TextEditingController _controller = TextEditingController();
|
|
|
|
|
late File _selectedImage;
|
|
|
|
|
File? _selectedImage;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
@ -42,7 +37,17 @@ class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
elevation: 0,
|
|
|
|
|
leading: IconButton(
|
|
|
|
|
onPressed: () {
|
|
|
|
|
Get.back();
|
|
|
|
|
// 返回到 MainTabView 并切换到“个人”标签页
|
|
|
|
|
Get.back(); // 关闭当前页面并返回到主界面
|
|
|
|
|
|
|
|
|
|
// 等待页面关闭后再切换标签
|
|
|
|
|
Future.delayed(Duration(milliseconds: 100), () {
|
|
|
|
|
// 查找 MainTabView 并获取 TabController
|
|
|
|
|
final mainTabController = Get.find<MainTabView>().getController(context);
|
|
|
|
|
if (mainTabController != null) {
|
|
|
|
|
mainTabController.index = 3; // 切换到“个人”标签页的索引
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
icon: Image.asset(
|
|
|
|
|
"assets/img/back.png",
|
|
|
|
@ -60,77 +65,8 @@ class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
body: SingleChildScrollView(
|
|
|
|
|
child: Column(
|
|
|
|
|
children: [
|
|
|
|
|
Container(
|
|
|
|
|
height: 80,
|
|
|
|
|
color: Colors.white.withOpacity(0.6),
|
|
|
|
|
padding: const EdgeInsets.only(left: 48, right: 25),
|
|
|
|
|
child: InkWell(
|
|
|
|
|
onTap: () {
|
|
|
|
|
_bottomSheet(context);
|
|
|
|
|
},
|
|
|
|
|
child: Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: [
|
|
|
|
|
const Text(
|
|
|
|
|
"头像",
|
|
|
|
|
style: TextStyle(fontSize: 20),
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
Image.network(
|
|
|
|
|
AppData().currentAvatar,
|
|
|
|
|
width: 64,
|
|
|
|
|
height: 64,
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
width: 20,
|
|
|
|
|
),
|
|
|
|
|
Image.asset(
|
|
|
|
|
"assets/img/user_next.png",
|
|
|
|
|
width: 25,
|
|
|
|
|
height: 25,
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Container(
|
|
|
|
|
height: 80,
|
|
|
|
|
color: Colors.white.withOpacity(0.6),
|
|
|
|
|
padding: const EdgeInsets.only(left: 48, right: 25),
|
|
|
|
|
child: InkWell(
|
|
|
|
|
onTap: () {
|
|
|
|
|
_showNicknameDialog();
|
|
|
|
|
},
|
|
|
|
|
child: Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: [
|
|
|
|
|
const Text(
|
|
|
|
|
"昵称",
|
|
|
|
|
style: TextStyle(fontSize: 20),
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
AppData().currentUsername,
|
|
|
|
|
style: const TextStyle(fontSize: 20),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(
|
|
|
|
|
width: 15,
|
|
|
|
|
),
|
|
|
|
|
Image.asset(
|
|
|
|
|
"assets/img/user_next.png",
|
|
|
|
|
width: 25,
|
|
|
|
|
height: 25,
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
_buildAvatarRow(),
|
|
|
|
|
_buildNicknameRow(),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
@ -138,68 +74,159 @@ class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建头像行
|
|
|
|
|
Widget _buildAvatarRow() {
|
|
|
|
|
return Container(
|
|
|
|
|
height: 80,
|
|
|
|
|
color: Colors.white.withOpacity(0.6),
|
|
|
|
|
padding: const EdgeInsets.only(left: 48, right: 25),
|
|
|
|
|
child: InkWell(
|
|
|
|
|
onTap: () {
|
|
|
|
|
_bottomSheet(context);
|
|
|
|
|
},
|
|
|
|
|
child: Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: [
|
|
|
|
|
const Text(
|
|
|
|
|
"头像",
|
|
|
|
|
style: TextStyle(fontSize: 20),
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
_buildAvatarImage(),
|
|
|
|
|
const SizedBox(width: 20),
|
|
|
|
|
Image.asset(
|
|
|
|
|
"assets/img/user_next.png",
|
|
|
|
|
width: 25,
|
|
|
|
|
height: 25,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建昵称行
|
|
|
|
|
Widget _buildNicknameRow() {
|
|
|
|
|
return Container(
|
|
|
|
|
height: 80,
|
|
|
|
|
color: Colors.white.withOpacity(0.6),
|
|
|
|
|
padding: const EdgeInsets.only(left: 48, right: 25),
|
|
|
|
|
child: InkWell(
|
|
|
|
|
onTap: () {
|
|
|
|
|
_showNicknameDialog();
|
|
|
|
|
},
|
|
|
|
|
child: Row(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: [
|
|
|
|
|
const Text(
|
|
|
|
|
"昵称",
|
|
|
|
|
style: TextStyle(fontSize: 20),
|
|
|
|
|
),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
AppData().currentUsername,
|
|
|
|
|
style: const TextStyle(fontSize: 20),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(width: 15),
|
|
|
|
|
Image.asset(
|
|
|
|
|
"assets/img/user_next.png",
|
|
|
|
|
width: 25,
|
|
|
|
|
height: 25,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示头像的 Widget,根据是否是网络 URL 或本地路径来动态加载
|
|
|
|
|
Widget _buildAvatarImage() {
|
|
|
|
|
final avatarPath = AppData().currentAvatar;
|
|
|
|
|
if (avatarPath.startsWith('http')) {
|
|
|
|
|
return Image.network(
|
|
|
|
|
avatarPath,
|
|
|
|
|
width: 64,
|
|
|
|
|
height: 64,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return Image.file(
|
|
|
|
|
File(avatarPath),
|
|
|
|
|
width: 64,
|
|
|
|
|
height: 64,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future _bottomSheet(BuildContext context) async {
|
|
|
|
|
final picker = ImagePicker();
|
|
|
|
|
await showModalBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
backgroundColor: Colors.white,
|
|
|
|
|
shape: const RoundedRectangleBorder(
|
|
|
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(30))),
|
|
|
|
|
builder: (context) => Container(
|
|
|
|
|
height: 132,
|
|
|
|
|
padding: const EdgeInsets.only(top: 20),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
|
children: [
|
|
|
|
|
ElevatedButton(
|
|
|
|
|
onPressed: () async {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
final pickedFile =
|
|
|
|
|
await picker.pickImage(source: ImageSource.gallery);
|
|
|
|
|
if (pickedFile != null) {
|
|
|
|
|
_selectedImage=File('assets/images/bg.png');
|
|
|
|
|
setState(() {
|
|
|
|
|
_selectedImage = File(pickedFile.path);
|
|
|
|
|
print(_selectedImage);
|
|
|
|
|
});
|
|
|
|
|
UniversalBean bean = await ChangeApiClient().changeHeader(
|
|
|
|
|
Authorization: AppData().currentToken,
|
|
|
|
|
avatar: _selectedImage);
|
|
|
|
|
GetInfoBean bean1 = await GetInfoApiClient().getInfo(
|
|
|
|
|
Authorization: AppData().currentToken);
|
|
|
|
|
AppData appData = AppData();
|
|
|
|
|
appData.box.write('currentAvatar', AppData().currentAvatar);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
elevation: 0,
|
|
|
|
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
|
|
|
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
|
|
|
),
|
|
|
|
|
child: const Text(
|
|
|
|
|
"从相册上传头像",
|
|
|
|
|
style: TextStyle(color: Colors.black, fontSize: 18),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
ElevatedButton(
|
|
|
|
|
onPressed: () => Navigator.pop(context),
|
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
|
backgroundColor: const Color(0xff429482),
|
|
|
|
|
padding: const EdgeInsets.symmetric(vertical: 18),
|
|
|
|
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
|
|
|
shape: const RoundedRectangleBorder(
|
|
|
|
|
borderRadius: BorderRadius.zero,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: const Text(
|
|
|
|
|
"取消",
|
|
|
|
|
style: TextStyle(color: Colors.black, fontSize: 18),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
context: context,
|
|
|
|
|
backgroundColor: Colors.white,
|
|
|
|
|
shape: const RoundedRectangleBorder(
|
|
|
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(30))),
|
|
|
|
|
builder: (context) => Container(
|
|
|
|
|
height: 132,
|
|
|
|
|
padding: const EdgeInsets.only(top: 20),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
|
children: [
|
|
|
|
|
ElevatedButton(
|
|
|
|
|
onPressed: () async {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
final pickedFile =
|
|
|
|
|
await picker.pickImage(source: ImageSource.gallery);
|
|
|
|
|
if (pickedFile != null) {
|
|
|
|
|
_selectedImage = File(pickedFile.path);
|
|
|
|
|
setState(() {}); // 更新 UI
|
|
|
|
|
|
|
|
|
|
// 上传头像
|
|
|
|
|
await ChangeApiClient().changeHeader(
|
|
|
|
|
Authorization: AppData().currentToken,
|
|
|
|
|
avatar: _selectedImage!);
|
|
|
|
|
|
|
|
|
|
// 更新本地存储
|
|
|
|
|
_updatetouxiang(_selectedImage!.path);
|
|
|
|
|
// 拉取更新后的用户信息
|
|
|
|
|
await GetInfoApiClient().getInfo(
|
|
|
|
|
Authorization: AppData().currentToken);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
elevation: 0,
|
|
|
|
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
|
|
|
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
|
|
|
),
|
|
|
|
|
));
|
|
|
|
|
child: const Text(
|
|
|
|
|
"从相册上传头像",
|
|
|
|
|
style: TextStyle(color: Colors.black, fontSize: 18),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
ElevatedButton(
|
|
|
|
|
onPressed: () => Navigator.pop(context),
|
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
|
backgroundColor: const Color(0xff429482),
|
|
|
|
|
padding: const EdgeInsets.symmetric(vertical: 18),
|
|
|
|
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
|
|
|
shape: const RoundedRectangleBorder(
|
|
|
|
|
borderRadius: BorderRadius.zero,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: const Text(
|
|
|
|
|
"取消",
|
|
|
|
|
style: TextStyle(color: Colors.black, fontSize: 18),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _showNicknameDialog() {
|
|
|
|
@ -209,12 +236,12 @@ class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
return AlertDialog(
|
|
|
|
|
title: const Center(
|
|
|
|
|
child: Text(
|
|
|
|
|
"修改昵称",
|
|
|
|
|
style: TextStyle(fontSize: 20),
|
|
|
|
|
)),
|
|
|
|
|
content: TextFieldColor(
|
|
|
|
|
"修改昵称",
|
|
|
|
|
style: TextStyle(fontSize: 20),
|
|
|
|
|
)),
|
|
|
|
|
content: TextField(
|
|
|
|
|
controller: _controller,
|
|
|
|
|
hintText: '请输入新昵称',
|
|
|
|
|
decoration: const InputDecoration(hintText: '请输入新昵称'),
|
|
|
|
|
),
|
|
|
|
|
actions: <Widget>[
|
|
|
|
|
TextButton(
|
|
|
|
@ -225,8 +252,7 @@ class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
backgroundColor: const Color(0xff429482),
|
|
|
|
|
minimumSize: const Size(130, 50),
|
|
|
|
|
shape: RoundedRectangleBorder(
|
|
|
|
|
borderRadius:
|
|
|
|
|
BorderRadius.circular(5.0), // Adjust the radius as needed
|
|
|
|
|
borderRadius: BorderRadius.circular(5.0),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: const Text(
|
|
|
|
@ -237,7 +263,7 @@ class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
TextButton(
|
|
|
|
|
onPressed: () async {
|
|
|
|
|
_updateNickname();
|
|
|
|
|
UniversalBean bean = await ChangeApiClient().changeName(
|
|
|
|
|
await ChangeApiClient().changeName(
|
|
|
|
|
Authorization: AppData().currentToken,
|
|
|
|
|
userName: AppData().currentUsername);
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
@ -246,8 +272,7 @@ class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
backgroundColor: const Color(0xff429482),
|
|
|
|
|
minimumSize: const Size(130, 50),
|
|
|
|
|
shape: RoundedRectangleBorder(
|
|
|
|
|
borderRadius:
|
|
|
|
|
BorderRadius.circular(5.0), // Adjust the radius as needed
|
|
|
|
|
borderRadius: BorderRadius.circular(5.0),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: const Text(
|
|
|
|
@ -267,4 +292,14 @@ class _UserInfoState extends State<UserInfo> {
|
|
|
|
|
appData.box.write('currentUsername', _controller.text);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _updatetouxiang(String path) {
|
|
|
|
|
setState(() {
|
|
|
|
|
AppData appData = AppData();
|
|
|
|
|
appData.box.write('currentAvatar', path); // 更新头像路径到本地存储
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|