完成Application-Category页

This commit is contained in:
胡天 2023-07-23 16:28:48 +08:00
parent 91c50070ec
commit ac67682918
7 changed files with 281 additions and 3 deletions

View File

@ -51,7 +51,7 @@ class ApplicationController extends GetxController {
super.onInit();
// tab
tabTitles = ['Welcome', 'Cagegory', 'Bookmarks', 'Account'];
tabTitles = ['Welcome', 'Category', 'Bookmarks', 'Account'];
bottomTabs = <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(

View File

@ -1,10 +1,13 @@
import 'package:get/get.dart';
import 'package:news_getx/data/repository/news_repository.dart';
import 'category_controller.dart';
class CategoryBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => CategoryController());
Get.lazyPut(() => CategoryController(
newsRepository: NewsRepository()
));
}
}

View File

@ -1,5 +1,76 @@
import 'package:get/get.dart';
import 'package:news_getx/data/model/news.dart';
import 'package:news_getx/data/repository/news_repository.dart';
import 'package:news_getx/modules/category/category_state.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class CategoryController extends GetxController {
NewsRepository newsRepository;
CategoryController({required this.newsRepository});
/// UI
final RefreshController refreshController = RefreshController(
initialRefresh: true,
);
///
final state = CategoryState();
///
String categoryCode = '';
int curPage = 1;
int pageSize = 20;
int total = 20;
///
void onRefresh() {
fetchNewsList(isRefresh: true).then((_) {
refreshController.refreshCompleted(resetFooterState: true);
}).catchError((_) {
refreshController.refreshFailed();
});
}
void onLoading() {
if (state.newsList.length < total) {
fetchNewsList().then((_) {
refreshController.loadComplete();
}).catchError((_) {
refreshController.loadFailed();
});
} else {
refreshController.loadNoData();
}
}
///
//
Future<void> fetchNewsList({bool isRefresh = false}) async {
var result = await newsRepository.newsPageList(
params: NewsPageListRequest(
categoryCode: categoryCode,
pageNum: curPage + 1,
pageSize: pageSize,
),
);
if (isRefresh) {
curPage = 1;
total = result.counts!;
state.newsList.clear();
} else {
curPage++;
}
state.newsList.addAll(result.items!);
}
///dispose
@override
void dispose() {
super.dispose();
refreshController.dispose();
}
}

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:news_getx/modules/category/widgets/news_page_list.dart';
import 'category_controller.dart';
@ -8,6 +9,8 @@ class CategoryPage extends GetView<CategoryController> {
@override
Widget build(BuildContext context) {
return Text('Categories');
return Scaffold(
body: NewsPageList(),
);
}
}

View File

@ -0,0 +1,7 @@
import 'package:get/get.dart';
import 'package:news_getx/data/model/news.dart';
class CategoryState {
//
RxList<NewsItem> newsList = <NewsItem>[].obs;
}

View File

@ -0,0 +1,142 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:news_getx/data/model/news.dart';
import 'package:news_getx/modules/widgets/image.dart';
import 'package:news_getx/theme/app_colors.dart';
import 'package:news_getx/utils/date.dart';
class NewsListItem extends StatelessWidget {
const NewsListItem({super.key, required this.newsItem});
final NewsItem newsItem;
@override
Widget build(BuildContext context) {
return Container(
height: 161.h,
padding: EdgeInsets.all(20.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//
InkWell(
onTap: () {
//
},
child: SizedBox(
width: 121.w,
height: 121.w,
child: netImageCached(
newsItem.thumbnail ?? "",
width: 121.w,
height: 121.w,
),
),
),
//
SizedBox(
width: 194.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//
Container(
margin: EdgeInsets.all(0),
child: Text(
newsItem.author ?? '',
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.thirdElementText,
fontSize: 14.sp,
),
),
),
//
InkWell(
onTap: () {
//
},
child: Container(
margin: EdgeInsets.only(top: 10.h),
child: Text(
newsItem.title ?? '',
overflow: TextOverflow.clip,
maxLines: 3,
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w500,
color: AppColors.primaryText,
fontSize: 16.sp,
),
),
),
),
Spacer(),
// 3
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ConstrainedBox(
//
constraints: BoxConstraints(maxWidth: 60.w),
child: Text(
newsItem.category ?? "",
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.secondaryElementText,
fontSize: 14.sp,
height: 1,
),
overflow: TextOverflow.clip,
maxLines: 1,
),
),
//
Container(
width: 15.w,
),
ConstrainedBox(
constraints: BoxConstraints(maxWidth: 100.w),
child: Text(
'${timeLineFormat(newsItem.addtime ?? DateTime(0))}',
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.thirdElementText,
fontSize: 14.sp,
height: 1,
),
overflow: TextOverflow.clip,
maxLines: 1,
),
),
//
Spacer(),
//
InkWell(
child: Icon(
Icons.more_horiz,
color: AppColors.primaryText,
size: 24,
),
onTap: () {
print('查看更多...');
},
),
],
),
),
],
),
),
],
),
);
}
}

View File

@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:news_getx/modules/category/category_controller.dart';
import 'package:news_getx/modules/category/widgets/news_item.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class NewsPageList extends StatefulWidget {
const NewsPageList({Key? key}) : super(key: key);
@override
State<NewsPageList> createState() => _NewsPageListState();
}
class _NewsPageListState extends State<NewsPageList>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
final controller = Get.find<CategoryController>();
@override
Widget build(BuildContext context) {
super.build(context);
return GetX<CategoryController>(
init: controller,
builder: (controller) {
return SmartRefresher(
controller: controller.refreshController,
enablePullUp: true,
onRefresh: controller.onRefresh,
onLoading: controller.onLoading,
child: CustomScrollView(
slivers: [
SliverPadding(
padding: EdgeInsets.symmetric(vertical: 0.w, horizontal: 0.h),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
var item = controller.state.newsList[index];
return NewsListItem(newsItem: item);
},
childCount: controller.state.newsList.length,
),
),
),
],
),
);
});
}
}