完成Application-Category页
This commit is contained in:
parent
91c50070ec
commit
ac67682918
|
@ -51,7 +51,7 @@ class ApplicationController extends GetxController {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
|
||||||
// 准备静态数据 作为tab
|
// 准备静态数据 作为tab
|
||||||
tabTitles = ['Welcome', 'Cagegory', 'Bookmarks', 'Account'];
|
tabTitles = ['Welcome', 'Category', 'Bookmarks', 'Account'];
|
||||||
bottomTabs = <BottomNavigationBarItem>[
|
bottomTabs = <BottomNavigationBarItem>[
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:news_getx/data/repository/news_repository.dart';
|
||||||
|
|
||||||
import 'category_controller.dart';
|
import 'category_controller.dart';
|
||||||
|
|
||||||
class CategoryBinding extends Bindings {
|
class CategoryBinding extends Bindings {
|
||||||
@override
|
@override
|
||||||
void dependencies() {
|
void dependencies() {
|
||||||
Get.lazyPut(() => CategoryController());
|
Get.lazyPut(() => CategoryController(
|
||||||
|
newsRepository: NewsRepository()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,76 @@
|
||||||
import 'package:get/get.dart';
|
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 {
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:news_getx/modules/category/widgets/news_page_list.dart';
|
||||||
|
|
||||||
import 'category_controller.dart';
|
import 'category_controller.dart';
|
||||||
|
|
||||||
|
@ -8,6 +9,8 @@ class CategoryPage extends GetView<CategoryController> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Text('Categories');
|
return Scaffold(
|
||||||
|
body: NewsPageList(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:news_getx/data/model/news.dart';
|
||||||
|
|
||||||
|
class CategoryState {
|
||||||
|
// 分类
|
||||||
|
RxList<NewsItem> newsList = <NewsItem>[].obs;
|
||||||
|
}
|
|
@ -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('查看更多...');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue