Browse Source

1、钱包下拉刷新

2、搜索页面的状态栏文字颜色
3、商品详情优惠券到期时间显示问题
4、首页的banner,多眼导航,公告通知,点击实现
5、热榜的取消加载底部的UI
tags/0.0.2+1
PH2 4 years ago
parent
commit
7b2c0eb1af
14 changed files with 326 additions and 116 deletions
  1. +20
    -4
      example/lib/main.dart
  2. +148
    -0
      example/lib/util/localizations_delegate.dart
  3. +2
    -0
      example/pubspec.yaml
  4. +55
    -37
      lib/pages/wallet_page/wallet_page.dart
  5. +3
    -1
      lib/widgets/goods_details/coupon/counpon_widget.dart
  6. +2
    -2
      lib/widgets/home/home_notice/home_notice_widget.dart
  7. +7
    -7
      lib/widgets/home/home_notice/model/home_notice_model.dart
  8. +3
    -3
      lib/widgets/home/home_quick_entry/home_quick_entry.dart
  9. +13
    -12
      lib/widgets/home/home_quick_entry/model/home_quick_entry_model.dart
  10. +1
    -1
      lib/widgets/home/home_slide_banner/home_slide_banner.dart
  11. +49
    -49
      lib/widgets/home/home_slide_banner/model/home_slide_banner_model.dart
  12. +4
    -0
      lib/widgets/hot_ranking/hot_ranking_list/hot_ranking_list.dart
  13. +18
    -0
      lib/widgets/refresh/refresh_footer/refresh_footer.dart
  14. +1
    -0
      lib/widgets/search/appbar/search_appbar_widget.dart

+ 20
- 4
example/lib/main.dart View File

@@ -6,6 +6,10 @@ import 'package:zhiying_base_widget/pages/home_page/home_page.dart';
import 'package:zhiying_base_widget/pages/launch_page/launch_page.dart';
import 'package:zhiying_base_widget/register.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

import 'util/localizations_delegate.dart';

void main() {
FlutterError.onError = (FlutterErrorDetails details) {
@@ -26,8 +30,7 @@ class _MyAppState extends State<MyApp> {
return Center(
child: Text(
"走神了~\n${error.exceptionAsString()}",
style:
Theme.of(context).textTheme.title.copyWith(color: Colors.redAccent),
style: Theme.of(context).textTheme.title.copyWith(color: Colors.redAccent),
),
);
}
@@ -53,11 +56,24 @@ class _MyAppState extends State<MyApp> {
ChangeNotifierProvider.value(value: UserInfoNotifier()),
],
child: MaterialApp(
localizationsDelegates: [
RefreshLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
CommonLocalizationsDelegate(),
],
supportedLocales: [
const Locale('en'),
const Locale('zh'),
],
localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) {
print("change language ${locale.toString()}");
return locale;
},
home: GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus &&
currentFocus.focusedChild != null) {
if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
FocusManager.instance.primaryFocus.unfocus();
}
},


+ 148
- 0
example/lib/util/localizations_delegate.dart View File

@@ -0,0 +1,148 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';

///语言(主要解决cupertino控件不能显示中文的问题)
class CommonLocalizationsDelegate
extends LocalizationsDelegate<CupertinoLocalizations> {
const CommonLocalizationsDelegate();

@override
bool isSupported(Locale locale) =>
<String>['zh', 'CN'].contains(locale.languageCode);

@override
SynchronousFuture<_DefaultCupertinoLocalizations> load(Locale locale) {
return SynchronousFuture<_DefaultCupertinoLocalizations>(
_DefaultCupertinoLocalizations(locale.languageCode));
}

@override
bool shouldReload(CommonLocalizationsDelegate old) => false;
}

