完成Application-Main页,调整构建代理以及仓库地址。

This commit is contained in:
胡天 2023-07-22 23:33:46 +08:00
parent 69f3d9d64c
commit 91c50070ec
13 changed files with 429 additions and 42 deletions

View File

@ -3,6 +3,8 @@ buildscript {
repositories {
google()
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/public/' }
}
dependencies {
@ -15,6 +17,9 @@ allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/public/' }
}
}

View File

@ -2,3 +2,9 @@ org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
#org.gradle.java.home=D\:\\Android\\Android Studio\\jbr
# 配置 VPN 加快下载速度
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=7890
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=7890

View File

@ -1,4 +1,5 @@
/// Api地址
const String ServerApiUrl = "http://172.31.163.87:4523/m1/2998542-0-default";
// const String ServerApiUrl = "http://172.31.163.87:4523/m1/2998542-0-default";
const String ServerApiUrl = "http://192.168.1.5:4523/m1/2998542-0-default";
const CryptoSalt = "E1pWsyfiy@R@X#qn17!StJNdZK1fFF8iV6ffN!goZkqt#JxO";

View File

@ -44,7 +44,7 @@ class ApplicationPage extends GetView<ApplicationController> {
onPageChanged: controller.handlePageChange,
children: <Widget>[
MainPage(),
Text('Categories'),
CategoryPage(),
Text('BookmarksPage'),
Text('AccountPage'),
],
@ -68,6 +68,7 @@ class ApplicationPage extends GetView<ApplicationController> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xfff6f6f6),
appBar: _buildAppBar(),
body: _buildPageView(),
bottomNavigationBar: _buildBottomNavigationBar(),

View File

@ -3,13 +3,11 @@ import 'package:get/get.dart';
import 'category_controller.dart';
class CategoryPage extends StatelessWidget {
class CategoryPage extends GetView<CategoryController> {
const CategoryPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final controller = Get.find<CategoryController>();
return Container();
return Text('Categories');
}
}

View File

@ -19,6 +19,7 @@ class MainController extends GetxController {
///
//
asyncLoadAllData() async {
print('开始拉取数据');
state.categories = await newsRepository.categories(cacheDisk: true);
state.channels = await newsRepository.channels(cacheDisk: true);
//

View File

@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:news_getx/modules/main/widgets/categories.dart';
import 'package:news_getx/modules/main/widgets/channels.dart';
import 'package:news_getx/modules/main/widgets/news_letter.dart';
import 'package:news_getx/modules/main/widgets/news_list.dart';
import 'package:news_getx/modules/main/widgets/recommend.dart';
import 'main_controller.dart';
@ -17,11 +20,11 @@ class MainPage extends GetView<MainController> {
Divider(height: 1),
NewsRecommendWidget(),
Divider(height: 1),
Text('NewsChannelsWidget'),
NewsChannelsWidget(),
Divider(height: 1),
Text('NewsListWidget'),
NewsListWidget(),
Divider(height: 1),
Text('NewsletterWidget'),
NewsLetterWidget(),
],
),
);

View File

@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:news_getx/modules/main/main_controller.dart';
import 'package:news_getx/theme/app_borders.dart';
import 'package:news_getx/theme/app_colors.dart';
import 'package:news_getx/theme/app_radii.dart';
class AdWidget extends GetView<MainController>{
@override
Widget build(BuildContext context) {
return Container(
height: 100.h,
padding: EdgeInsets.all(20.w),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20.w),
decoration: BoxDecoration(
// border
border: Border.fromBorderSide(AppBorders.primaryBorder),
borderRadius: Radii.k6pxRadius,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Tired of Ads? Get Premium - \$9.99",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 18.sp,
height: 18.sp / 18,
),
),
],
),
),
);
}
}

View File

@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:news_getx/data/model/channels.dart';
import 'package:news_getx/modules/main/main_controller.dart';
import 'package:news_getx/theme/app_colors.dart';
import 'package:news_getx/theme/app_shadows.dart';
class NewsChannelsWidget extends GetView<MainController> {
Widget _buildChannelItem(ChannelResponse item) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 10),
width: 70.w,
height: 97.h,
child: InkWell(
// splashColor文档 splashColor是透明纯黑色
// splashColor: Colors.cyanAccent,
onTap: () {
print(item.title);
},
child: Column(
children: [
// `child` ,
// `Container` ,
// `child` ,
// , ,
// `Container` .
// https://juejin.cn/post/7016649859008725022#heading-9
Container(
width: 64.w,
height: 64.w,
margin: EdgeInsets.symmetric(horizontal: 3.w),
// padding而不是居中对齐
//
padding: EdgeInsets.all(10.w),
decoration: BoxDecoration(
color: AppColors.primaryBackground,
boxShadow: [AppShadows.primaryShadow],
borderRadius: BorderRadius.all(Radius.circular(32.w)),
),
child: Image.asset(
"assets/images/channel-${item.code}.png",
fit: BoxFit.cover,
),
),
Padding(
padding: const EdgeInsets.only(top: 12.0),
child: Text(
item.title,
textAlign: TextAlign.center,
overflow: TextOverflow.clip,
maxLines: 1,
style: TextStyle(
color: AppColors.thirdElementText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 14.sp,
height: 14.sp / 14,
),
),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Obx(
() => controller.state.channels == null
? Container()
: Container(
height: 137.h,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: controller.state.channels!.map<Widget>((item) {
return _buildChannelItem(item);
}).toList(),
),
),
),
);
}
}

