diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 2ff2799..aea820a 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -770,7 +770,7 @@
"languageVersion": "2.1"
}
],
- "generated": "2020-09-19T06:19:07.938950Z",
+ "generated": "2020-09-21T02:27:30.928433Z",
"generator": "pub",
"generatorVersion": "2.7.2"
}
diff --git a/.idea/runConfigurations/example_lib_main_dart.xml b/.idea/runConfigurations/example_lib_main_dart.xml
deleted file mode 100644
index 5fd9159..0000000
--- a/.idea/runConfigurations/example_lib_main_dart.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/saveactions_settings.xml b/.idea/saveactions_settings.xml
deleted file mode 100644
index 6025467..0000000
--- a/.idea/saveactions_settings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/android/gradlew b/android/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/android/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/android/gradlew.bat b/android/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/android/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/lib/pages/goods_details_page/bloc/goods_details_page_bloc.dart b/lib/pages/goods_details_page/bloc/goods_details_page_bloc.dart
new file mode 100644
index 0000000..3960ec1
--- /dev/null
+++ b/lib/pages/goods_details_page/bloc/goods_details_page_bloc.dart
@@ -0,0 +1,39 @@
+import 'dart:async';
+
+import 'package:bloc/bloc.dart';
+import 'package:equatable/equatable.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:zhiying_base_widget/pages/goods_details_page/bloc/goods_details_page_repository.dart';
+import 'package:zhiying_comm/util/empty_util.dart';
+
+part 'goods_details_page_event.dart';
+
+part 'goods_details_page_state.dart';
+
+class GoodsDetailsPageBloc extends Bloc {
+ // GoodsDetailsPageBloc() : super(GoodsDetailsPageInitial());
+
+ @override
+ GoodsDetailsPageState get initialState => GoodsDetailsPageInitial();
+
+ GoodsDetailsPageRepository repository;
+
+ GoodsDetailsPageBloc({@required this.repository});
+
+ @override
+ Stream mapEventToState(
+ GoodsDetailsPageEvent event,
+ ) async* {
+ if (event is GoodsDetailsPageInitEvent) {
+ yield* _mapInitEventToState(event);
+ }
+ }
+
+ Stream _mapInitEventToState(GoodsDetailsPageInitEvent event) async* {
+ var result = await repository.fetchInitData(event.model);
+ if (!EmptyUtil.isEmpty(result))
+ yield GoodsDetailsPageLoadedState(model: result);
+ else
+ yield GoodsDetailsPageErrorState();
+ }
+}
diff --git a/lib/pages/goods_details_page/bloc/goods_details_page_event.dart b/lib/pages/goods_details_page/bloc/goods_details_page_event.dart
new file mode 100644
index 0000000..4af1ac7
--- /dev/null
+++ b/lib/pages/goods_details_page/bloc/goods_details_page_event.dart
@@ -0,0 +1,15 @@
+part of 'goods_details_page_bloc.dart';
+
+abstract class GoodsDetailsPageEvent extends Equatable {
+ const GoodsDetailsPageEvent();
+}
+
+/// 初始化
+class GoodsDetailsPageInitEvent extends GoodsDetailsPageEvent {
+ final Map model;
+
+ const GoodsDetailsPageInitEvent({this.model});
+
+ @override
+ List get props => [this.model];
+}
diff --git a/lib/pages/goods_details_page/bloc/goods_details_page_repository.dart b/lib/pages/goods_details_page/bloc/goods_details_page_repository.dart
new file mode 100644
index 0000000..77ed80e
--- /dev/null
+++ b/lib/pages/goods_details_page/bloc/goods_details_page_repository.dart
@@ -0,0 +1,40 @@
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+class GoodsDetailsPageRepository {
+ List> _pageData = [];
+
+ /// 初始化
+ Future>> fetchInitData(Map model) async {
+ int id = 13;
+ var result = await NetUtil.post('/api/v1/mod',
+ method: NetMethod.POST,
+ params: Map.from({
+ 'ids': [id]
+ }));
+ try {
+ if(NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
+ return _loadData(id, result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]);
+ }
+ } catch (e) {
+ Logger.log(e);
+ }
+ return null;
+ }
+
+ /// 处理数据
+ List> _loadData(int id, dynamic data) {
+ String key = id.toString();
+ Map json = Map.from(data);
+ if (json.containsKey(key)) {
+ List list = json[key];
+ _pageData = list.map((item) {
+ return Map.from(item);
+ }).toList();
+ return _pageData;
+ }
+ return null;
+ }
+
+ /// 获取缓存数据?
+
+}
diff --git a/lib/pages/goods_details_page/bloc/goods_details_page_state.dart b/lib/pages/goods_details_page/bloc/goods_details_page_state.dart
new file mode 100644
index 0000000..e15fc97
--- /dev/null
+++ b/lib/pages/goods_details_page/bloc/goods_details_page_state.dart
@@ -0,0 +1,24 @@
+part of 'goods_details_page_bloc.dart';
+
+abstract class GoodsDetailsPageState extends Equatable {
+ const GoodsDetailsPageState();
+
+ @override
+ List get props => [];
+}
+
+/// 初始化状态
+class GoodsDetailsPageInitial extends GoodsDetailsPageState {}
+
+/// 数据加载完毕状态
+class GoodsDetailsPageLoadedState extends GoodsDetailsPageState {
+ final List> model;
+
+ const GoodsDetailsPageLoadedState({this.model});
+
+ @override
+ List get props => [this.model];
+}
+
+/// 数据加载出错
+class GoodsDetailsPageErrorState extends GoodsDetailsPageState {}
diff --git a/lib/pages/goods_details_page/goods_details_page.dart b/lib/pages/goods_details_page/goods_details_page.dart
new file mode 100644
index 0000000..a033f9f
--- /dev/null
+++ b/lib/pages/goods_details_page/goods_details_page.dart
@@ -0,0 +1,193 @@
+import 'package:flutter/material.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+import 'package:zhiying_base_widget/pages/goods_details_page/bloc/goods_details_page_bloc.dart';
+import 'package:zhiying_base_widget/pages/goods_details_page/bloc/goods_details_page_repository.dart';
+import 'package:zhiying_base_widget/pages/goods_details_page/notifier/goods_details_page_notifier.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/footer/goods_details_footer_widget.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+import 'package:provider/provider.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'dart:ui';
+
+class GoodsDetailsPage extends StatefulWidget {
+ final Map data;
+
+ GoodsDetailsPage(this.data, {Key key}) : super(key: key);
+
+ @override
+ _GoodsDetailsPageState createState() => _GoodsDetailsPageState();
+}
+
+class _GoodsDetailsPageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: HexColor.fromHex('#FFF1F1F1'),
+ body: MultiProvider(
+ providers: [
+ /// 滑动通知
+ ChangeNotifierProvider.value(value: GoodsDetailsPageNotifier()),
+ ],
+ child: BlocProvider(
+ create: (_) => GoodsDetailsPageBloc(repository: GoodsDetailsPageRepository())..add(GoodsDetailsPageInitEvent(model: widget?.data)),
+ child: GoodsDetailsContainer(widget?.data),
+ ),
+ ),
+ );
+ }
+}
+
+class GoodsDetailsContainer extends StatefulWidget {
+ final Map data;
+
+ const GoodsDetailsContainer(this.data);
+
+ @override
+ _GoodsDetailsContainerState createState() => _GoodsDetailsContainerState();
+}
+
+class _GoodsDetailsContainerState extends State {
+ bool _isEnded = false;
+ ScrollController _controller = ScrollController();
+ RefreshController _refreshController = RefreshController(initialRefresh: false);
+
+ void _onLoading() async {
+ // await Future.delayed(Duration(milliseconds: 1000));
+ // if (mounted) setState(() {});
+ // _refreshController.loadComplete();
+ }
+
+ /// 返回上一页
+ void _openPop() {
+ print('返回上一页');
+
+ Navigator.maybePop(context);
+ }
+
+ @override
+ void dispose() {
+ _controller.dispose();
+ super.dispose();
+ }
+
+ @override
+ void initState() {
+ _controller.addListener(() {
+ // print('${_controller.offset} ${_controller.position.maxScrollExtent}');
+ if (_controller.offset >= _controller.position.maxScrollExtent && !_isEnded) {
+ // 滑动到底部
+ _isEnded = true;
+ Provider.of(context, listen: false).loadMore();
+ } else if (_controller.offset < _controller.position.maxScrollExtent && _isEnded) {
+ _isEnded = false;
+ Provider.of(context, listen: false).reset();
+ }
+ });
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return MediaQuery.removePadding(
+ removeTop: true,
+ context: context,
+ child: Container(
+ width: double.infinity,
+ child: BlocConsumer(
+ listener: (BuildContext context, GoodsDetailsPageState state) {
+ if (state is GoodsDetailsPageErrorState) {
+ print('数据加载出错');
+ }
+ },
+ buildWhen: (previous, current) {
+ /// 数据加载出错不进行build
+ if (current is GoodsDetailsPageErrorState) {
+ return false;
+ }
+ return true;
+ },
+ builder: (context, state) {
+ print('currente state = $state');
+ if (state is GoodsDetailsPageLoadedState) {
+ return _getMainWidget(state?.model);
+ }
+ return _getMainWidget(null);
+ },
+ ),
+ ),
+ );
+ }
+
+ /// 主视图
+ Widget _getMainWidget(List> datas) {
+ return Stack(
+ fit: StackFit.passthrough,
+ children: [
+ /// 主体布局
+ SmartRefresher(
+ enablePullDown: true,
+ enablePullUp: false,
+ header: WaterDropHeader(),
+ controller: _refreshController,
+ onLoading: _onLoading,
+ child: CustomScrollView(
+ controller: _controller,
+ slivers: _createContent(context, datas ?? []),
+ ),
+ ),
+ /// appBar
+ Align(
+ alignment: Alignment.topCenter,
+ child: _getAppBarWidget()),
+ /// 底部
+ Align(alignment: Alignment.bottomCenter, child: GoodsDetailsFooterWidget(null))
+ ],
+ );
+ }
+
+ List _createContent(BuildContext context, List> datas) {
+ List list = List();
+ for (int i = 0; i < datas.length; i++) {
+ WidgetModel item = WidgetModel.fromJson(Map.from(datas[i]));
+
+ print('item.modName ${item.modName}');
+ list.addAll(WidgetFactory.create(
+ item.modName,
+ isSliver: true,
+ model: datas[i],
+ ));
+ }
+ if (list.length <= 0) {
+ list.add(SliverToBoxAdapter(
+ child: Container(
+ height: 200,
+ child: Center(
+ child: Text('暂时无数据哦~'),
+ ),
+ ),
+ ));
+ }
+ return list;
+ }
+
+ /// appBar
+ Widget _getAppBarWidget() {
+ return Container(
+ width: double.infinity,
+ height: 40,
+ margin: EdgeInsets.only(top: MediaQueryData.fromWindow(window).padding.top),
+ child: AppBar(
+ backgroundColor: Colors.transparent,
+ elevation: 0,
+ leading: IconButton(
+ icon: Icon(
+ Icons.arrow_back_ios,
+ size: 22,
+ color: HexColor.fromHex('#FFFFFF'),
+ ),
+ onPressed: () => _openPop(),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/pages/goods_details_page/notifier/goods_details_page_notifier.dart b/lib/pages/goods_details_page/notifier/goods_details_page_notifier.dart
new file mode 100644
index 0000000..7e041d7
--- /dev/null
+++ b/lib/pages/goods_details_page/notifier/goods_details_page_notifier.dart
@@ -0,0 +1,16 @@
+import 'package:flutter/material.dart';
+
+class GoodsDetailsPageNotifier with ChangeNotifier {
+ bool scrollEnd = false;
+
+ // 加载更多数据
+ void loadMore() {
+ scrollEnd = true;
+ notifyListeners();
+ }
+
+ void reset() {
+ scrollEnd = false;
+ notifyListeners();
+ }
+}
diff --git a/lib/register.dart b/lib/register.dart
index 15bfe43..55a1501 100644
--- a/lib/register.dart
+++ b/lib/register.dart
@@ -1,3 +1,5 @@
+import 'package:flutter/cupertino.dart';
+import 'package:zhiying_base_widget/pages/goods_details_page/goods_details_page.dart';
import 'package:zhiying_base_widget/pages/home_page/home_page.dart';
import 'package:zhiying_base_widget/pages/main_page/main_page.dart';
import 'package:zhiying_base_widget/pages/mine_detail_page/mine_detail_page.dart';
@@ -5,10 +7,19 @@ import 'package:zhiying_base_widget/pages/orders_page/orders_page.dart';
import 'package:zhiying_base_widget/pages/setting_page/setting_page.dart';
import 'package:zhiying_base_widget/pages/wallet_page/wallet_page.dart';
import 'package:zhiying_base_widget/widgets/home/home_auth/home_auth_creater.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/footer/goods_details_footer_widget.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/price/goods_details_price_widget.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/store/store_widget.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart';
import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_creater.dart';
import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_widget.dart';
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart';
+import 'package:zhiying_base_widget/widgets/home/home_notice/home_notice_widget.dart';
+import 'package:zhiying_base_widget/widgets/home/home_notice/model/home_notice_model.dart';
import 'package:zhiying_base_widget/widgets/home/home_slide_banner/home_slide_banner_creater.dart';
+import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_creater.dart';
+import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_widget.dart';
import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data.dart';
import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header.dart';
import 'package:zhiying_base_widget/widgets/mine/mine_nav/mine_nav_bg.dart';
@@ -16,10 +27,14 @@ import 'package:zhiying_base_widget/widgets/mine/mine_nav/mine_nav_creater.dart'
import 'package:zhiying_base_widget/widgets/mine/mine_quick_entry/mine_quick_entry.dart';
import 'package:zhiying_base_widget/widgets/others/normal_nav/normal_nav_creater.dart';
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data.dart';
+import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail.dart';
import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income.dart';
import 'package:zhiying_comm/util/defalut_widget_creater.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
+import 'widgets/goods_details/coupon/counpon_widget.dart';
+import 'widgets/goods_details/evaluate/goods_details_evaluate_widget.dart';
+import 'widgets/goods_details/title/goods_details_title_widget.dart';
import 'widgets/home/home_quick_entry/home_quick_entry.dart';
class BaseWidgetRegister {
@@ -35,15 +50,17 @@ class BaseWidgetRegister {
PageFactory.regist('index', (model) => MainPage(model));
PageFactory.regist('profile', (model) => MainPage(model));
PageFactory.regist('category', (model) => WalletPage());
+ PageFactory.regist('goods_details', (model) => GoodsDetailsPage(model));
// PageFactory.regist('login', (model) => LoginPage(model));
// PageFactory.regist('login_quick', (model) => LoginQuickPage(model));
// PageFactory.regist('login_account', (model) => LoginAccountPage(model));
// PageFactory.regist('login_invite', (model) => LoginInvitePage());
- PageFactory.regist(
- 'pub.flutter.profile_settings', (model) => MineDetailPage());
+ PageFactory.regist('pub.flutter.profile_settings', (model) => MineDetailPage());
PageFactory.regist('pub.flutter.settings', (model) => SettingPage(model));
+
PageFactory.regist('pub.flutter.my_orders', (model) => OrdersPage(model));
+
}
// 注册控件
@@ -53,36 +70,56 @@ class BaseWidgetRegister {
WidgetFactory.regist('normal_nav', NormalNavCreater());
// ==================== 首页
-// WidgetFactory.regist('index_title', NormalNavCreater());
-// WidgetFactory.regist(
-// 'index_search', DefaultWidgetCreater((model) => MineData()));
-
-// /// 可滚动banner
+ // WidgetFactory.regist('index_title', NormalNavCreater());
+ /// 首页搜索栏
+ // WidgetFactory.regist('index_search', HomeSreachCreater());
+ // WidgetFactory.regist('index_search', DefaultWidgetCreater((model) => HomeSreachWidget(model)));
+ /// 可滚动banner
WidgetFactory.regist('index_carousel', HomeSlideBannerCreater());
WidgetFactory.regist('index_recommend_list', GoodsListCreater());
-// /// 首页快速入口
- WidgetFactory.regist(
- 'multi_nav', DefaultWidgetCreater((model) => HomeQuickEntry(model)));
-//
-// /// 不可以滚动banner
+
+ /// 首页快速入口
+ WidgetFactory.regist('multi_nav', DefaultWidgetCreater((model) => HomeQuickEntry(model)));
+
+ /// 滚动公告
+ WidgetFactory.regist('index_placard', DefaultWidgetCreater((model) => HomeNoticeWidget(model)));
+
+ /// 不可以滚动banner
WidgetFactory.regist('index_banner_one', HomeBannerCreater());
WidgetFactory.regist('index_banner_two', HomeBannerCreater());
WidgetFactory.regist('index_taobao_auth_tip', HomeAuthCreater());
+ /// ==================== 商品详情 ==================== ///
+ // 商品详情轮播图
+ WidgetFactory.regist('product_detail_carousel', DefaultWidgetCreater((model) => GoodsDetailsSlideBannerWidget(model)));
+ // 商品详情下载APP提示
+ WidgetFactory.regist('product_detail_download_tips', DefaultWidgetCreater((model) => UpgradeTipWidget(model)));
+ // 商品详情价格显示
+ WidgetFactory.regist('product_detail_price', DefaultWidgetCreater((model) => GoodsDetailsPriceWidget(model)));
+ // 商品详情标题
+ WidgetFactory.regist('product_detail_title', DefaultWidgetCreater((model) => GoodsDetailsTitleWidget(model)));
+ // 商品详情优惠劵
+ WidgetFactory.regist('product_detail_coupon', DefaultWidgetCreater((model) => CounponWidget(model)));
+ // 商品详情店铺
+ WidgetFactory.regist('product_detail_shop', DefaultWidgetCreater((model) => StoreWidget(model)));
+ // 商品详情宝贝评价
+ WidgetFactory.regist('product_detail_comment', DefaultWidgetCreater((model) => GoodsDetailsEvaluateWidget(model)));
+ // 商品详情图片
+ // WidgetFactory.regist('product_detail_img_list', MineNavCreater());
+ // 商品详情底部推荐列表
+ // WidgetFactory.regist('product_detail_bottom_rec', DefaultWidgetCreater((model) => GoodsDetailsEvaluateWidget(model)));
+ // 商品详情底部
+ WidgetFactory.regist('product_detail_bottom', DefaultWidgetCreater((model) => GoodsDetailsFooterWidget(model)));
+
+
// ==================== 个人中心
WidgetFactory.regist('profile_appbar', MineNavCreater());
- WidgetFactory.regist('profile_background',
- DefaultWidgetCreater((model) => MineNavBg(model)));
- WidgetFactory.regist(
- 'profile_header', DefaultWidgetCreater((model) => MineHeader(model)));
- WidgetFactory.regist(
- 'profile_earning', DefaultWidgetCreater((model) => MineData(model)));
- WidgetFactory.regist('profile_functions',
- DefaultWidgetCreater((model) => MineQuickEntry(model)));
- WidgetFactory.regist('profile_my_functions',
- DefaultWidgetCreater((model) => MineQuickEntry(model)));
- WidgetFactory.regist('profile_carousel',
- DefaultWidgetCreater((model) => HomeBannerWidget(model)));
+ WidgetFactory.regist('profile_background', DefaultWidgetCreater((model) => MineNavBg(model)));
+ WidgetFactory.regist('profile_header', DefaultWidgetCreater((model) => MineHeader(model)));
+ WidgetFactory.regist('profile_earning', DefaultWidgetCreater((model) => MineData(model)));
+ WidgetFactory.regist('profile_functions', DefaultWidgetCreater((model) => MineQuickEntry(model)));
+ WidgetFactory.regist('profile_my_functions', DefaultWidgetCreater((model) => MineQuickEntry(model)));
+ WidgetFactory.regist('profile_carousel', DefaultWidgetCreater((model) => HomeBannerWidget(model)));
// ==================== 钱包
WidgetFactory.regist(
@@ -90,8 +127,9 @@ class BaseWidgetRegister {
// WidgetFactory.regist(
// 'wallet_detail', DefaultWidgetCreater((model) => WalletDetail()));
WidgetFactory.regist('wallet_detail', HomeAuthCreater());
+ WidgetFactory.regist('wallet_data', DefaultWidgetCreater((model) => WalletData()));
+ WidgetFactory.regist('wallet_detail', DefaultWidgetCreater((model) => WalletDetail()));
- WidgetFactory.regist(
- 'wallet_income', DefaultWidgetCreater((model) => WalletIncome()));
+ WidgetFactory.regist('wallet_income', DefaultWidgetCreater((model) => WalletIncome()));
}
}
diff --git a/lib/widgets/goods_details/counpon_description/counpon_description_widget.dart b/lib/widgets/goods_details/counpon_description/counpon_description_widget.dart
new file mode 100644
index 0000000..cbafae9
--- /dev/null
+++ b/lib/widgets/goods_details/counpon_description/counpon_description_widget.dart
@@ -0,0 +1,61 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+///
+/// 优惠券说明
+///
+class CounponDescriptionWidget extends StatelessWidget {
+ final Map model;
+
+ const CounponDescriptionWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: const EdgeInsets.symmetric(horizontal: 12.5),
+ width: double.infinity,
+ child:_getMainWidget(),
+ );
+ }
+
+ /// 主widget
+ Widget _getMainWidget() {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+
+ /// 领券立减
+ Padding(padding: const EdgeInsets.only(right: 5), child: _getButtom1Widget()),
+
+
+ /// 收货后返现
+ Padding(padding: const EdgeInsets.only(right: 5), child: _getButtom2Widget()),
+
+
+ ],
+ );
+ }
+
+ /// 领券立减
+ Widget _getButtom1Widget() {
+ return Container(
+ decoration: BoxDecoration(
+ color: HexColor.fromHex('#FFE0E0'),
+ borderRadius: BorderRadius.circular(50),
+ ),
+ padding: const EdgeInsets.only(left: 14, right: 14, top: 3, bottom: 3),
+ child: Text('领券立减100元', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 11)));
+ }
+
+
+ /// 收货后返现
+ Widget _getButtom2Widget() {
+ return Container(
+ decoration: BoxDecoration(
+ color: HexColor.fromHex('#FFEFDA'),
+ borderRadius: BorderRadius.circular(50),
+ ),
+ padding: const EdgeInsets.only(left: 14, right: 14, top: 3, bottom: 3),
+ child: Text('收货后返现5.5元', style: TextStyle(color: HexColor.fromHex('#B78107'), fontSize: 11)));
+ }
+}
diff --git a/lib/widgets/goods_details/coupon/bloc/bloc.dart b/lib/widgets/goods_details/coupon/bloc/bloc.dart
new file mode 100644
index 0000000..8c610f6
--- /dev/null
+++ b/lib/widgets/goods_details/coupon/bloc/bloc.dart
@@ -0,0 +1,3 @@
+export 'counpon_bloc.dart';
+export 'counpon_event.dart';
+export 'counpon_state.dart';
\ No newline at end of file
diff --git a/lib/widgets/goods_details/coupon/bloc/counpon_bloc.dart b/lib/widgets/goods_details/coupon/bloc/counpon_bloc.dart
new file mode 100644
index 0000000..bf024b8
--- /dev/null
+++ b/lib/widgets/goods_details/coupon/bloc/counpon_bloc.dart
@@ -0,0 +1,30 @@
+import 'dart:async';
+import 'dart:math';
+
+import 'package:bloc/bloc.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/coupon/bloc/counpon_repository.dart';
+import 'bloc.dart';
+
+class CounponBloc extends Bloc {
+ @override
+ CounponState get initialState => CounponInitial();
+
+ CounponRepository repository;
+
+ CounponBloc({this.repository});
+
+ @override
+ Stream mapEventToState(
+ CounponEvent event,
+ ) async* {
+ if (event is CounponInitEvent) {
+ yield* _mapInitEnvetTostate(event);
+ }
+ }
+
+ /// 获取数据
+ Stream _mapInitEnvetTostate(CounponInitEvent event) async* {
+ var result = await repository.fetchParentData(event);
+ yield CounponLoadedState(model: result);
+ }
+}
diff --git a/lib/widgets/goods_details/coupon/bloc/counpon_event.dart b/lib/widgets/goods_details/coupon/bloc/counpon_event.dart
new file mode 100644
index 0000000..17697b0
--- /dev/null
+++ b/lib/widgets/goods_details/coupon/bloc/counpon_event.dart
@@ -0,0 +1,15 @@
+import 'package:equatable/equatable.dart';
+
+abstract class CounponEvent extends Equatable {
+ const CounponEvent();
+}
+
+/// 初始化请求
+class CounponInitEvent extends CounponEvent {
+ final Map model;
+
+ const CounponInitEvent({this.model});
+
+ @override
+ List get props => [this.model];
+}
diff --git a/lib/widgets/goods_details/coupon/bloc/counpon_repository.dart b/lib/widgets/goods_details/coupon/bloc/counpon_repository.dart
new file mode 100644
index 0000000..4d5a4f3
--- /dev/null
+++ b/lib/widgets/goods_details/coupon/bloc/counpon_repository.dart
@@ -0,0 +1,11 @@
+import 'package:zhiying_base_widget/widgets/goods_details/coupon/bloc/bloc.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/coupon/model/counpon_model.dart';
+
+class CounponRepository {
+
+ /// 获取父页面传进来的数据
+ Future fetchParentData(CounponInitEvent event) async{
+ return null;
+ }
+
+}
diff --git a/lib/widgets/goods_details/coupon/bloc/counpon_state.dart b/lib/widgets/goods_details/coupon/bloc/counpon_state.dart
new file mode 100644
index 0000000..8dcc9a0
--- /dev/null
+++ b/lib/widgets/goods_details/coupon/bloc/counpon_state.dart
@@ -0,0 +1,25 @@
+import 'package:equatable/equatable.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/coupon/model/counpon_model.dart';
+
+abstract class CounponState extends Equatable {
+ const CounponState();
+}
+
+class CounponInitial extends CounponState {
+ @override
+ List get props => [];
+}
+
+class CounponLoadedState extends CounponState {
+ CounponModel model;
+
+ CounponLoadedState({this.model});
+
+ @override
+ List get props => [this.model];
+}
+
+class CounponErrorState extends CounponState {
+ @override
+ List get props => [];
+}
diff --git a/lib/widgets/goods_details/coupon/counpon_sk.dart b/lib/widgets/goods_details/coupon/counpon_sk.dart
new file mode 100644
index 0000000..65e33d6
--- /dev/null
+++ b/lib/widgets/goods_details/coupon/counpon_sk.dart
@@ -0,0 +1,26 @@
+import 'package:shimmer/shimmer.dart';
+import 'package:flutter/material.dart';
+
+class CounponSkeleton extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: const EdgeInsets.only(left: 12.5, right: 12.5),
+ width: double.infinity,
+ height: 70,
+ child: _shimmerWidget(width: double.infinity, height: 65, radius: 7.5),
+ );
+ }
+
+ Widget _shimmerWidget({double width, double height, double radius = 0}) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300],
+ highlightColor: Colors.grey[100],
+ child: Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/goods_details/coupon/counpon_widget.dart b/lib/widgets/goods_details/coupon/counpon_widget.dart
new file mode 100644
index 0000000..0af9170
--- /dev/null
+++ b/lib/widgets/goods_details/coupon/counpon_widget.dart
@@ -0,0 +1,104 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/coupon/bloc/bloc.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/coupon/bloc/counpon_repository.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/coupon/counpon_sk.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/coupon/model/counpon_model.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+///
+/// 优惠券widget
+///
+class CounponWidget extends StatelessWidget {
+ final Map model;
+
+ const CounponWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container();
+ // return BlocProvider(
+ // create: (_) => CounponBloc(repository: CounponRepository())..add(CounponInitEvent(model: model)),
+ // child: CounponContainer(),
+ // );
+ }
+}
+
+class CounponContainer extends StatefulWidget {
+ @override
+ _CounponContainerState createState() => _CounponContainerState();
+}
+
+class _CounponContainerState extends State {
+ /// 点击领取
+ void _onJump(CounponModel model) {}
+
+ @override
+ Widget build(BuildContext context) {
+ BlocConsumer(
+ listener: (context, state) {},
+ buildWhen: (prev, current) {
+ if (current is CounponErrorState) {
+ return false;
+ }
+ return true;
+ },
+ builder: (context, state) {
+ if (state is CounponLoadedState) {
+ // return _getMainWdiget(state.model);
+ }
+ // return CounponSkeleton();
+ return Container();
+ },
+ );
+ }
+
+ /// 主视图
+ Widget _getMainWdiget(CounponModel model) {
+ return GestureDetector(
+ onTap: () => _onJump(model),
+ behavior: HitTestBehavior.opaque,
+ child: Container(
+ width: double.infinity,
+ margin: const EdgeInsets.only(left: 12.5, right: 12.5),
+ padding: const EdgeInsets.only(left: 18.5),
+ alignment: Alignment.centerLeft,
+ child: Row(
+ children: [
+ /// 价格
+ _getPriceWidget(model),
+ const SizedBox(width: 7.5),
+ /// 有效期
+ _getTimeWidget(model)
+ ],
+ ),
+ ),
+ );
+ }
+
+ /// 价格
+ Widget _getPriceWidget(CounponModel model) {
+ return Row(
+ children: [
+ /// 价格类型
+ Text('¥', style: TextStyle(fontSize: 15, color: HexColor.fromHex('#FFFFFF'))),
+
+ /// 价格
+ Text('100', style: TextStyle(fontSize: 30, color: HexColor.fromHex('#FFFFFF'))),
+ ],
+ );
+ }
+
+ /// 名称与有效期
+ Widget _getTimeWidget(CounponModel model) {
+ return Column(
+ children: [
+ /// 标题
+ Text('优惠券', style: TextStyle(fontSize: 17, color: HexColor.fromHex('#FFFFFF'))),
+
+ /// 到期时间
+ Text('有效期至2020-10-01', style: TextStyle(fontSize: 10, color: HexColor.fromHex('#FFFFFF')))
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/goods_details/coupon/model/counpon_model.dart b/lib/widgets/goods_details/coupon/model/counpon_model.dart
new file mode 100644
index 0000000..090b814
--- /dev/null
+++ b/lib/widgets/goods_details/coupon/model/counpon_model.dart
@@ -0,0 +1,2 @@
+
+class CounponModel{}
\ No newline at end of file
diff --git a/lib/widgets/goods_details/evaluate/godds_details_evaluate_sk.dart b/lib/widgets/goods_details/evaluate/godds_details_evaluate_sk.dart
new file mode 100644
index 0000000..bcb6668
--- /dev/null
+++ b/lib/widgets/goods_details/evaluate/godds_details_evaluate_sk.dart
@@ -0,0 +1,27 @@
+import 'package:shimmer/shimmer.dart';
+import 'package:flutter/material.dart';
+
+///
+/// 商品详情评论骨架屏幕
+///
+class GoodsDetailsEvaluateSkeleton extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Container();
+ }
+
+
+ Widget _shimmerWidget({double width, double height, double radius = 0}) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300],
+ highlightColor: Colors.grey[100],
+ child: Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)),
+ ),
+ );
+ }
+}
+
+
diff --git a/lib/widgets/goods_details/evaluate/goods_details_evaluate_widget.dart b/lib/widgets/goods_details/evaluate/goods_details_evaluate_widget.dart
new file mode 100644
index 0000000..1f404f5
--- /dev/null
+++ b/lib/widgets/goods_details/evaluate/goods_details_evaluate_widget.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+///
+/// 商品详情评价Widget
+///
+class GoodsDetailsEvaluateWidget extends StatelessWidget {
+ final Map model;
+
+ const GoodsDetailsEvaluateWidget(this.model);
+
+ /// 点击查看更多
+ void _openLookMore() {}
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: () => _openLookMore(),
+ behavior: HitTestBehavior.opaque,
+ child: Container(
+ width: double.infinity,
+ padding: const EdgeInsets.only(top: 15, bottom: 15, left: 12.5, right: 12.5),
+ child: getMainWidget(),
+ ),
+ );
+ }
+
+ /// 评价以及查看更多
+ Widget getMainWidget() {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text('宝贝评价', style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 12)),
+ Text('查看更多 >', style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 11)),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/goods_details/footer/goods_details_footer_sk.dart b/lib/widgets/goods_details/footer/goods_details_footer_sk.dart
new file mode 100644
index 0000000..bf7e85e
--- /dev/null
+++ b/lib/widgets/goods_details/footer/goods_details_footer_sk.dart
@@ -0,0 +1,38 @@
+import 'package:shimmer/shimmer.dart';
+import 'package:flutter/material.dart';
+
+class GoodsDetailsFooterSkeleton extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: double.infinity,
+ padding: const EdgeInsets.only(left: 21, right: 12.5, top: 12.5, bottom: 12.5),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ _shimmerWidget(width: 30, height: 30,),
+ const SizedBox(width: 35),
+ _shimmerWidget(width: 30, height: 30,),
+ ],
+ ),
+
+ _shimmerWidget( height: 44, width: 230, radius: 22),
+ ],
+ ),
+ );
+ }
+
+ Widget _shimmerWidget({double width, double height, double radius = 0}) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300],
+ highlightColor: Colors.grey[100],
+ child: Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/goods_details/footer/goods_details_footer_widget.dart b/lib/widgets/goods_details/footer/goods_details_footer_widget.dart
new file mode 100644
index 0000000..1ec445c
--- /dev/null
+++ b/lib/widgets/goods_details/footer/goods_details_footer_widget.dart
@@ -0,0 +1,169 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+///
+/// 商品详情底部Widget
+///
+class GoodsDetailsFooterWidget extends StatelessWidget {
+
+ final Map model;
+
+ const GoodsDetailsFooterWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return GooddsDetailsFooterContainer();
+ }
+}
+
+class GooddsDetailsFooterContainer extends StatefulWidget {
+ @override
+ _GooddsDetailsFooterContainerState createState() => _GooddsDetailsFooterContainerState();
+}
+
+class _GooddsDetailsFooterContainerState extends State {
+ /// 打开首页
+ void _openHome() {}
+
+ /// 收藏
+ void _collectOnClick() {}
+
+ /// 分享
+ void _shareOnClick() {}
+
+ /// 自购省
+ void _savemoneyOnClick() {}
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: 70,
+ width: double.infinity,
+ padding: const EdgeInsets.only(bottom: 10, top: 12.5, left: 21, right: 12.5),
+ decoration: BoxDecoration(
+ boxShadow:[
+ BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0), blurRadius: 5.0, spreadRadius: 2.0),
+ BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0)),
+ ],
+ color: Colors.white
+ ),
+ child: _getMainWidet(),
+ );
+ }
+
+ /// 主Widget
+ Widget _getMainWidet() {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ /// 首页与收藏
+ _getLeftWidget(),
+
+ /// 分享赚与自购省
+ _getRightWidget(),
+ ],
+ );
+ }
+
+ /// 首页 和 收藏
+ Widget _getLeftWidget() {
+ return Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () => _openHome(),
+ child: Padding(
+ padding: const EdgeInsets.only(right: 35),
+ child: _getCustomWidget('首页', '999999', null),
+ )),
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () => _collectOnClick(),
+ child: Padding(padding: const EdgeInsets.only(right: 0), child: _getCustomWidget('收藏', '999999', null)))
+ ],
+ );
+ }
+
+ /// 分享赚与自购省
+ Widget _getRightWidget() {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [_getFxzButton(), _getZgsButton()],
+ );
+ }
+
+ /// 分享赚,
+ Widget _getFxzButton() {
+ return GestureDetector(
+ onTap: () => _shareOnClick(),
+ child: Container(
+ alignment: Alignment.center,
+ padding: const EdgeInsets.only(left: 30, right: 30, top: 5, bottom: 5),
+ decoration: BoxDecoration(
+ gradient: LinearGradient(colors: [HexColor.fromHex('#FFCA66'), HexColor.fromHex('#FFD961')], begin: Alignment.centerLeft, end: Alignment.centerRight),
+ borderRadius: BorderRadius.only(
+ bottomLeft: Radius.circular(25),
+ topLeft: Radius.circular(25)
+ )
+ ),
+ child: Column(
+ children: [
+ RichText(
+ text: TextSpan(text: '¥', style: TextStyle(fontSize: 12, color: HexColor.fromHex('FFFFFF')), children: [
+ TextSpan(text: '3.10', style: TextStyle(fontSize: 15, color: HexColor.fromHex('#FFFFFF'))),
+ ]),
+ ),
+ Text('分享赚', style: TextStyle(color: HexColor.fromHex('#FFFFFF'), fontSize: 15))
+ ],
+ ),
+ ),
+ );
+ }
+
+ /// 自购省
+ Widget _getZgsButton() {
+ return GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () => _savemoneyOnClick(),
+ child: Container(
+ alignment: Alignment.center,
+ padding: const EdgeInsets.only(left: 30, right: 30, top: 5, bottom: 5),
+ decoration: BoxDecoration(
+ gradient: LinearGradient(colors: [HexColor.fromHex('#FF6969'), HexColor.fromHex('#FF4646')], begin: Alignment.centerLeft, end: Alignment.centerRight),
+ borderRadius: BorderRadius.only(
+ bottomRight: Radius.circular(25),
+ topRight: Radius.circular(25)
+ )
+ ),
+ child: Column(
+ children: [
+ RichText(
+ text: TextSpan(text: '¥', style: TextStyle(fontSize: 12, color: HexColor.fromHex('FFFFFF')), children: [
+ TextSpan(text: '23.10', style: TextStyle(fontSize: 15, color: HexColor.fromHex('#FFFFFF'))),
+ ]),
+ ),
+ Text('自购省', style: TextStyle(color: HexColor.fromHex('#FFFFFF'), fontSize: 15))
+ ],
+ ),
+ ),
+ );
+ }
+
+ Widget _getCustomWidget(String text, String textColor, String icon) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ /// 图标
+ Container(height: 25, width: 25, color: Colors.red, margin: const EdgeInsets.only(bottom: 3)),
+
+ /// 图片
+ Text(text, style: TextStyle(color: HexColor.fromHex(textColor), fontSize: 11))
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/goods_details/price/goods_details_price_widget.dart b/lib/widgets/goods_details/price/goods_details_price_widget.dart
new file mode 100644
index 0000000..36d22ca
--- /dev/null
+++ b/lib/widgets/goods_details/price/goods_details_price_widget.dart
@@ -0,0 +1,83 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+///
+/// 商品详情价格widget
+///
+class GoodsDetailsPriceWidget extends StatelessWidget {
+ final Map model;
+
+ const GoodsDetailsPriceWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(margin: const EdgeInsets.symmetric(horizontal: 12.5), child: _getMainWidget());
+ }
+
+ /// 主体视图
+ Widget _getMainWidget() {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ _getLeftWidget(),
+
+ /// 右边widget
+ _getBuyNumberWidget(),
+ ],
+ );
+ }
+
+ /// 左边的wiget 包括价格等
+ Widget _getLeftWidget() {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ /// 价格
+ _getPriceWidget(),
+ const SizedBox(width: 5),
+
+ /// 券后
+ _getQhPriceWidget(),
+ const SizedBox(width: 5),
+
+ /// 积分
+ _getPointsWidget()
+ ],
+ );
+ }
+
+ /// 价格
+ Widget _getPriceWidget() {
+ return Row(
+ children: [
+ Text('¥', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 15)),
+ Text('99', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 30)),
+ ],
+ );
+ }
+
+ /// 积分
+ Widget _getPointsWidget() {
+ return Container(
+ decoration: BoxDecoration(color: HexColor.fromHex('#FFEFDA'), borderRadius: BorderRadius.circular(5)),
+ padding: const EdgeInsets.only(left: 4, right: 7.5, top: 4, bottom: 4),
+ child: Text('', style: TextStyle(color: HexColor.fromHex('#B78107'), fontSize: 9)),
+ );
+ }
+
+ /// 券后价格
+ Widget _getQhPriceWidget() {
+ return Column(
+ children: [
+ Text('券后', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 11)),
+ Text('¥ 199', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 10)),
+ ],
+ );
+ }
+
+ /// 购买人数
+ Widget _getBuyNumberWidget() {
+ return Text('99999人已购买', style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 12.5));
+ }
+}
diff --git a/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_bloc.dart b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_bloc.dart
new file mode 100644
index 0000000..de1fd8f
--- /dev/null
+++ b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_bloc.dart
@@ -0,0 +1,46 @@
+import 'dart:async';
+import 'dart:math';
+
+import 'package:bloc/bloc.dart';
+import 'package:equatable/equatable.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart';
+import 'package:zhiying_comm/util/empty_util.dart';
+
+part 'goods_details_slide_banner_event.dart';
+
+part 'goods_details_slide_banner_state.dart';
+
+class GoodsDetailsSlideBannerBloc extends Bloc {
+ GoodsDetailsSlideBannerRepository repository;
+
+ GoodsDetailsSlideBannerBloc({@required this.repository});
+
+ @override
+ GoodsDetailsSlideBannerState get initialState => GoodsDetailsSlideBannerInitial();
+
+ @override
+ Stream mapEventToState(
+ GoodsDetailsSlideBannerEvent event,
+ ) async* {
+ /// 初始化
+ if (event is GoodsDetailsSlideBannerInitEvent) {
+ yield* _mapInitEventToState(event);
+ }
+ }
+
+ /// 初始化
+ Stream _mapInitEventToState(GoodsDetailsSlideBannerInitEvent event) async* {
+ var parentData = await repository.fetchParentData(event.model);
+ if (!EmptyUtil.isEmpty(parentData)) {
+ yield GoodsDetailsSlideBannerLoadedState(model: parentData);
+ return;
+ }
+ var netData = await repository.fetchNetData(event.model);
+ if (!EmptyUtil.isEmpty(netData))
+ yield GoodsDetailsSlideBannerLoadedState(model: parentData);
+ else
+ yield GoodsDetailsSlideBannerErrorState();
+ }
+}
diff --git a/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_event.dart b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_event.dart
new file mode 100644
index 0000000..68ece5c
--- /dev/null
+++ b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_event.dart
@@ -0,0 +1,15 @@
+part of 'goods_details_slide_banner_bloc.dart';
+
+abstract class GoodsDetailsSlideBannerEvent extends Equatable {
+ const GoodsDetailsSlideBannerEvent();
+}
+
+/// 初始化事件
+class GoodsDetailsSlideBannerInitEvent extends GoodsDetailsSlideBannerEvent {
+ final Map model;
+
+ const GoodsDetailsSlideBannerInitEvent({@required this.model});
+
+ @override
+ List get props => [this.model];
+}
diff --git a/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart
new file mode 100644
index 0000000..c43c29a
--- /dev/null
+++ b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart
@@ -0,0 +1,21 @@
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+class GoodsDetailsSlideBannerRepository {
+ /// 加载父页面数据
+ Future fetchParentData(final Map model) async {
+ if (!EmptyUtil.isEmpty(model)) {
+ try {
+ return GoodsDetailsSlideBannerModel.fromJson(model['data']);
+ } catch (e) {
+ Logger.log(e);
+ }
+ }
+ return null;
+ }
+
+ /// 加载网络数据
+ Future fetchNetData(final Map model) async {
+ return null;
+ }
+}
diff --git a/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_state.dart b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_state.dart
new file mode 100644
index 0000000..ad4637a
--- /dev/null
+++ b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_state.dart
@@ -0,0 +1,26 @@
+part of 'goods_details_slide_banner_bloc.dart';
+
+abstract class GoodsDetailsSlideBannerState extends Equatable {
+ const GoodsDetailsSlideBannerState();
+}
+
+class GoodsDetailsSlideBannerInitial extends GoodsDetailsSlideBannerState {
+ @override
+ List get props => [];
+}
+
+/// 数据加载成功
+class GoodsDetailsSlideBannerLoadedState extends GoodsDetailsSlideBannerState {
+ GoodsDetailsSlideBannerModel model;
+
+ GoodsDetailsSlideBannerLoadedState({this.model});
+
+ @override
+ List get props => [this.model];
+}
+
+/// 数据加载失败
+class GoodsDetailsSlideBannerErrorState extends GoodsDetailsSlideBannerState {
+ @override
+ List get props => [];
+}
diff --git a/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_creater.dart b/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_creater.dart
new file mode 100644
index 0000000..aa80309
--- /dev/null
+++ b/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_creater.dart
@@ -0,0 +1,19 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/goods_details_slide_banner_sk.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+///
+/// 可以滚动Banner
+///
+class HomeSlideBannerCreater extends WidgetCreater {
+ @override
+ List createSkeleton(Map model) {
+ return [GoodsDetailsSlideBannerSkeleton()];
+ }
+
+ @override
+ List createWidgets(Map model) {
+ return [GoodsDetailsSlideBannerWidget(model)];
+ }
+}
diff --git a/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_sk.dart b/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_sk.dart
new file mode 100644
index 0000000..fb50ce9
--- /dev/null
+++ b/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_sk.dart
@@ -0,0 +1,21 @@
+import 'package:flutter/material.dart';
+import 'package:shimmer/shimmer.dart';
+
+class GoodsDetailsSlideBannerSkeleton extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return _shimmerWidget(width: double.infinity, height: 375);
+ }
+
+ Widget _shimmerWidget({double width, double height, double radius = 0}) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300],
+ highlightColor: Colors.grey[100],
+ child: Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart b/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart
new file mode 100644
index 0000000..c1abccf
--- /dev/null
+++ b/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart
@@ -0,0 +1,172 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_swiper/flutter_swiper.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_bloc.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/goods_details_slide_banner_sk.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+import 'package:cached_network_image/cached_network_image.dart';
+
+///
+/// 商品详情轮播图
+///
+class GoodsDetailsSlideBannerWidget extends StatelessWidget {
+ final Map model;
+
+ const GoodsDetailsSlideBannerWidget(this.model, {Key key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return BlocProvider(
+ create: (_) => GoodsDetailsSlideBannerBloc(repository: GoodsDetailsSlideBannerRepository())..add(GoodsDetailsSlideBannerInitEvent(model: model)),
+ child: GoodsDetailsSlideBannerContainer(model),
+ );
+ }
+}
+
+class GoodsDetailsSlideBannerContainer extends StatefulWidget {
+ final Map model;
+
+ const GoodsDetailsSlideBannerContainer(this.model, {Key key}) : super(key: key);
+
+ @override
+ _GoodsDetailsSlideBannerContainerState createState() => _GoodsDetailsSlideBannerContainerState();
+}
+
+class _GoodsDetailsSlideBannerContainerState extends State {
+ /// 子元素点击事件
+ void _itemOnClick(IndexCarousel model) {
+ print('点击了 $model');
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return BlocConsumer(
+ listener: (BuildContext context, GoodsDetailsSlideBannerState state) {
+ if (state is GoodsDetailsSlideBannerErrorState) {
+ print('数据加载出错');
+ }
+ },
+ buildWhen: (previous, current) {
+ /// 数据加载出错不进行build
+ if (current is GoodsDetailsSlideBannerErrorState) {
+ return false;
+ }
+ return true;
+ },
+ builder: (context, state) {
+ print('currente state = $state');
+ if (state is GoodsDetailsSlideBannerLoadedState) {
+ if (!EmptyUtil.isEmpty(state.model) && !EmptyUtil.isEmpty(state.model.index_carousel_list)) {
+ return _getMainWidget(state.model);
+ }
+ }
+ // 骨架屏
+ return GoodsDetailsSlideBannerSkeleton();
+ },
+ );
+ }
+
+ /// 页面
+ Widget _getMainWidget(GoodsDetailsSlideBannerModel datas) {
+ return Container(
+ width: double.infinity,
+ height: 375,
+ child: Swiper(
+ itemBuilder: (BuildContext context, int index) {
+ IndexCarousel items = datas.index_carousel_list[index];
+ return Container(
+ width: double.infinity,
+ child: CachedNetworkImage(imageUrl: items?.img ?? '', fit: BoxFit.cover),
+ );
+ },
+ itemCount: datas?.index_carousel_list?.length ?? 0,
+ loop: true,
+ autoplay: true,
+ onTap: (index) => _itemOnClick(datas.index_carousel_list[index]),
+ pagination: _getSwiperStyleByType(datas, datas?.index_carousel_list?.length ?? 0),
+ ),
+ );
+ }
+
+ /// 获取进度样式
+ SwiperPlugin _getSwiperStyleByType(GoodsDetailsSlideBannerModel model, int pageCount) {
+ if ('1' != model.pagination_open) {
+ return null;
+ }
+
+ if ('type_number' == model.pagination) {
+ return _getNumswiperPlugin(pageCount, model.pagination_select_color, model.pagination_unselect_color);
+ }
+ if ('type_point' == model.pagination) {
+ return _swiperCustomPaginationDito(pageCount, model.pagination_select_color, model.pagination_unselect_color);
+ }
+ if ('type_bar' == model.pagination) {
+ return _swiperCustomPagination(pageCount, model.pagination_select_color, model.pagination_unselect_color);
+ }
+ return null;
+ }
+
+ /// 数字样式
+ SwiperPlugin _getNumswiperPlugin(int pageCount, String selectColor, String unselectColor) {
+ return SwiperCustomPagination(builder: (BuildContext context, SwiperPluginConfig config) {
+ return Align(
+ alignment: Alignment(0.0, 0.9),
+ child: Container(
+ padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 18),
+ decoration: BoxDecoration(borderRadius: BorderRadius.circular(13), color: HexColor.fromHex('#4D000000')),
+ child: RichText(
+ text: TextSpan(text: '${config.activeIndex + 1}', style: TextStyle(fontSize: 12, color: HexColor.fromHex(selectColor)), children: [
+ TextSpan(text: '/', style: TextStyle(fontSize: 12, color: HexColor.fromHex(unselectColor))),
+ TextSpan(text: '$pageCount', style: TextStyle(fontSize: 12, color: HexColor.fromHex(unselectColor))),
+ ]),
+ )),
+ );
+ });
+ }
+
+ /// 自定义进度条
+ SwiperPlugin _swiperCustomPagination(int pageCount, String selectColor, String unselectColor) {
+ List list = [];
+ for (int i = 0; i < pageCount; i++) {
+ list.add(i);
+ }
+
+ return SwiperCustomPagination(builder: (BuildContext context, SwiperPluginConfig config) {
+ return Align(
+ alignment: Alignment(0.0, 0.9),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: list.map((index) {
+ var borderRadius;
+ if (index == 0) {
+ borderRadius = BorderRadius.only(topLeft: Radius.circular(2), bottomLeft: Radius.circular(2));
+ }
+ if (index == list.length - 1) {
+ borderRadius = BorderRadius.only(topRight: Radius.circular(2), bottomRight: Radius.circular(2));
+ }
+
+ if (index == config.activeIndex) {
+ borderRadius = BorderRadius.all(Radius.circular(2));
+ }
+
+ return Container(
+ height: 4,
+ width: 25,
+ decoration: BoxDecoration(borderRadius: borderRadius, color: index == config.activeIndex ? HexColor.fromHex(selectColor) : HexColor.fromHex(unselectColor)),
+ );
+ }).toList(),
+ ),
+ );
+ });
+ }
+
+ /// 圆形进度条
+ SwiperPlugin _swiperCustomPaginationDito(int pageCount, String selectColor, String unselectColor) {
+ return SwiperPagination(
+ margin: const EdgeInsets.only(),
+ builder: DotSwiperPaginationBuilder(color: HexColor.fromHex(unselectColor), activeColor: HexColor.fromHex(selectColor), size: 8, activeSize: 8));
+ }
+}
diff --git a/lib/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart b/lib/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart
new file mode 100644
index 0000000..40f1dd9
--- /dev/null
+++ b/lib/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart
@@ -0,0 +1,61 @@
+
+
+class GoodsDetailsSlideBannerModel {
+ String pagination;
+ String pagination_open;
+ List pagination_options;
+ List index_carousel_list;
+ String pagination_select_color;
+ String pagination_unselect_color;
+
+ GoodsDetailsSlideBannerModel({this.pagination, this.pagination_open, this.pagination_options, this.pagination_select_color, this.pagination_unselect_color, this.index_carousel_list});
+
+ factory GoodsDetailsSlideBannerModel.fromJson(Map json) {
+ return GoodsDetailsSlideBannerModel(
+ pagination: json['pagination'],
+ pagination_open: json['pagination_open'],
+ pagination_options: json['pagination_options'] != null ? new List.from(json['pagination_options']) : null,
+ index_carousel_list: json['index_carousel_list'] != null ? (json['index_carousel_list'] as List).map((i) => IndexCarousel.fromJson(i)).toList() : null,
+ pagination_select_color: json['pagination_select_color'],
+ pagination_unselect_color: json['pagination_unselect_color'],
+
+ );
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ 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.pagination_options != null) {
+ data['pagination_options'] = this.pagination_options;
+ }
+ if (this.index_carousel_list != null) {
+ data['index_carousel_list'] = this.index_carousel_list.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+
+class IndexCarousel {
+ String img;
+ String skip_identifier;
+
+ IndexCarousel({this.img, this.skip_identifier});
+
+ factory IndexCarousel.fromJson(Map json) {
+ return IndexCarousel(
+ img: json['img'],
+ skip_identifier: json['skip_identifier'],
+ );
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['img'] = this.img;
+ data['skip_identifier'] = this.skip_identifier;
+ return data;
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/goods_details/store/bloc/bloc.dart b/lib/widgets/goods_details/store/bloc/bloc.dart
new file mode 100644
index 0000000..38113a3
--- /dev/null
+++ b/lib/widgets/goods_details/store/bloc/bloc.dart
@@ -0,0 +1,4 @@
+
+export 'store_bloc.dart';
+export 'store_event.dart';
+export 'store_state.dart';
\ No newline at end of file
diff --git a/lib/widgets/goods_details/store/bloc/store_bloc.dart b/lib/widgets/goods_details/store/bloc/store_bloc.dart
new file mode 100644
index 0000000..37a23fd
--- /dev/null
+++ b/lib/widgets/goods_details/store/bloc/store_bloc.dart
@@ -0,0 +1,43 @@
+import 'dart:async';
+import 'package:bloc/bloc.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/store/bloc/store_repository.dart';
+import 'package:zhiying_comm/util/empty_util.dart'
+ '';
+
+import 'bloc.dart';
+
+class StoreBloc extends Bloc {
+ StoreRepository repository;
+
+ StoreBloc({this.repository});
+
+ @override
+ StoreState get initialState => StoreInitial();
+
+ @override
+ Stream mapEventToState(
+ StoreEvent event,
+ ) async* {
+
+ /// 初始化
+ if(event is StoreInitEvent){
+ yield* _mapInitEventToState(event);
+ }
+ }
+
+
+ /// 获取数据
+ Stream _mapInitEventToState(StoreInitEvent event) async*{
+ var result = await repository.fetchParentData(event);
+ if(!EmptyUtil.isEmpty(result)){
+ yield StoreLoadedState(model: result);
+ return;
+ }
+ var net = await repository.fetchNetData(event);
+ if(!EmptyUtil.isEmpty(net))
+ yield StoreLoadedState(model: result);
+ else
+ yield StoreErrorState();
+ }
+
+}
diff --git a/lib/widgets/goods_details/store/bloc/store_event.dart b/lib/widgets/goods_details/store/bloc/store_event.dart
new file mode 100644
index 0000000..f7c8642
--- /dev/null
+++ b/lib/widgets/goods_details/store/bloc/store_event.dart
@@ -0,0 +1,11 @@
+import 'package:equatable/equatable.dart';
+
+abstract class StoreEvent extends Equatable {
+ const StoreEvent();
+}
+
+/// 初始化事件
+class StoreInitEvent extends StoreEvent {
+ @override
+ List get props => [];
+}
diff --git a/lib/widgets/goods_details/store/bloc/store_repository.dart b/lib/widgets/goods_details/store/bloc/store_repository.dart
new file mode 100644
index 0000000..46d56ad
--- /dev/null
+++ b/lib/widgets/goods_details/store/bloc/store_repository.dart
@@ -0,0 +1,10 @@
+import 'package:zhiying_base_widget/widgets/goods_details/store/bloc/bloc.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/store/model/store_model.dart';
+
+class StoreRepository {
+ /// 获取上级数据
+ Future fetchParentData(StoreInitEvent event) async {}
+
+ /// 网络数据
+ Future fetchNetData(StoreInitEvent event) async {}
+}
diff --git a/lib/widgets/goods_details/store/bloc/store_state.dart b/lib/widgets/goods_details/store/bloc/store_state.dart
new file mode 100644
index 0000000..0148013
--- /dev/null
+++ b/lib/widgets/goods_details/store/bloc/store_state.dart
@@ -0,0 +1,27 @@
+import 'package:equatable/equatable.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/store/model/store_model.dart';
+
+abstract class StoreState extends Equatable {
+ const StoreState();
+}
+
+class StoreInitial extends StoreState {
+ @override
+ List get props => [];
+}
+
+/// 数据加载完毕
+class StoreLoadedState extends StoreState {
+
+ final StoreModel model;
+ const StoreLoadedState({this.model});
+
+ @override
+ List get props => [];
+}
+
+/// 数据加载出错
+class StoreErrorState extends StoreState {
+ @override
+ List get props => [];
+}
diff --git a/lib/widgets/goods_details/store/model/store_model.dart b/lib/widgets/goods_details/store/model/store_model.dart
new file mode 100644
index 0000000..a3200a9
--- /dev/null
+++ b/lib/widgets/goods_details/store/model/store_model.dart
@@ -0,0 +1,3 @@
+
+
+class StoreModel{}
\ No newline at end of file
diff --git a/lib/widgets/goods_details/store/store_sk.dart b/lib/widgets/goods_details/store/store_sk.dart
new file mode 100644
index 0000000..c3017bc
--- /dev/null
+++ b/lib/widgets/goods_details/store/store_sk.dart
@@ -0,0 +1,44 @@
+import 'package:shimmer/shimmer.dart';
+import 'package:flutter/material.dart';
+
+class StoreSkeleton extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: 50,
+ width: double.infinity,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+
+ /// 图片
+ _shimmerWidget(width: 50, height: 50),
+
+ ///
+ Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+
+ _shimmerWidget(width: 150, height: 20),
+ _shimmerWidget(width: 50, height: 15)
+
+ ],
+ ),
+
+ ],
+ ),
+ );
+ }
+
+ Widget _shimmerWidget({double width, double height, double radius = 0}) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300],
+ highlightColor: Colors.grey[100],
+ child: Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/goods_details/store/store_widget.dart b/lib/widgets/goods_details/store/store_widget.dart
new file mode 100644
index 0000000..de3e999
--- /dev/null
+++ b/lib/widgets/goods_details/store/store_widget.dart
@@ -0,0 +1,147 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/store/bloc/bloc.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/store/bloc/store_repository.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/store/model/store_model.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'store_sk.dart';
+
+///
+/// 商家widget
+///
+class StoreWidget extends StatelessWidget {
+ final Map model;
+
+ const StoreWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return BlocProvider(
+ create: (_) => StoreBloc(repository: StoreRepository())..add(StoreInitEvent()),
+ child: StoreContainer(),
+ );
+ }
+}
+
+class StoreContainer extends StatefulWidget {
+ @override
+ _StoreContainerState createState() => _StoreContainerState();
+}
+
+class _StoreContainerState extends State {
+
+ /// 点击更多
+ void _onMoreClick(){
+
+ }
+
+ /// 点击商家
+ void _onStoreClick(){
+
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return BlocConsumer(
+ listener: (context, state) {},
+ buildWhen: (prev, current) {
+ if (current is StoreErrorState) {
+ return false;
+ }
+ return true;
+ },
+ builder: (context, state) {
+ if (state is StoreLoadedState) {
+ return _getMianWidget(state.model);
+ }
+ return StoreSkeleton();
+ },
+ );
+ }
+
+ /// 主视图
+ Widget _getMianWidget(StoreModel model) {
+ return Container(
+ margin: const EdgeInsets.only(left: 12.5, right: 12.5),
+ child: Row(
+ children: [
+ /// 商家图片
+ _getStoreImgWidget(model),
+
+ Expanded(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ /// 商店名称与更多
+ _getStoreNameWidget(model),
+
+ /// 评分描述
+ _getEvaluateWidget(model),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ /// 商家图片
+ Widget _getStoreImgWidget(StoreModel model) {
+ return Container(
+ width: 50,
+ height: 50,
+ color: Colors.red,
+ );
+ }
+
+ /// 商店名称
+ Widget _getStoreNameWidget(StoreModel model) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ /// 商店名称
+ Text(
+ '品胜京东自营旗舰店',
+ style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 13),
+ ),
+
+ /// 更多
+ Text(
+ '更多店铺优惠 >',
+ style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 11),
+ ),
+ ],
+ );
+ }
+
+ /// 评分描述
+ Widget _getEvaluateWidget(StoreModel model) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ /// 宝贝描述 5.0
+ _getCoustomWidet('宝贝描述 5.0', '#999999', ''),
+
+ /// 物流服务 5.0
+ _getCoustomWidet('宝贝描述 5.0', '#999999', ''),
+
+ /// 服务态度 1.0
+ _getCoustomWidet('宝贝描述 5.0', '#999999', ''),
+ ],
+ );
+ }
+
+ Widget _getCoustomWidet(String text, String textColor, String icon) {
+ return Row(
+ children: [
+ Text(text, style: TextStyle(fontSize: 11, color: HexColor.fromHex(textColor))),
+ Container(
+ width: 12,
+ height: 12,
+ color: Colors.red,
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/goods_details/title/goods_details_title_widget.dart b/lib/widgets/goods_details/title/goods_details_title_widget.dart
new file mode 100644
index 0000000..17a9a32
--- /dev/null
+++ b/lib/widgets/goods_details/title/goods_details_title_widget.dart
@@ -0,0 +1,48 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+///
+/// 商品详情标题
+///
+class GoodsDetailsTitleWidget extends StatelessWidget {
+ final Map model;
+
+ const GoodsDetailsTitleWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: double.infinity,
+ margin: const EdgeInsets.only(left: 12.5, right: 12.5),
+ child: _getMaiWidget(),
+ );
+ }
+
+ /// 主widget
+ Widget _getMaiWidget() {
+ return RichText(
+ maxLines: 2,
+ overflow: TextOverflow.ellipsis,
+ text: TextSpan(children: [
+ WidgetSpan(
+ child: _getGoodsTypeIcon(),
+ ),
+ _getGoodsTitle(),
+ ]),
+ );
+ }
+
+ /// 商品类型图标
+ Widget _getGoodsTypeIcon() {
+ return Container(
+ height: 15,
+ width: 32,
+ color: Colors.red,
+ );
+ }
+
+ /// 商品标题
+ InlineSpan _getGoodsTitle() {
+ return TextSpan(text: '品胜(PISEN)苹果数据线1.5米 适用于苹果手机所有机型 MFI认证安全稳定一年换新1.5米2米', style: TextStyle(fontSize: 14, color: HexColor.fromHex('#FF333333')));
+ }
+}
diff --git a/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart b/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart
new file mode 100644
index 0000000..0d86b2f
--- /dev/null
+++ b/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart
@@ -0,0 +1,3 @@
+
+class UpgradeTipModel{}
+
diff --git a/lib/widgets/goods_details/upgrade_tip/upgrade_tip_sk.dart b/lib/widgets/goods_details/upgrade_tip/upgrade_tip_sk.dart
new file mode 100644
index 0000000..b576576
--- /dev/null
+++ b/lib/widgets/goods_details/upgrade_tip/upgrade_tip_sk.dart
@@ -0,0 +1,27 @@
+
+import 'package:shimmer/shimmer.dart';
+import 'package:flutter/material.dart';
+
+class UpgradeTipSkeleton extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: const EdgeInsets.symmetric(horizontal: 12.5),
+ height: 35,
+ child: _shimmerWidget(width: double.infinity, height: double.infinity, radius: 20),
+ );
+ }
+
+ Widget _shimmerWidget({double width, double height, double radius = 0}) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300],
+ highlightColor: Colors.grey[100],
+ child: Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)),
+ ),
+ );
+ }
+}
+
diff --git a/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart b/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart
new file mode 100644
index 0000000..9f9e69e
--- /dev/null
+++ b/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart
@@ -0,0 +1,57 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_base_widget/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+///
+/// 更新提示widget
+///
+class UpgradeTipWidget extends StatelessWidget {
+ final Map model;
+
+ const UpgradeTipWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ decoration: BoxDecoration(
+ color: HexColor.fromHex('#FFEFDA'),
+ borderRadius: BorderRadius.circular(30),
+ ),
+ padding: const EdgeInsets.only(left: 10, right: 13, top: 10, bottom: 10),
+ margin: const EdgeInsets.symmetric(horizontal: 12.5),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ _geLeftWidget(null),
+ _getRightWidget(null),
+ ],
+ ),
+ );
+ }
+
+ /// 左边的视图
+ Widget _geLeftWidget(UpgradeTipModel model) {
+ return Row(
+ children: [
+ /// 图标
+ Container(width: 15, height: 15, color: Colors.red),
+
+ const SizedBox(width: 7.5),
+
+ /// 文字
+ Text('下载APP升级运营商,享受更多收益', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11))
+ ],
+ );
+ }
+
+ /// 右边的视图
+ Widget _getRightWidget(UpgradeTipModel model) {
+ return Row(
+ children: [
+ Text('前往下载', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)),
+ const SizedBox(width: 4),
+ Text('》', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11))
+ ],
+ );
+ }
+}
diff --git a/lib/widgets/home/home_ai_dialog/home_ai_dialog.dart b/lib/widgets/home/home_ai_dialog/home_ai_dialog.dart
new file mode 100644
index 0000000..f84b59a
--- /dev/null
+++ b/lib/widgets/home/home_ai_dialog/home_ai_dialog.dart
@@ -0,0 +1,9 @@
+import 'package:flutter/material.dart';
+
+
+class HomeAiDialog extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Container();
+ }
+}
diff --git a/lib/widgets/home/home_banner/home_banner_widget.dart b/lib/widgets/home/home_banner/home_banner_widget.dart
index bda962a..34ca54b 100644
--- a/lib/widgets/home/home_banner/home_banner_widget.dart
+++ b/lib/widgets/home/home_banner/home_banner_widget.dart
@@ -45,6 +45,7 @@ class _HomeBannerContainerState extends State {
/// 点击事件
void _itemOnClick(HomeBannerListItemModel model){
print('${model?.skip_identifier}');
+ RouterUtil.route(model.toJson(), context);
}
@override
diff --git a/lib/widgets/home/home_notice/bloc/bloc.dart b/lib/widgets/home/home_notice/bloc/bloc.dart
new file mode 100644
index 0000000..d68273b
--- /dev/null
+++ b/lib/widgets/home/home_notice/bloc/bloc.dart
@@ -0,0 +1,3 @@
+export 'home_notice_bloc.dart';
+export 'home_notice_event.dart';
+export 'home_notice_state.dart';
\ No newline at end of file
diff --git a/lib/widgets/home/home_notice/bloc/home_notice_bloc.dart b/lib/widgets/home/home_notice/bloc/home_notice_bloc.dart
new file mode 100644
index 0000000..56a2cab
--- /dev/null
+++ b/lib/widgets/home/home_notice/bloc/home_notice_bloc.dart
@@ -0,0 +1,32 @@
+import 'dart:async';
+import 'package:bloc/bloc.dart';
+import 'package:zhiying_base_widget/widgets/home/home_notice/bloc/home_notice_repository.dart';
+import 'package:zhiying_comm/util/empty_util.dart';
+import 'bloc.dart';
+
+class HomeNoticeBloc extends Bloc {
+ HomeNoticeRepository repository;
+
+ HomeNoticeBloc({this.repository});
+
+ @override
+ HomeNoticeState get initialState => HomeNoticeInitial();
+
+ @override
+ Stream mapEventToState(
+ HomeNoticeEvent event,
+ ) async* {
+ if(event is HomeNoticeInitEvent){
+ yield* _mapInitEventToState(event);
+ }
+ }
+
+ /// 初始化
+ Stream _mapInitEventToState(HomeNoticeInitEvent event) async* {
+ var parentData = await repository.fetchParentData(event);
+ if(!EmptyUtil.isEmpty(parentData))
+ yield HomeNoticeLoadedState(model: parentData);
+ else
+ yield HomeNoticeErrorState();
+ }
+}
diff --git a/lib/widgets/home/home_notice/bloc/home_notice_event.dart b/lib/widgets/home/home_notice/bloc/home_notice_event.dart
new file mode 100644
index 0000000..7b5c1e0
--- /dev/null
+++ b/lib/widgets/home/home_notice/bloc/home_notice_event.dart
@@ -0,0 +1,16 @@
+import 'package:equatable/equatable.dart';
+import 'bloc.dart';
+
+abstract class HomeNoticeEvent extends Equatable {
+ const HomeNoticeEvent();
+ @override
+ List get props => [];
+}
+
+/// 初始化事件
+class HomeNoticeInitEvent extends HomeNoticeEvent{
+ final Map model;
+ const HomeNoticeInitEvent({this.model});
+ @override
+ List get props => [this.model];
+}
\ No newline at end of file
diff --git a/lib/widgets/home/home_notice/bloc/home_notice_repository.dart b/lib/widgets/home/home_notice/bloc/home_notice_repository.dart
new file mode 100644
index 0000000..c17af8c
--- /dev/null
+++ b/lib/widgets/home/home_notice/bloc/home_notice_repository.dart
@@ -0,0 +1,18 @@
+import 'dart:convert';
+
+import 'package:zhiying_base_widget/widgets/home/home_notice/bloc/bloc.dart';
+import 'package:zhiying_base_widget/widgets/home/home_notice/model/home_notice_model.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+class HomeNoticeRepository {
+ /// 获取父页面的数据
+ Future fetchParentData(HomeNoticeInitEvent event) async {
+ try {
+ String jsonStr = event.model['data'];
+ return HomeNoticeModel.fromJson(jsonDecode(jsonStr));
+ } catch (e) {
+ Logger.log(e);
+ }
+ return null;
+ }
+}
diff --git a/lib/widgets/home/home_notice/bloc/home_notice_state.dart b/lib/widgets/home/home_notice/bloc/home_notice_state.dart
new file mode 100644
index 0000000..e6e4dd3
--- /dev/null
+++ b/lib/widgets/home/home_notice/bloc/home_notice_state.dart
@@ -0,0 +1,30 @@
+import 'package:equatable/equatable.dart';
+import 'package:zhiying_base_widget/widgets/home/home_notice/model/home_notice_model.dart';
+import 'bloc.dart';
+
+abstract class HomeNoticeState extends Equatable {
+ const HomeNoticeState();
+ @override
+ List get props => [];
+}
+
+/// 初始化事件
+class HomeNoticeInitial extends HomeNoticeState {
+ @override
+ List get props => [];
+}
+
+/// 数据加载完毕
+class HomeNoticeLoadedState extends HomeNoticeState {
+ final HomeNoticeModel model;
+
+ const HomeNoticeLoadedState({this.model});
+
+ @override
+ List get props => [this.model];
+}
+
+/// 数据加载出错
+class HomeNoticeErrorState extends HomeNoticeState{
+
+}
diff --git a/lib/widgets/home/home_notice/home_notice_sk.dart b/lib/widgets/home/home_notice/home_notice_sk.dart
new file mode 100644
index 0000000..32e21f8
--- /dev/null
+++ b/lib/widgets/home/home_notice/home_notice_sk.dart
@@ -0,0 +1,28 @@
+import 'package:shimmer/shimmer.dart';
+import 'package:flutter/material.dart';
+
+///
+/// 公告的骨架屏
+///
+class HomeNoticeSkeleton extends StatelessWidget {
+ final Map map;
+
+ const HomeNoticeSkeleton({this.map});
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(padding: const EdgeInsets.symmetric(horizontal: 12.5), child: _shimmerWidget(width: double.infinity, height: 30, radius: 8));
+ }
+
+ Widget _shimmerWidget({double width, double height, double radius = 0}) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300],
+ highlightColor: Colors.grey[100],
+ child: Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/home/home_notice/home_notice_widget.dart b/lib/widgets/home/home_notice/home_notice_widget.dart
new file mode 100644
index 0000000..7a93f70
--- /dev/null
+++ b/lib/widgets/home/home_notice/home_notice_widget.dart
@@ -0,0 +1,203 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:zhiying_base_widget/widgets/home/home_notice/bloc/home_notice_repository.dart';
+import 'package:zhiying_base_widget/widgets/home/home_notice/home_notice_sk.dart';
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+import 'package:zhiying_base_widget/widgets/home/home_notice/model/home_notice_model.dart';
+import 'bloc/bloc.dart';
+
+///
+/// 公告滚动widget
+///
+class HomeNoticeWidget extends StatelessWidget {
+ final Map model;
+
+ const HomeNoticeWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return BlocProvider(
+ create: (_) => HomeNoticeBloc(repository: HomeNoticeRepository())..add(HomeNoticeInitEvent(model: model)),
+ child: HomeNoticeWidgetContianer(),
+ );
+ }
+}
+
+class HomeNoticeWidgetContianer extends StatefulWidget {
+ @override
+ _HomeNoticeWidgetContianerState createState() => _HomeNoticeWidgetContianerState();
+}
+
+class _HomeNoticeWidgetContianerState extends State {
+
+ /// 子item点击事件
+ void _itemOnClick(HomeNoticeModel model) {
+ if(pageIndex == model.notices.length){
+ pageIndex = 0;
+ }
+ print('===== $pageIndex');
+ HomeNoticeNoticesModel item = model.notices[pageIndex];
+ _itemJump(item);
+ }
+
+ /// 子item跳转
+ void _itemJump(HomeNoticeNoticesModel model){
+ print('${model?.skip_identifier}');
+ RouterUtil.route(model.toJson(), context);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return BlocConsumer(
+ listener: (context, state) {},
+ buildWhen: (prev, current) {
+ return true;
+ },
+ builder: (context, state) {
+ if (state is HomeNoticeLoadedState) {
+ return _getMainWidget(state?.model);
+ }
+ return HomeNoticeSkeleton();
+ },
+ );
+ }
+
+ /// 主体页面
+ Widget _getMainWidget(HomeNoticeModel model) {
+ return Container(
+ width: double.infinity,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.only(bottomLeft: Radius.circular(7.5), bottomRight: Radius.circular(7.5))),
+ padding: const EdgeInsets.only(bottom: 7.5),
+ child: Container(
+ decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5), color: HexColor.fromHex(model?.bg_color)),
+ // color: Colors.cyan),
+ margin: const EdgeInsets.only(left: 12.5, right: 12.5),
+ padding: const EdgeInsets.only(top: 8, bottom: 8, left: 12, right: 8),
+ // height: 30,
+ width: double.infinity,
+ child: _getChildWidget(model),
+ ),
+ );
+ }
+
+ var pageIndex = 0;
+
+ Widget _getChildWidget(HomeNoticeModel model) {
+ return GestureDetector(
+ onTap: () => _itemOnClick(model),
+ behavior: HitTestBehavior.opaque,
+ child: Row(
+ children: [
+ /// 图片
+ // Container(width: 52, height: 13, color: Colors.red),
+ CachedNetworkImage(
+ imageUrl: model?.logo_img ?? '',
+ width: 52,
+ ),
+ const SizedBox(width: 14),
+
+ /// 文字
+ Expanded(
+ child: Container(
+ width: double.infinity,
+ height: 15,
+ alignment: Alignment.centerLeft,
+ // color: Colors.yellowAccent,
+ child: MarqueeWidget(
+ model?.notices?.length ?? 0,
+ (BuildContext context, int index) {
+ HomeNoticeNoticesModel item = model.notices[index];
+ return Align(alignment: Alignment.centerLeft, child: Text('${item?.notice_text}' , style: TextStyle(color: HexColor.fromHex(model?.text_color), fontSize: 12)));
+ },
+ onPageChanged: (index) => pageIndex = index,
+ ),
+ ),
+ ),
+ const SizedBox(width: 14),
+
+ /// 图片
+ CachedNetworkImage(imageUrl: model?.jump_img ?? '', height: 18),
+ // Container(
+ // width: 18,
+ // height: 18,
+ // color: Colors.red,
+ // ),
+ ],
+ ),
+ );
+ }
+}
+
+// 上下滚动的消息轮播
+class MarqueeWidget extends StatefulWidget {
+ int count; // 子视图数量
+ IndexedWidgetBuilder itemBuilder; // 子视图构造器
+ final ValueChanged onPageChanged;
+
+ MarqueeWidget(this.count, this.itemBuilder, {this.onPageChanged});
+
+ @override
+ _MarqueeWidgetState createState() => _MarqueeWidgetState();
+}
+
+class _MarqueeWidgetState extends State {
+ PageController _controller;
+ Timer _timer;
+
+ @override
+ void initState() {
+ super.initState();
+
+ if (widget.count > 1) {
+ _controller = PageController();
+ _timer = Timer.periodic(Duration(seconds: 5), (timer) {
+ // 如果当前位于最后一页,则直接跳转到第一页,两者内容相同,跳转时视觉上无感知
+ if (_controller.page.round() >= widget.count) {
+ _controller.jumpToPage(0);
+ }
+ _controller.nextPage(duration: Duration(seconds: 1), curve: Curves.linear);
+ });
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ // return PageView.builder(
+ // scrollDirection: Axis.vertical,
+ // controller: _controller,
+ // itemBuilder: (buildContext, index) {
+ // if (index < widget.count) {
+ // return widget.itemBuilder(buildContext, index);
+ // } else {
+ // return widget.itemBuilder(buildContext, 0);
+ // }
+ // },
+ // itemCount: widget.count + 1, // 在原数据末尾添加一笔数据(即第一笔数据),用于实现无限循环滚动效果
+ // );
+ // }
+
+ return PageView.custom(
+ physics: NeverScrollableScrollPhysics(),
+ childrenDelegate: SliverChildBuilderDelegate((context, index) {
+ if (index < widget.count) {
+ return widget.itemBuilder(context, index);
+ } else {
+ return widget.itemBuilder(context, 0);
+ }
+ }, childCount: widget.count + 1),
+ scrollDirection: Axis.vertical,
+ controller: _controller,
+ onPageChanged: widget?.onPageChanged,
+ );
+ }
+
+ @override
+ void dispose() {
+ super.dispose();
+ _controller?.dispose();
+ _timer?.cancel();
+ }
+}
diff --git a/lib/widgets/home/home_notice/model/home_notice_model.dart b/lib/widgets/home/home_notice/model/home_notice_model.dart
new file mode 100644
index 0000000..1ce3866
--- /dev/null
+++ b/lib/widgets/home/home_notice/model/home_notice_model.dart
@@ -0,0 +1,58 @@
+class HomeNoticeModel {
+ String logo_img;
+ String jump_img;
+ String bg_color;
+ String text_color;
+ String duration_time;
+
+ List notices;
+
+ HomeNoticeModel({this.notices, this.logo_img, this.jump_img, this.bg_color, this.text_color, this.duration_time});
+
+ factory HomeNoticeModel.fromJson(Map json) {
+ return HomeNoticeModel(
+ logo_img: json['logo_img']?.toString(),
+ jump_img: json['jump_img']?.toString(),
+ bg_color: json['bg_color']?.toString(),
+ text_color: json['text_color']?.toString(),
+ duration_time: json['duration_time']?.toString(),
+ notices: json['notices'] != null ? (json['notices'] as List).map((i) => HomeNoticeNoticesModel.fromJson(i)).toList() : null,
+ );
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+
+ data['duration_time'] = this.duration_time;
+ data['text_color'] = this.text_color;
+ data['bg_color'] = this.bg_color;
+ data['jump_img'] = this.jump_img;
+ data['logo_img'] = this.logo_img;
+
+ if (this.notices != null) {
+ data['notices'] = this.notices.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+class HomeNoticeNoticesModel {
+ String notice_text;
+ String skip_identifier;
+
+ HomeNoticeNoticesModel({this.notice_text, this.skip_identifier});
+
+ factory HomeNoticeNoticesModel.fromJson(Map json) {
+ return HomeNoticeNoticesModel(
+ notice_text: json['notice_text']?.toString(),
+ skip_identifier: json['skip_identifier']?.toString(),
+ );
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['img'] = this.notice_text;
+ data['skip_identifier'] = this.skip_identifier;
+ return data;
+ }
+}
diff --git a/lib/widgets/home/home_quick_entry/home_quick_entry.dart b/lib/widgets/home/home_quick_entry/home_quick_entry.dart
index 6d9723a..8689a25 100644
--- a/lib/widgets/home/home_quick_entry/home_quick_entry.dart
+++ b/lib/widgets/home/home_quick_entry/home_quick_entry.dart
@@ -32,8 +32,9 @@ class HomeQuickEntryContianer extends StatefulWidget {
class _HomeQuickEntryContianerState extends State {
/// Icon点击事件
- void _itemIconClick(TypeNormal item){
- print("item type = ${item.skip_identifier}");
+ void _itemIconClick(TypeNormal model){
+ print("item type = ${model.skip_identifier}");
+ RouterUtil.route(model.toJson(), context);
}
@override
@@ -250,6 +251,7 @@ class _HomeQuickEntryContianerState extends State {
SwiperPagination _swiperPaginationDot(HomeQuickEntryModel model){
return SwiperPagination(margin: const EdgeInsets.only(), builder: DotSwiperPaginationBuilder( color: HexColor.fromHex(model?.pagination_unselect_color), activeColor: HexColor.fromHex(model?.pagination_select_color), size: 8, activeSize: 8));
}
+
// 自定义进度条 条形
SwiperPlugin _swiperCustomPagination(int pageCount) {
List list = [];
diff --git a/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_bloc.dart b/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_bloc.dart
index 5b6b786..12d2c6d 100644
--- a/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_bloc.dart
+++ b/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_bloc.dart
@@ -9,8 +9,7 @@ import 'package:zhiying_comm/util/empty_util.dart';
import './bloc.dart';
-class HomeSlideBannerBloc
- extends Bloc {
+class HomeSlideBannerBloc extends Bloc {
HomeSlideBannerRepository repository;
HomeSlideBannerBloc({@required this.repository});
@@ -19,8 +18,7 @@ class HomeSlideBannerBloc
HomeSlideBannerState get initialState => InitialHomeSlideBannerState();
@override
- Stream mapEventToState(
- HomeSlideBannerEvent event) async* {
+ Stream mapEventToState(HomeSlideBannerEvent event) async* {
final currentState = state;
/// 初始化
@@ -31,11 +29,14 @@ class HomeSlideBannerBloc
}
/// 初始化
- Stream _mapInitEventToState(
- HomeBannerInitEvent event) async* {
+ Stream _mapInitEventToState(HomeBannerInitEvent event) async* {
+ var parent = await repository.fetchPreantData(event.model);
+ if(!EmptyUtil.isEmpty(parent)){
+ yield HomeSlideBannerLoadedState(datas: parent);
+ return;
+ }
var cached = await repository.fetchCachedDate(id: event.model['mod_id']);
- if (!EmptyUtil.isEmpty(cached))
- yield HomeSlideBannerCachedState(datas: cached);
+ if (!EmptyUtil.isEmpty(cached)) yield HomeSlideBannerCachedState(datas: cached);
var param = await repository.fetchData(id: event.model['mod_id']);
if (!EmptyUtil.isEmpty(param))
yield HomeSlideBannerLoadedState(datas: param);
diff --git a/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_repository.dart b/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_repository.dart
index a396ff9..37a978a 100644
--- a/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_repository.dart
+++ b/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_repository.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
import 'package:flutter/cupertino.dart';
import 'package:zhiying_base_widget/widgets/home/home_slide_banner/model/home_slide_banner_model.dart';
import 'package:zhiying_comm/util/empty_util.dart';
@@ -6,33 +8,42 @@ import 'package:zhiying_comm/util/net_util.dart';
class HomeSlideBannerRepository {
/// 获取缓存数据
- Future> fetchCachedDate({@required int id}) async {
+ Future fetchCachedDate({@required int id}) async {
var cached = await NetUtil.getRequestCachedData('/api/v1/mod', params: {
'ids': [id]
});
if (!EmptyUtil.isEmpty(cached)) {
- HomeSlideBannerModel model = HomeSlideBannerModel.fromJson(cached);
- if (null != model && !EmptyUtil.isEmpty(model.items)) {
- return model.items;
+ try {
+ return HomeSlideBannerModel.fromJson(cached);
+ }catch(e){
}
+
}
return null;
}
/// 获取父页面传进来的数据
-
+ Future fetchPreantData(@required Map model) async{
+ try{
+ if(!EmptyUtil.isEmpty(model)){
+ return HomeSlideBannerModel.fromJson(jsonDecode(model['data']));
+ }
+ }catch(e){
+ }
+ return null;
+ }
/// 获取数据
- Future> fetchData({@required int id}) async {
+ Future fetchData({@required int id}) async {
var params = await NetUtil.post('/api/v1/mod',
params: {
'ids': [id]
},
cache: true);
if (NetUtil.isSuccess(params) && !EmptyUtil.isEmpty(params[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
- HomeSlideBannerModel model = HomeSlideBannerModel.fromJson(params[GlobalConfig.HTTP_RESPONSE_KEY_DATA]);
- if (null != model && !EmptyUtil.isEmpty(model.items)) {
- return model.items;
+ try{
+ return HomeSlideBannerModel.fromJson(params[GlobalConfig.HTTP_RESPONSE_KEY_DATA]);
+ }catch(e){
}
}
return null;
diff --git a/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_state.dart b/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_state.dart
index 5765ab1..e53e534 100644
--- a/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_state.dart
+++ b/lib/widgets/home/home_slide_banner/bloc/home_slide_banner_state.dart
@@ -16,7 +16,7 @@ class InitialHomeSlideBannerState extends HomeSlideBannerState {
/// 缓存数据
class HomeSlideBannerCachedState extends HomeSlideBannerState {
- List datas;
+ HomeSlideBannerModel datas;
HomeSlideBannerCachedState({this.datas});
@@ -26,12 +26,11 @@ class HomeSlideBannerCachedState extends HomeSlideBannerState {
/// 数据加载完毕状态
class HomeSlideBannerLoadedState extends HomeSlideBannerState {
- List datas;
+ HomeSlideBannerModel datas;
HomeSlideBannerLoadedState({this.datas});
- HomeSlideBannerLoadedState copyWith(
- {List newData}) {
+ HomeSlideBannerLoadedState copyWith({HomeSlideBannerModel newData}) {
return HomeSlideBannerLoadedState(
datas: newData ?? datas,
);
diff --git a/lib/widgets/home/home_slide_banner/home_slide_banner.dart b/lib/widgets/home/home_slide_banner/home_slide_banner.dart
index 5bdbc73..9c1fd78 100644
--- a/lib/widgets/home/home_slide_banner/home_slide_banner.dart
+++ b/lib/widgets/home/home_slide_banner/home_slide_banner.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:provider/provider.dart';
+import 'package:zhiying_base_widget/pages/goods_details_page/goods_details_page.dart';
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
@@ -39,9 +40,14 @@ class HomeSlideBannerContainer extends StatefulWidget {
}
class _HomeSlideBannerContainerState extends State {
+
/// 子元素点击事件
- void _itemOnClick(HomeSlideBannerModelItems items) {
- print('点击了 $items');
+ void _itemOnClick(IndexCarousel model) {
+ print('点击了 $model');
+ // RouterUtil.route(model.toJson(), context);
+ Navigator.push(context, MaterialPageRoute(
+ builder: (_) => PageFactory.create('goods_details', null)
+ ));
}
@override
@@ -73,26 +79,26 @@ class _HomeSlideBannerContainerState extends State {
);
}
- Widget _getMainWidget(List datas) {
+ Widget _getMainWidget(HomeSlideBannerModel datas) {
return Container(
width: double.infinity,
height: 140,
child: Swiper(
itemBuilder: (BuildContext context, int index) {
- HomeSlideBannerModelItems items = datas[index];
+ IndexCarousel items = datas.index_carousel_list[index];
return Container(
- // color: Colors.primaries[index % Colors.primaries.length],
width: double.infinity,
child: CachedNetworkImage(
- imageUrl: items?.img?? '',
+ imageUrl: items?.img ?? '',
fit: BoxFit.cover,
),
);
},
- itemCount: datas?.length ?? 0,
+ itemCount: datas?.index_carousel_list?.length ?? 0,
loop: true,
- onTap: (index) => _itemOnClick(datas[index]),
- pagination: _SwiperCustomPagination(datas?.length ?? 0),
+ autoplay: true,
+ onTap: (index) => _itemOnClick(datas.index_carousel_list[index]),
+ pagination: _getSwiperStyleByType(datas, datas?.index_carousel_list?.length ?? 0),
onIndexChanged: (index) {
print('切换下一页');
Provider.of(context, listen: false).switchBg(Container(
@@ -105,8 +111,45 @@ class _HomeSlideBannerContainerState extends State {
);
}
+ /// 获取进度样式
+ SwiperPlugin _getSwiperStyleByType(HomeSlideBannerModel model, int pageCount) {
+
+ if('1' != model.pagination_open){
+ return null;
+ }
+
+ if ('type_number' == model.pagination) {
+ return _getNumswiperPlugin(pageCount, model.pagination_select_color, model.pagination_unselect_color);
+ }
+ if ('type_point' == model.pagination) {
+ return _swiperCustomPaginationDito(pageCount, model.pagination_select_color, model.pagination_unselect_color);
+ }
+ if ('type_bar' == model.pagination) {
+ return _swiperCustomPagination(pageCount, model.pagination_select_color, model.pagination_unselect_color);
+ }
+ return null;
+ }
+
+ /// 数字样式
+ SwiperPlugin _getNumswiperPlugin(int pageCount, String selectColor, String unselectColor) {
+ return SwiperCustomPagination(builder: (BuildContext context, SwiperPluginConfig config) {
+ return Align(
+ alignment: Alignment(0.0, 0.9),
+ child: Container(
+ padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 18),
+ decoration: BoxDecoration(borderRadius: BorderRadius.circular(13), color: HexColor.fromHex('#4D000000')),
+ child: RichText(
+ text: TextSpan(text: '${config.activeIndex + 1}', style: TextStyle(fontSize: 12, color: HexColor.fromHex(selectColor)), children: [
+ TextSpan(text: '/', style: TextStyle(fontSize: 12, color: HexColor.fromHex(unselectColor))),
+ TextSpan(text: '$pageCount', style: TextStyle(fontSize: 12, color: HexColor.fromHex(unselectColor))),
+ ]),
+ )),
+ );
+ });
+ }
+
/// 自定义进度条
- SwiperPlugin _SwiperCustomPagination(int pageCount) {
+ SwiperPlugin _swiperCustomPagination(int pageCount, String selectColor, String unselectColor) {
List list = [];
for (int i = 0; i < pageCount; i++) {
list.add(i);
@@ -134,11 +177,16 @@ class _HomeSlideBannerContainerState extends State {
return Container(
height: 4,
width: 25,
- decoration: BoxDecoration(borderRadius: borderRadius, color: index == config.activeIndex ? HexColor.fromHex('#FF4242') : HexColor.fromHex('#FFFFFF')),
+ decoration: BoxDecoration(borderRadius: borderRadius, color: index == config.activeIndex ? HexColor.fromHex(selectColor) : HexColor.fromHex(unselectColor)),
);
}).toList(),
),
);
});
}
+
+ /// 圆形进度条
+ SwiperPlugin _swiperCustomPaginationDito(int pageCount, String selectColor, String unselectColor) {
+ return SwiperPagination(margin: const EdgeInsets.only(), builder: DotSwiperPaginationBuilder( color: HexColor.fromHex(unselectColor), activeColor: HexColor.fromHex(selectColor), size: 8, activeSize: 8));
+ }
}
diff --git a/lib/widgets/home/home_slide_banner/model/home_slide_banner_model.dart b/lib/widgets/home/home_slide_banner/model/home_slide_banner_model.dart
index cdcda54..9165299 100644
--- a/lib/widgets/home/home_slide_banner/model/home_slide_banner_model.dart
+++ b/lib/widgets/home/home_slide_banner/model/home_slide_banner_model.dart
@@ -1,115 +1,58 @@
+
class HomeSlideBannerModel {
- List items;
+ List index_carousel_list;
+ String pagination;
+ String pagination_open;
+ List pagination_options;
+ String pagination_select_color;
+ String pagination_unselect_color;
- HomeSlideBannerModel({this.items});
+ HomeSlideBannerModel({this.index_carousel_list, this.pagination, this.pagination_open, this.pagination_options, this.pagination_select_color, this.pagination_unselect_color});
- HomeSlideBannerModel.fromJson(Map json) {
- if (json['6'] != null) {
- items = new List();
- json['6'].forEach((v) {
- items.add(new HomeSlideBannerModelItems.fromJson(v));
- });
+ factory HomeSlideBannerModel.fromJson(Map 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.from(json['pagination_options']) : null,
+ pagination_select_color: json['pagination_select_color'],
+ pagination_unselect_color: json['pagination_unselect_color'],
+ );
}
- }
- Map toJson() {
- final Map data = new Map();
- if (this.items != null) {
- data['6'] = this.items.map((v) => v.toJson()).toList();
+ Map toJson() {
+ final Map data = new Map();
+ 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;
}
- return data;
- }
}
-class HomeSlideBannerModelItems {
- String modId;
- String modPid;
- String modName;
- String position;
- String title;
- String subtitle;
- String url;
- String margin;
- String aspectRatio;
- String icon;
- String img;
- String fontColor;
- String bgImg;
- String bgColor;
- String bgColorT;
- String badge;
- String path;
- String data;
- String sort;
- String isGlobal;
+class IndexCarousel {
+ String img;
+ String skip_identifier;
- HomeSlideBannerModelItems(
- {this.modId,
- this.modPid,
- this.modName,
- this.position,
- this.title,
- this.subtitle,
- this.url,
- this.margin,
- this.aspectRatio,
- this.icon,
- this.img,
- this.fontColor,
- this.bgImg,
- this.bgColor,
- this.bgColorT,
- this.badge,
- this.path,
- this.data,
- this.sort,
- this.isGlobal});
+ IndexCarousel({this.img, this.skip_identifier});
- HomeSlideBannerModelItems.fromJson(Map json) {
- modId = json['mod_id']?.toString();
- modPid = json['mod_pid']?.toString();
- modName = json['mod_name']?.toString();
- position = json['position']?.toString();
- title = json['title']?.toString();
- subtitle = json['subtitle']?.toString();
- url = json['url']?.toString();
- margin = json['margin']?.toString();
- aspectRatio = json['aspect_ratio']?.toString();
- icon = json['icon']?.toString();
- img = json['img']?.toString();
- fontColor = json['font_color']?.toString();
- bgImg = json['bg_img']?.toString();
- bgColor = json['bg_color']?.toString();
- bgColorT = json['bg_color_t']?.toString();
- badge = json['badge']?.toString();
- path = json['path']?.toString();
- data = json['data']?.toString();
- sort = json['sort']?.toString();
- isGlobal = json['is_global']?.toString();
- }
+ factory IndexCarousel.fromJson(Map json) {
+ return IndexCarousel(
+ img: json['img'],
+ skip_identifier: json['skip_identifier'],
+ );
+ }
- Map toJson() {
- final Map data = new Map();
- data['mod_id'] = this.modId;
- data['mod_pid'] = this.modPid;
- data['mod_name'] = this.modName;
- data['position'] = this.position;
- data['title'] = this.title;
- data['subtitle'] = this.subtitle;
- data['url'] = this.url;
- data['margin'] = this.margin;
- data['aspect_ratio'] = this.aspectRatio;
- data['icon'] = this.icon;
- data['img'] = this.img;
- data['font_color'] = this.fontColor;
- data['bg_img'] = this.bgImg;
- data['bg_color'] = this.bgColor;
- data['bg_color_t'] = this.bgColorT;
- data['badge'] = this.badge;
- data['path'] = this.path;
- data['data'] = this.data;
- data['sort'] = this.sort;
- data['is_global'] = this.isGlobal;
- return data;
- }
-}
+ Map toJson() {
+ final Map data = new Map();
+ data['img'] = this.img;
+ data['skip_identifier'] = this.skip_identifier;
+ return data;
+ }
+}
\ No newline at end of file
diff --git a/lib/widgets/home/home_sreach/home_sreach_creater.dart b/lib/widgets/home/home_sreach/home_sreach_creater.dart
new file mode 100644
index 0000000..6102cbd
--- /dev/null
+++ b/lib/widgets/home/home_sreach/home_sreach_creater.dart
@@ -0,0 +1,22 @@
+import 'package:flutter/material.dart';
+import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_widget.dart';
+import 'package:zhiying_base_widget/widgets/others/normal_nav/normal_nav.dart';
+import 'package:zhiying_comm/zhiying_comm.dart';
+
+class HomeSreachCreater extends WidgetCreater {
+ @override
+ List createWidgets(Map model) {
+ return [
+ SliverPersistentHeader(
+ pinned: false,
+ floating: false,
+ delegate: HomeSreachDeleagater(),
+ ),
+ ];
+ }
+
+ @override
+ bool isSliverChild() {
+ return true;
+ }
+}
diff --git a/lib/widgets/home/home_sreach/home_sreach_sk.dart b/lib/widgets/home/home_sreach/home_sreach_sk.dart
new file mode 100644
index 0000000..e3748aa
--- /dev/null
+++ b/lib/widgets/home/home_sreach/home_sreach_sk.dart
@@ -0,0 +1,21 @@
+import 'package:shimmer/shimmer.dart';
+import 'package:flutter/material.dart';
+
+class HomeSreachSkeleton extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Container();
+ }
+
+ Widget _shimmerWidget({double width, double height, double radius = 0}) {
+ return Shimmer.fromColors(
+ baseColor: Colors.grey[300],
+ highlightColor: Colors.grey[100],
+ child: Container(
+ width: width,
+ height: height,
+ decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(radius)),
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/home/home_sreach/home_sreach_widget.dart b/lib/widgets/home/home_sreach/home_sreach_widget.dart
new file mode 100644
index 0000000..c99d7d8
--- /dev/null
+++ b/lib/widgets/home/home_sreach/home_sreach_widget.dart
@@ -0,0 +1,119 @@
+import 'package:zhiying_comm/zhiying_comm.dart';
+import 'package:flutter/material.dart';
+import 'dart:ui';
+
+class HomeSreachDeleagater extends SliverPersistentHeaderDelegate{
+
+ double _height;
+
+ HomeSreachDeleagater() : super() {
+ _height = MediaQueryData.fromWindow(window).padding.top + 44;
+ }
+
+ @override
+ Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
+ print('${shrinkOffset.toString()}');
+ double percent = shrinkOffset / _height;
+ print('${percent.toString()}');
+ return HomeSreachWidget(null);
+ }
+
+ @override
+ double get maxExtent => _height;
+
+ @override
+ double get minExtent => _height;
+
+ @override
+ bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
+ return false;
+ }
+
+}
+
+
+///
+/// 首页搜索框
+///
+class HomeSreachWidget extends StatelessWidget {
+ final Map model;
+
+ const HomeSreachWidget(this.model);
+
+ @override
+ Widget build(BuildContext context) {
+ return HomeSreachContainer();
+ }
+}
+
+class HomeSreachContainer extends StatefulWidget {
+ @override
+ _HomeSreachContainerState createState() => _HomeSreachContainerState();
+}
+
+class _HomeSreachContainerState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return _getMainWidget();
+ }
+
+ /// 主视图
+ Widget _getMainWidget() {
+ return Container(
+ color: Colors.transparent,
+ height: 30,
+ width: double.infinity,
+ margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 10, top: MediaQueryData.fromWindow(window).padding.top + 10),
+ child: Row(
+ children: [
+ /// 搜索框
+ Expanded(
+ child: _getSreachWidget(),
+ ),
+ const SizedBox(width: 10),
+
+ /// 消息
+ _getMessageWidget(),
+ ],
+ ),
+ );
+ }
+
+ /// 搜索栏
+ Widget _getSreachWidget() {
+ return Container(
+ height: 30,
+ width: double.infinity,
+ child: TextField(
+ autofocus: false,
+ style: TextStyle(color: HexColor.fromHex('#FFFFFF'), fontSize: 14),
+ readOnly: true,
+ decoration: InputDecoration(
+ hintText: '输入搜索内容,领券省钱',
+ hintStyle: TextStyle(
+ color: Colors.white,
+ fontSize: 14,
+ ),
+ contentPadding: EdgeInsets.zero,
+ prefixIcon: Icon(
+ Icons.search,
+ color: Colors.white,
+ ),
+ filled: true,
+ fillColor: Color(0x50cccccc),
+ focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Color(0x00000000)), borderRadius: BorderRadius.all(Radius.circular(30))),
+ enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Color(0x00000000)), borderRadius: BorderRadius.all(Radius.circular(30))),
+ ),
+ ),
+ );
+ }
+
+ /// 消息widget
+ Widget _getMessageWidget() {
+ return Container(
+ width: 30,
+ height: 30,
+ color: Colors.red,
+ );
+ }
+}