class _DefaultCupertinoLocalizations extends CupertinoLocalizations {
_DefaultCupertinoLocalizations(this._languageCode)
: assert(_languageCode != null);
final String _languageCode;

static const List<String> _shortWeekdays = <String>[
'周一',
'周二',
'周三',
'周四',
'周五',
'周六',
'周日',
];

static const List<String> _shortMonths = <String>[
'一月',
'二月',
'三月',
'四月',
'五月',
'六月',
'七月',
'八月',
'九月',
'十月',
'十一月',
'十二月',
];

static const List<String> _months = <String>[
'一月',
'二月',
'三月',
'四月',
'五月',
'六月',
'七月',
'八月',
'九月',
'十月',
'十一月',
'十二月',
];

@override
String get alertDialogLabel => '提醒';

@override
String get anteMeridiemAbbreviation => "上午";

@override
String get postMeridiemAbbreviation => "下午";

@override
String get copyButtonLabel => "复制";

@override
String get cutButtonLabel => "剪切";

@override
String get pasteButtonLabel => "粘贴";

@override
String get selectAllButtonLabel => "全选";

@override
DatePickerDateOrder get datePickerDateOrder => DatePickerDateOrder.ymd;

@override
DatePickerDateTimeOrder get datePickerDateTimeOrder =>
DatePickerDateTimeOrder.date_time_dayPeriod;

@override
String datePickerDayOfMonth(int dayIndex) => dayIndex.toString();

@override
String datePickerHour(int hour) => hour.toString();

@override
String datePickerHourSemanticsLabel(int hour) => hour.toString();

@override
String datePickerMediumDate(DateTime date) {
return '${_shortWeekdays[date.weekday - DateTime.monday]} '
'${_shortMonths[date.month - DateTime.january]} '
'${date.day.toString().padRight(2)}';
}

@override
String datePickerMinute(int minute) => minute.toString().padLeft(2, '0');

@override
String datePickerMinuteSemanticsLabel(int minute) {
if (minute == 1) return '1 分钟';
return minute.toString() + ' 分钟';
}

@override
String datePickerMonth(int monthIndex) => _months[monthIndex - 1];

@override
String datePickerYear(int yearIndex) => yearIndex.toString();

@override
String timerPickerHour(int hour) => hour.toString();

@override
String timerPickerHourLabel(int hour) => '时';

@override
String timerPickerMinute(int minute) => minute.toString();

@override
String timerPickerMinuteLabel(int minute) => '分';

@override
String timerPickerSecond(int second) => second.toString();

@override
String timerPickerSecondLabel(int second) => '秒';

@override
// TODO: implement todayLabel
String get todayLabel => null;
}

+ 2
- 0
example/pubspec.yaml View File

@@ -12,6 +12,8 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
flutter_localizations:
sdk: flutter

dev_dependencies:
flutter_test:


+ 55
- 37
lib/pages/wallet_page/wallet_page.dart View File

@@ -5,12 +5,14 @@ import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart';
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart';
import 'package:zhiying_base_widget/utils/contants.dart';
import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_header.dart';
import 'package:zhiying_base_widget/widgets/wallet/wallet_appbar/wallet_appbar_sk.dart';
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data_sk.dart';
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_sk.dart';
import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income_sk.dart';
import 'package:zhiying_comm/util/base_bloc.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
import 'dart:ui';

import 'wallet_page_bloc.dart';

@@ -53,14 +55,15 @@ class _WalletPageContainer extends StatefulWidget {
}

