fix_个人中心&博主主页

This commit is contained in:
abu 2025-10-13 22:52:47 +08:00
parent 314aeddf23
commit 67ed131eeb
3 changed files with 250 additions and 201 deletions

View File

@ -543,16 +543,6 @@ class _IndexPageState extends State<IndexPage> with TickerProviderStateMixin {
SliverToBoxAdapter(
child: Obx(
() {
// if (isInitLoading.value) {
// return Column(
// children: [
// RefreshProgressIndicator(
// backgroundColor: Colors.white,
// color: Color(0xFFFF5000),
// ),
// ],
// );
// }
if (dataList.isEmpty) {
return EmptyTip();
}

View File

@ -28,7 +28,7 @@ import '../../utils/common.dart';
class PageParams {
int page;
int pageSize;
bool isLoading;
RxBool isLoading;
RxBool hasMore;
int total;
bool isInitLoading;
@ -36,16 +36,21 @@ class PageParams {
PageParams({
this.page = 1,
this.pageSize = 10,
this.isLoading = false,
bool isLoading = false,
bool hasMore = true,
this.total = 0,
this.isInitLoading = true,
}) : hasMore = hasMore.obs;
}) : hasMore = hasMore.obs,
isLoading = isLoading.obs;
@override
String toString() {
return 'PageParams(page: $page, pageSize: $pageSize, isLoading: ${isLoading.value}, hasMore: ${hasMore.value})';
}
void init() {
page = 1;
pageSize = 10;
isLoading = false;
isLoading.value = false;
hasMore.value = true;
total = 0;
isInitLoading = true;
@ -98,16 +103,16 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
super.initState();
imUserInfoController = Get.find<ImUserInfoController>();
initControllers();
//
scrollListener = () {
final pos = scrollController.position;
final isNearBottom = pos.pixels >= pos.maxScrollExtent - 100;
if (!isNearBottom) return;
if (currentTabIndex.value == 0 && !itemsParams.isLoading && itemsParams.hasMore.value) {
if (currentTabIndex.value == 0 && !itemsParams.isLoading.value && itemsParams.hasMore.value) {
loadData(0);
} else if (currentTabIndex.value == 1 && !favoriteParams.isLoading && favoriteParams.hasMore.value) {
} else if (currentTabIndex.value == 1 && !favoriteParams.isLoading.value && favoriteParams.hasMore.value) {
loadData(1);
}
};
@ -124,8 +129,6 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
}
};
tabController.addListener(tabListener);
// loadData(0);
}
@override
@ -165,10 +168,10 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
Future<void> loadData([int? tabIndex]) async {
final index = tabIndex ?? currentTabIndex.value;
if (index == 0) {
if (itemsParams.isLoading || !itemsParams.hasMore.value) return;
itemsParams.isLoading = true;
// itemsParams.isInitLoading = true;
if (itemsParams.isLoading.value || !itemsParams.hasMore.value) return;
WidgetsBinding.instance.addPostFrameCallback((_) {
itemsParams.isLoading.value = true;
});
final res = await Http.post(VideoApi.myPublicList, data: {
"userId": imUserInfoController.userID.value,
@ -179,25 +182,22 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
final obj = res['data'];
final total = obj['total'];
final row = obj['records'] ?? [];
logger.i(res['data']);
//
logger.e(items.length);
//
items.addAll(row);
logger.e(obj);
itemsParams.page++;
if (items.length >= total) {
itemsParams.hasMore.value = false;
}
//
itemsParams.page++;
//
itemsParams.isLoading = false;
itemsParams.isLoading.value = false;
itemsParams.isInitLoading = false;
} else if (index == 1) {
if (favoriteParams.isLoading || !favoriteParams.hasMore.value) return;
favoriteParams.isLoading = true;
// favoriteParams.isInitLoading = true;
if (favoriteParams.isLoading.value || !favoriteParams.hasMore.value) return;
WidgetsBinding.instance.addPostFrameCallback((_) {
favoriteParams.isLoading.value = true;
});
final res = await Http.post(VideoApi.myLikedList, data: {
"userId": imUserInfoController.userID.value,
@ -209,14 +209,14 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
final total = obj['total'];
final row = obj['records'] ?? [];
favoriteItems.addAll(row);
favoriteParams.page++;
if (favoriteItems.length >= total) {
favoriteParams.hasMore.value = false;
}
favoriteParams.page++;
favoriteParams.isLoading = false;
favoriteParams.isLoading.value = false;
favoriteParams.isInitLoading = false;
logger.e(favoriteParams.toString());
}
}
@ -583,46 +583,65 @@ class MyPageState extends State<MyPage> with SingleTickerProviderStateMixin {
if (listToShow.isEmpty) {
return emptyTip('暂无相关数据');
}
return CustomScrollView(
// physics: !isPinned.value ? NeverScrollableScrollPhysics() : AlwaysScrollableScrollPhysics(),
// physics: AlwaysScrollableScrollPhysics(),
key: PageStorageKey('myindex_$tabIndex'),
slivers: [
SliverPadding(
padding: EdgeInsets.all(10.0),
sliver: SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
decoration: BoxDecoration(
color: Colors.blue[100 * ((index % 8) + 1)],
borderRadius: BorderRadius.circular(10.0),
),
alignment: Alignment.center,
child: _buildVdCard(listToShow[index], tabIndex),
);
},
childCount: listToShow.length,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: 0.6,
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20.0),
child: Center(
child: Obx(
() => params.hasMore.value ? CircularProgressIndicator() : Text('没有更多数据了'),
return NotificationListener<ScrollNotification>(
onNotification: (notification) {
if (notification is ScrollUpdateNotification) {
final metrics = notification.metrics;
final isNearBottom = metrics.pixels == metrics.maxScrollExtent;
if (isNearBottom && !params.isLoading.value && params.hasMore.value) {
loadData(tabIndex);
}
}
return false;
},
child: CustomScrollView(
key: PageStorageKey('myindex_$tabIndex'),
slivers: [
SliverPadding(
padding: EdgeInsets.all(10.0),
sliver: SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
decoration: BoxDecoration(
color: Colors.blue[100 * ((index % 8) + 1)],
borderRadius: BorderRadius.circular(10.0),
),
alignment: Alignment.center,
child: _buildVdCard(listToShow[index], tabIndex),
);
},
childCount: listToShow.length,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: 0.6,
),
),
),
),
],
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: Center(
child: Obx(
() {
if (params.isLoading.value) {
return SafeArea(top: false, child: CircularProgressIndicator());
} else if (!params.hasMore.value) {
return SafeArea(top: false, child: Text('没有更多数据了'));
} else {
return SizedBox(height: 20);
}
},
),
),
),
),
],
),
);
}

View File

@ -23,15 +23,20 @@ import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
class PageParams {
int page;
int pageSize;
bool isLoading;
bool hasMore;
RxBool isLoading;
RxBool hasMore;
PageParams({
this.page = 1,
this.pageSize = 10,
this.isLoading = false,
this.hasMore = true,
});
this.pageSize = 12,
bool isLoading = false,
bool hasMore = true,
}) : hasMore = hasMore.obs,
isLoading = isLoading.obs;
@override
String toString() {
return 'PageParams(page: $page, pageSize: $pageSize, isLoading: ${isLoading.value}, hasMore: ${hasMore.value})';
}
}
class Vloger extends StatefulWidget {
@ -67,7 +72,7 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
));
RxBool get shouldFixHeader => (currentTabIndex.value == 0 && items.isEmpty) || (currentTabIndex.value == 1 && favoriteItems.isEmpty) ? true.obs : false.obs;
RxInt totalCount = 0.obs;
List tabList = [
{'name': "作品"},
];
@ -85,24 +90,21 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
void initState() {
super.initState();
args = Get.arguments ?? {};
print('argsssssssssssssssssssssss$args');
logger.e(args);
itemsParams = PageParams();
favoriteParams = PageParams();
selfInfo();
flowInfo();
checkFollowType();
initControllers();
//
scrollListener = () {
final pos = scrollController.position;
final isNearBottom = pos.pixels >= pos.maxScrollExtent - 100;
if (!isNearBottom) return;
if (currentTabIndex.value == 0 && !itemsParams.isLoading && itemsParams.hasMore) {
if (currentTabIndex.value == 0 && !itemsParams.isLoading.value && itemsParams.hasMore.value) {
loadData(0);
} else if (currentTabIndex.value == 1 && !favoriteParams.isLoading && favoriteParams.hasMore) {
loadData(1);
}
};
scrollController.addListener(scrollListener);
@ -133,18 +135,27 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
void getUserLikesCount() async {
try {
final resData = await Http.get('${CommonApi.accountInfo}?memberId=${args['memberId']}');
print('aaaaaaaaaaaaaaaaaaa$resData');
logger.e('$resData');
if (resData != null && resData['code'] == 200) {
vlogLikeCount = resData['data']['vlogLikeCount'] ?? 0;
}
} catch (e) {}
} catch (e) {
logger.e(e);
}
}
void loadData([int? tabIndex]) async {
final index = tabIndex ?? currentTabIndex.value;
if (index == 0) {
if (itemsParams.isLoading || !itemsParams.hasMore) return;
itemsParams.isLoading = true;
if (itemsParams.isLoading.value || !itemsParams.hasMore.value) return;
WidgetsBinding.instance.addPostFrameCallback((_) {
itemsParams.isLoading.value = true;
});
// await Future.delayed(Duration(seconds: 5), () {
// logger.e('5秒后执行完毕');
// });
final res = await Http.post(VideoApi.getVideoListByMemberId, data: {
"memberId": args['memberId'],
"current": itemsParams.page,
@ -153,19 +164,20 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
final obj = res['data'];
final total = obj['total'];
final row = obj['records'] ?? [];
logger.i(res['data']);
// logger.i(res['data']);
totalCount.value = total;
//
logger.e(items.length);
//
items.addAll(row);
logger.e(obj);
if (items.length >= total) {
itemsParams.hasMore = false;
}
//
itemsParams.page++;
//
itemsParams.isLoading = false;
if (items.length >= total) {
itemsParams.hasMore.value = false;
}
itemsParams.isLoading.value = false;
logger.e(itemsParams.toString());
}
}
@ -418,14 +430,20 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
controller: tabController,
tabs: tabList.map((item) {
return Tab(
child: Badge.count(
backgroundColor: Colors.red,
count: item['badge'] ?? 0,
isLabelVisible: item['badge'] != null,
alignment: Alignment.topRight,
offset: const Offset(14, -6),
child: Text(item['name'], style: const TextStyle(fontWeight: FontWeight.bold)),
child: Obx(
() => Text(
'${item['name']}(${totalCount.value})',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
// child: Badge.count(
// backgroundColor: Colors.red,
// count: item['badge'] ?? 0,
// isLabelVisible: item['badge'] != null,
// alignment: Alignment.topRight,
// offset: const Offset(14, -6),
// child: Text(item['name'], style: const TextStyle(fontWeight: FontWeight.bold)),
// ),
);
}).toList(),
isScrollable: true, //
@ -496,111 +514,133 @@ class MyPageState extends State<Vloger> with SingleTickerProviderStateMixin {
if (listToShow.isEmpty) {
return emptyTip('暂无相关数据');
}
return NotificationListener<ScrollNotification>(
onNotification: (notification) {
if (notification is ScrollUpdateNotification) {
final metrics = notification.metrics;
final isNearBottom = metrics.pixels >= metrics.maxScrollExtent;
return CustomScrollView(
slivers: [
SliverPadding(
padding: const EdgeInsets.all(10.0),
sliver: SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) {
final item = listToShow[index];
return GestureDetector(
onTap: () {
//
Get.toNamed('/videoDetail', arguments: {'videoId': item['id']});
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Stack(
fit: StackFit.expand,
children: [
//
NetworkOrAssetImage(
imageUrl: item['firstFrameImg'] ?? item['cover'],
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
placeholderAsset: 'assets/images/bk.jpg',
),
//
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
height: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Colors.black.withOpacity(0.6),
Colors.transparent,
],
),
),
),
),
//
Positioned(
right: 8,
bottom: 8,
child: Row(
children: [
const Icon(
Icons.favorite,
color: Colors.white,
size: 16,
),
const SizedBox(width: 4),
Text(
'${item['likeCounts'] ?? 0}',
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
if (isNearBottom && !params.isLoading.value && params.hasMore.value) {
loadData(0);
}
}
return false;
},
child: CustomScrollView(
slivers: [
SliverPadding(
padding: const EdgeInsets.all(10.0),
sliver: SliverGrid(
delegate: SliverChildBuilderDelegate(
(context, index) {
final item = listToShow[index];
return GestureDetector(
onTap: () {
//
Get.toNamed('/videoDetail', arguments: {'videoId': item['id']});
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 4,
offset: const Offset(0, 2),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Stack(
fit: StackFit.expand,
children: [
//
NetworkOrAssetImage(
imageUrl: item['firstFrameImg'] ?? item['cover'],
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
placeholderAsset: 'assets/images/bk.jpg',
),
//
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
height: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Colors.black.withOpacity(0.6),
Colors.transparent,
],
),
),
),
),
//
Positioned(
right: 8,
bottom: 8,
child: Row(
children: [
const Icon(
Icons.favorite,
color: Colors.white,
size: 16,
),
const SizedBox(width: 4),
Text(
'${item['likeCounts'] ?? 0}',
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
),
),
),
);
},
childCount: listToShow.length,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: 0.7, //
);
},
childCount: listToShow.length,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: 0.6, // 1=
),
),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20.0),
child: Center(
child: params.hasMore ? const CircularProgressIndicator() : const Text('没有更多数据了'),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20.0),
child: Center(
child: Obx(
() {
if (params.isLoading.value) {
return SafeArea(top: false, child: CircularProgressIndicator());
} else if (!params.hasMore.value) {
return SafeArea(top: false, child: Text('没有更多数据了'));
} else {
return SizedBox(height: 20);
}
},
),
),
),
),
),
],
],
),
);
}