View File

@ -0,0 +1,102 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:news_getx/modules/main/main_controller.dart';
import 'package:news_getx/modules/widgets/button.dart';
import 'package:news_getx/modules/widgets/input.dart';
import 'package:news_getx/modules/widgets/toast.dart';
import 'package:news_getx/theme/app_colors.dart';
///
class NewsLetterWidget extends GetView<MainController> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20.w),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(
'Newsletter',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 18.sp,
fontWeight: FontWeight.w300,
color: AppColors.thirdElementText,
),
),
Spacer(),
IconButton(
padding: EdgeInsets.zero,
alignment: Alignment.centerRight,
onPressed: () {},
icon: Icon(
Icons.close,
color: AppColors.thirdElementText,
size: 18.sp,
),
)
],
),
// email
inputEmailEdit(
marginTop: 19,
keyboardType: TextInputType.emailAddress,
hintText: "Email",
isPassword: false,
controller: null,
),
// btn subcrible
Padding(
padding: EdgeInsets.only(top: 15),
child: FlatButton(
onPressed: () {},
width: 335.w,
height: 44.h,
fontWeight: FontWeight.w600,
title: "Subscribe",
),
),
// disc
Container(
margin: EdgeInsets.only(top: 29.h),
width: 261.w,
child: Text.rich(
TextSpan(
children: <TextSpan>[
TextSpan(
text: 'By clicking on Subscribe button you agree to accept',
style: TextStyle(
color: AppColors.thirdElementText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 14.sp,
),
),
TextSpan(
text: ' Privacy Policy',
style: TextStyle(
color: AppColors.secondaryElementText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 14.sp,
),
recognizer: TapGestureRecognizer()
..onTap = () {
toastInfo(msg: 'Privacy Policy');
},
),
],
),
textAlign: TextAlign.center,
),
),
],
),
);
}
}

View File

@ -0,0 +1,171 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:news_getx/data/model/news.dart';
import 'package:news_getx/modules/main/main_controller.dart';
import 'package:news_getx/modules/main/widgets/ad.dart';
import 'package:news_getx/modules/widgets/image.dart';
import 'package:news_getx/theme/app_colors.dart';
import 'package:news_getx/utils/date.dart';
/// Item
class NewsListWidget extends GetView<MainController> {
Widget _buildListItem(NewsItem item) {
return Container(
height: 161.h,
padding: EdgeInsets.all(20.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
//
InkWell(
onTap: () {
//
},
child: SizedBox(
width: 121.w,
height: 121.w,
child: netImageCached(
item.thumbnail ?? "",
width: 121.w,
height: 121.w,
),
),
),
//
SizedBox(
width: 194.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//
Container(
margin: EdgeInsets.all(0),
child: Text(
item.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(
item.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(
item.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(item.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('查看更多...');
},
),
],
),
), ],
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
// ListView.build吗
return Obx(
() => controller.state.newsPageList == null
? Container()
: Column(
children:
controller.state.newsPageList!.items!.map<Widget>((item) {
//
List<Widget> widgets = [
_buildListItem(item),
Divider(height: 1),
];
// 5 广
int index = controller.state.newsPageList!.items!.indexOf(item);
if ((index + 1) % 5 == 0) {
widgets.addAll([
AdWidget(),
Divider(height: 1),
]);
}
return Column(
children: widgets,
);
}).toList(),
),
);
}
}

View File

@ -9,7 +9,7 @@ import 'package:news_getx/utils/date.dart';
class NewsRecommendWidget extends GetView<MainController> {
@override
Widget build(BuildContext context) {
print(controller.state.newsRecommend?.thumbnail);
print('推荐信息:${controller.state.newsRecommend?.thumbnail}');
return Obx(
() => controller.state.newsRecommend == null
? Container()
@ -93,7 +93,9 @@ class NewsRecommendWidget extends GetView<MainController> {
color: AppColors.primaryText,
size: 24,
),
onTap: () {},
onTap: () {
print('查看更多...');
},
),
],
),

View File

@ -1,30 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:news_getx/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}