class _WalletPageContainerState extends State<_WalletPageContainer> {
final ScrollController _controller = ScrollController();
final RefreshController _refreshController =
RefreshController(initialRefresh: false);
ScrollController _controller;
RefreshController _refreshController;

WalletPageBloc _pageBloc;

@override
void initState() {
_controller = ScrollController();
_refreshController = RefreshController(initialRefresh: false);
_pageBloc = BlocProvider.of<WalletPageBloc>(context);
if (widget.data.containsKey(Constants.SkipIdentifierName)) {
_pageBloc.loadData(widget.data[Constants.SkipIdentifierName]);
@@ -68,48 +71,66 @@ class _WalletPageContainerState extends State<_WalletPageContainer> {
super.initState();
}

@override
void dispose() {
_refreshController?.dispose();
super.dispose();
}

void _onLoading() async {
// await Future.delayed(Duration(milliseconds: 1000));
// if (mounted) setState(() {});
// _refreshController.loadComplete();
}

void _onRefresh() async {
if (widget.data.containsKey(Constants.SkipIdentifierName)) {
_pageBloc.loadData(widget.data[Constants.SkipIdentifierName]);
}
}

@override
Widget build(BuildContext context) {
ScreenUtil.init(context, width: 750, height: 1334);
return SmartRefresher(
controller: _refreshController,
enablePullDown: true,
enablePullUp: true,
header: WaterDropHeader(),
onLoading: _onLoading,
child: Container(
width: double.infinity,
child: Stack(
fit: StackFit.passthrough,
children: <Widget>[
StreamBuilder(
stream: _pageBloc.outData,
builder: (context, asyncSnapshot) {
var model = asyncSnapshot.data;
return Stack(
children: <Widget>[
Container(height: 362.h, color: _pageBloc.backgroundColor),
CustomScrollView(
double top = MediaQueryData.fromWindow(window).padding.top;

return Container(
width: double.infinity,
child: Stack(
fit: StackFit.passthrough,
children: <Widget>[
StreamBuilder(
stream: _pageBloc.outData,
builder: (context, asyncSnapshot) {
var model = asyncSnapshot.data;
_refreshController.refreshCompleted();
return Stack(
children: <Widget>[
Container(height: 362.h, color: _pageBloc.backgroundColor),
SmartRefresher(
controller: _refreshController,
enablePullDown: true,
enablePullUp: false,
header: RefreshHeader(
offsetY: top,
),
onLoading: _onLoading,
onRefresh: _onRefresh,
child: CustomScrollView(
controller: _controller,
slivers: _createContent(context, model),
)
],
);
},
)
],
),
),
)
],
);
},
)
],
),
);
}

List<Widget> _createContent(
BuildContext context, List<Map<String, dynamic>> model) {
List<Widget> _createContent(BuildContext context, List<Map<String, dynamic>> model) {
List<Widget> list = List();
if (model == null) {
///骨架图
@@ -127,10 +148,8 @@ class _WalletPageContainerState extends State<_WalletPageContainer> {
));
} else {
for (var item in model) {
WidgetModel widgetModel =
WidgetModel.fromJson(Map<String, dynamic>.from(item));
list.addAll(WidgetFactory.create(widgetModel.modName,
isSliver: true, model: item));
WidgetModel widgetModel = WidgetModel.fromJson(Map<String, dynamic>.from(item));
list.addAll(WidgetFactory.create(widgetModel.modName, isSliver: true, model: item));
}
}
return list;
@@ -152,8 +171,7 @@ class _SilverAppBarDelegate extends SliverPersistentHeaderDelegate {
double get maxExtent => MediaQuery.of(context).padding.top + 44;

@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return child;
}



+ 3
- 1
lib/widgets/goods_details/coupon/counpon_widget.dart View File

@@ -126,7 +126,9 @@ class _CounponWidgetContainerState extends State<CounponWidgetContainer> {
Text(model?.coupon_title ?? '优惠券', style: TextStyle(fontSize: 17, color: HexColor.fromHex(model?.coupon_title_color ?? '#FFFFFF'))),

/// 到期时间
Text(model?.coupon_endtime ?? '有效期至2020-10-01', style: TextStyle(fontSize: 10, color: HexColor.fromHex(model?.coupon_time_color ?? '#FFFFFF')))
Visibility(
visible: !EmptyUtil.isEmpty(model?.coupon_endtime),
child: Text(model?.coupon_endtime ?? '有效期至2020-10-01', style: TextStyle(fontSize: 10, color: HexColor.fromHex(model?.coupon_time_color ?? '#FFFFFF'))))
],
);
}


+ 2
- 2
lib/widgets/home/home_notice/home_notice_widget.dart View File

@@ -45,8 +45,8 @@ class _HomeNoticeWidgetContianerState extends State<HomeNoticeWidgetContianer> {

/// 子item跳转
void _itemJump(HomeNoticeNoticesModel model){
print('${model?.skip_identifier}');
// RouterUtil.route(model, model.toJson(), context);
print('${model?.notice_text}');
RouterUtil.route(model, model.toJson(), context);
}

@override


+ 7
- 7
lib/widgets/home/home_notice/model/home_notice_model.dart View File

@@ -1,3 +1,4 @@
import 'package:zhiying_base_widget/dialog/global_dialog/intellect_search_goods_dialog/model/no_goods_dialog_style_model.dart';
import 'package:zhiying_comm/zhiying_comm.dart';

class HomeNoticeModel {
@@ -38,21 +39,20 @@ class HomeNoticeModel {
}
}

class HomeNoticeNoticesModel{
class HomeNoticeNoticesModel extends SkipModel{
String notice_text;
String skip_identifier;

HomeNoticeNoticesModel({this.notice_text, this.skip_identifier});

factory HomeNoticeNoticesModel.fromJson(Map<String, dynamic> json) {
return HomeNoticeNoticesModel(
notice_text: json['notice_text']?.toString(),
skip_identifier: json['skip_identifier']?.toString(),
);
HomeNoticeNoticesModel.fromJson(Map<String, dynamic> json) {
super.fromJson(json);
notice_text = json['notice_text']?.toString();
skip_identifier = json['skip_identifier']?.toString();
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
Map<String, dynamic> data = super.toJson();
data['img'] = this.notice_text;
data['skip_identifier'] = this.skip_identifier;
return data;


+ 3
- 3
lib/widgets/home/home_quick_entry/home_quick_entry.dart View File

@@ -34,7 +34,7 @@ class _HomeQuickEntryContianerState extends State<HomeQuickEntryContianer> {
/// Icon点击事件
void _itemIconClick(TypeNormal model){
print("item type = ${model.skip_identifier}");
// RouterUtil.route(model, model.toJson(), context);
RouterUtil.route(model, model.toJson(), context);
}

@override
@@ -104,7 +104,7 @@ class _HomeQuickEntryContianerState extends State<HomeQuickEntryContianer> {
return Container(
color: Colors.white,
child: Container(
margin: const EdgeInsets.only(top: 15, bottom: 15 ),
margin: EdgeInsets.only(top: 15, bottom: totalPage >1 ? 15 : 0 ),
height: totalHeight, // 总体高度
width: double.infinity,
color: Colors.white,
@@ -129,7 +129,7 @@ class _HomeQuickEntryContianerState extends State<HomeQuickEntryContianer> {
),
);
},
pagination: _getSwiperPaginationContorl(model, totalPage),
pagination: totalPage <= 1 ? null : _getSwiperPaginationContorl(model, totalPage),
),
),
);


+ 13
- 12
lib/widgets/home/home_quick_entry/model/home_quick_entry_model.dart View File

@@ -1,3 +1,5 @@
import 'package:zhiying_comm/zhiying_comm.dart';

class HomeQuickEntryModel {
String colum_size;
String data_type;
@@ -63,7 +65,7 @@ class HomeQuickEntryModel {
}
}

class TypeNormal {
class TypeNormal extends SkipModel {
String img;
String required_login;
String required_taobao_auth;
@@ -74,20 +76,19 @@ class TypeNormal {

TypeNormal({this.img, this.required_login, this.required_taobao_auth, this.skip_identifier, this.title_1, this.title_2, this.type});

factory TypeNormal.fromJson(Map<String, dynamic> json) {
return TypeNormal(
img: json['img']?.toString(),
required_login: json['required_login']?.toString(),
required_taobao_auth: json['required_taobao_auth']?.toString(),
skip_identifier: json['skip_identifier']?.toString(),
title_1: json['title_1']?.toString(),
title_2: json['title_2']?.toString(),
type: json['type']?.toString(),
);
TypeNormal.fromJson(Map<String, dynamic> json) {
super.fromJson(json);
img = json['img']?.toString();
required_login = json['required_login']?.toString();
required_taobao_auth = json['required_taobao_auth']?.toString();
skip_identifier = json['skip_identifier']?.toString();
title_1 = json['title_1']?.toString();
title_2 = json['title_2']?.toString();
type = json['type']?.toString();
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
final Map<String, dynamic> data = super.toJson();
data['img'] = this.img;
data['required_login'] = this.required_login;
data['required_taobao_auth'] = this.required_taobao_auth;


+ 1
- 1
lib/widgets/home/home_slide_banner/home_slide_banner.dart View File

@@ -48,7 +48,7 @@ class _HomeSlideBannerContainerState extends State<HomeSlideBannerContainer> {
/// 子元素点击事件
void _itemOnClick(IndexCarousel model) {
print('点击了 $model');
// RouterUtil.route(model, model.toJson(), context);
RouterUtil.route(model, model.toJson(), context);
// Navigator.push(context, CupertinoPageRoute(
// builder: (_) => PageFactory.create('goods_details', null)
// ));


+ 49
- 49
lib/widgets/home/home_slide_banner/model/home_slide_banner_model.dart View File

@@ -1,58 +1,58 @@
import 'package:zhiying_comm/zhiying_comm.dart';

class HomeSlideBannerModel {
List<IndexCarousel> index_carousel_list;
String pagination;
String pagination_open;
List<String> pagination_options;
String pagination_select_color;
String pagination_unselect_color;

HomeSlideBannerModel({this.index_carousel_list, this.pagination, this.pagination_open, this.pagination_options, this.pagination_select_color, this.pagination_unselect_color});

factory HomeSlideBannerModel.fromJson(Map<String, dynamic> json) {
return HomeSlideBannerModel(
index_carousel_list: json['index_carousel_list'] != null ? (json['index_carousel_list'] as List).map((i) => IndexCarousel.fromJson(i)).toList() : null,
pagination: json['pagination'],
pagination_open: json['pagination_open'],
pagination_options: json['pagination_options'] != null ? new List<String>.from(json['pagination_options']) : null,
pagination_select_color: json['pagination_select_color'],
pagination_unselect_color: json['pagination_unselect_color'],
);
List<IndexCarousel> index_carousel_list;
String pagination;
String pagination_open;
List<String> pagination_options;
String pagination_select_color;
String pagination_unselect_color;

HomeSlideBannerModel({this.index_carousel_list, this.pagination, this.pagination_open, this.pagination_options, this.pagination_select_color, this.pagination_unselect_color});

factory HomeSlideBannerModel.fromJson(Map<String, dynamic> json) {
return HomeSlideBannerModel(
index_carousel_list: json['index_carousel_list'] != null ? (json['index_carousel_list'] as List).map((i) => IndexCarousel.fromJson(i)).toList() : null,
pagination: json['pagination'],
pagination_open: json['pagination_open'],
pagination_options: json['pagination_options'] != null ? new List<String>.from(json['pagination_options']) : null,
pagination_select_color: json['pagination_select_color'],
pagination_unselect_color: json['pagination_unselect_color'],
);
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['pagination'] = this.pagination;
data['pagination_open'] = this.pagination_open;
data['pagination_select_color'] = this.pagination_select_color;
data['pagination_unselect_color'] = this.pagination_unselect_color;
if (this.index_carousel_list != null) {
data['index_carousel_list'] = this.index_carousel_list.map((v) => v.toJson()).toList();
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['pagination'] = this.pagination;
data['pagination_open'] = this.pagination_open;
data['pagination_select_color'] = this.pagination_select_color;
data['pagination_unselect_color'] = this.pagination_unselect_color;
if (this.index_carousel_list != null) {
data['index_carousel_list'] = this.index_carousel_list.map((v) => v.toJson()).toList();
}
if (this.pagination_options != null) {
data['pagination_options'] = this.pagination_options;
}
return data;
if (this.pagination_options != null) {
data['pagination_options'] = this.pagination_options;
}
return data;
}
}

class IndexCarousel {
String img;
String skip_identifier;
class IndexCarousel extends SkipModel {
String img;
String skip_identifier;

IndexCarousel({this.img, this.skip_identifier});
IndexCarousel({this.img, this.skip_identifier});

factory IndexCarousel.fromJson(Map<String, dynamic> json) {
return IndexCarousel(
img: json['img'],
skip_identifier: json['skip_identifier'],
);
}
IndexCarousel.fromJson(Map<String, dynamic> json) {
super.toJson();
img = json['img'];
skip_identifier = json['skip_identifier'];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['img'] = this.img;
data['skip_identifier'] = this.skip_identifier;
return data;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = super.toJson();
data['img'] = this.img;
data['skip_identifier'] = this.skip_identifier;
return data;
}
}

+ 4
- 0
lib/widgets/hot_ranking/hot_ranking_list/hot_ranking_list.dart View File

@@ -6,6 +6,8 @@ import 'package:zhiying_base_widget/pages/hot_ranking_page/hot_ranking_page_bloc
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_goods/hot_ranking_goods.dart';
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_list/model/hot_ranking_list_data_model.dart';
import 'package:zhiying_base_widget/widgets/hot_ranking/hot_ranking_list/model/hot_ranking_list_model.dart';
import 'package:zhiying_base_widget/widgets/refresh/refresh_footer/refresh_footer.dart';
import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_header.dart';
import 'package:zhiying_comm/util/base_bloc.dart';

import 'hot_ranking_bloc.dart';
@@ -82,6 +84,8 @@ class _HotRankingState extends State<HotRankingList>
enablePullUp: true,
onLoading: _onLoading,
onRefresh: _onRefresh,
header: RefreshHeader(),
footer: RefreshFooter(),
child: CustomScrollView(
controller: _scrollcontroller,
slivers: <Widget>[


+ 18
- 0
lib/widgets/refresh/refresh_footer/refresh_footer.dart View File

@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

class RefreshFooter extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomFooter(
height: 1,
builder: (BuildContext context, LoadStatus model){

return Container(
height: 1,
width: double.infinity,
);
},
);
}
}

+ 1
- 0
lib/widgets/search/appbar/search_appbar_widget.dart View File

@@ -37,6 +37,7 @@ class SearchAppbarWidget extends StatelessWidget {
return AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
brightness: Brightness.light,
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,


Loading…
Cancel
Save