From 99912333ac10e4549dd380b55a331b861703bafa Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 19 Jul 2021 01:47:12 +0200 Subject: [PATCH] Animate kanji search UI --- lib/view/components/kanji/kanji_grid.dart | 1 + .../components/kanji/kanji_search_bar.dart | 28 ++---- .../kanji/kanji_search_options_bar.dart | 52 ++++++++++ lib/view/screens/kanji/init.dart | 17 ---- lib/view/screens/kanji/search.dart | 95 +++++++++++++++++++ lib/view/screens/kanji/view.dart | 9 +- 6 files changed, 158 insertions(+), 44 deletions(-) create mode 100644 lib/view/components/kanji/kanji_search_options_bar.dart delete mode 100644 lib/view/screens/kanji/init.dart create mode 100644 lib/view/screens/kanji/search.dart diff --git a/lib/view/components/kanji/kanji_grid.dart b/lib/view/components/kanji/kanji_grid.dart index 5861b76..52ea485 100644 --- a/lib/view/components/kanji/kanji_grid.dart +++ b/lib/view/components/kanji/kanji_grid.dart @@ -15,6 +15,7 @@ class KanjiGrid extends StatelessWidget { horizontal: 40.0, ), child: GridView.count( + shrinkWrap: true, crossAxisCount: 3, mainAxisSpacing: 10.0, crossAxisSpacing: 10.0, diff --git a/lib/view/components/kanji/kanji_search_bar.dart b/lib/view/components/kanji/kanji_search_bar.dart index 67e4342..2248eb4 100644 --- a/lib/view/components/kanji/kanji_search_bar.dart +++ b/lib/view/components/kanji/kanji_search_bar.dart @@ -4,6 +4,9 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart'; class KanjiSearchBar extends StatefulWidget { + + const KanjiSearchBar(); + @override _KanjiSearchBarState createState() => new _KanjiSearchBarState(); } @@ -18,7 +21,7 @@ class _KanjiSearchBarState extends State { @override void initState() { super.initState(); - focus.addListener(_onFocusChange); + // focus.addListener(_onFocusChange); } void _getKanjiSuggestions(String text) => @@ -26,19 +29,6 @@ class _KanjiSearchBarState extends State { void updateSuggestions() => _getKanjiSuggestions(textController.text); - void _onFocusChange() { - debugPrint('TextField Focus Changed: ${focus.hasFocus.toString()}'); - - setState(() { - button = focus.hasFocus ? TextFieldButton.clear : TextFieldButton.paste; - }); - - if (focus.hasFocus) - updateSuggestions(); - else - FocusScope.of(context).unfocus(); - } - void _clearText() { textController.text = ''; updateSuggestions(); @@ -63,27 +53,23 @@ class _KanjiSearchBarState extends State { ); return TextField( - focusNode: focus, controller: textController, onChanged: (text) => _getKanjiSuggestions(text), - onSubmitted: (text) => - BlocProvider.of(context).add(GetKanji(text)), + onSubmitted: (text) => {}, + // BlocProvider.of(context).add(GetKanji(text)), decoration: new InputDecoration( prefixIcon: Icon(Icons.search), hintText: 'Search', fillColor: Colors.white, filled: true, + border: OutlineInputBorder( borderRadius: BorderRadius.circular(10.0), ), - contentPadding: EdgeInsets.symmetric(vertical: 10.0), isDense: false, suffixIcon: (button == TextFieldButton.clear) ? clearButton : pasteButton, ), - style: TextStyle( - fontSize: 14.0, - ), ); } } \ No newline at end of file diff --git a/lib/view/components/kanji/kanji_search_options_bar.dart b/lib/view/components/kanji/kanji_search_options_bar.dart new file mode 100644 index 0000000..080f15c --- /dev/null +++ b/lib/view/components/kanji/kanji_search_options_bar.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart'; + +//TODO: Make buttons have an effect + +class KanjiSearchOptionsBar extends StatelessWidget { + const KanjiSearchOptionsBar({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _IconButton( + icon: Text( + "部", + style: TextStyle( + fontWeight: FontWeight.w700, + fontSize: 18, + ), + ), + onPressed: () => + BlocProvider.of(context).add(ReturnToInitialState()), + ), + _IconButton( + icon: Icon(Icons.category), + onPressed: () => + BlocProvider.of(context).add(ReturnToInitialState()), + ), + _IconButton( + icon: Icon(Icons.mode), + onPressed: () => + BlocProvider.of(context).add(ReturnToInitialState()), + ), + ], + ), + ); + } +} + +class _IconButton extends StatelessWidget { + final Widget icon; + final Function onPressed; + const _IconButton({this.icon, this.onPressed, Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return IconButton(onPressed: onPressed, icon: icon); + } +} diff --git a/lib/view/screens/kanji/init.dart b/lib/view/screens/kanji/init.dart deleted file mode 100644 index 44717c7..0000000 --- a/lib/view/screens/kanji/init.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:jisho_study_tool/view/components/kanji/kanji_search_bar.dart'; - -class InitScreen extends StatelessWidget { - const InitScreen({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - alignment: Alignment.center, - padding: EdgeInsets.symmetric(horizontal: 20), - child: KanjiSearchBar(), - ); - - } -} \ No newline at end of file diff --git a/lib/view/screens/kanji/search.dart b/lib/view/screens/kanji/search.dart new file mode 100644 index 0000000..5949094 --- /dev/null +++ b/lib/view/screens/kanji/search.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart'; +import 'package:animated_size_and_fade/animated_size_and_fade.dart'; + +import 'package:jisho_study_tool/view/components/kanji/kanji_grid.dart'; +import 'package:jisho_study_tool/view/components/kanji/kanji_search_bar.dart'; +import 'package:jisho_study_tool/view/components/kanji/kanji_search_options_bar.dart'; + +class SearchScreen extends StatefulWidget { + SearchScreen({Key key}) : super(key: key); + + @override + _SearchScreenState createState() => _SearchScreenState(); +} + +class _SearchScreenState extends State + with SingleTickerProviderStateMixin { + AnimationController _controller; + Animation _searchbarMovementAnimation; + + @override + void initState() { + super.initState(); + + _controller = AnimationController( + vsync: this, + duration: Duration(milliseconds: 200), + ); + + _searchbarMovementAnimation = AlignmentTween( + begin: Alignment.center, + end: Alignment.topCenter, + ).animate(CurvedAnimation( + parent: _controller, + curve: Curves.easeInOut, + )); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: BoxDecoration(), + alignment: Alignment.center, + padding: EdgeInsets.symmetric(horizontal: 20), + child: AnimatedBuilder( + animation: _searchbarMovementAnimation, + builder: (BuildContext context, _) { + return Container( + alignment: _searchbarMovementAnimation.value, + padding: EdgeInsets.symmetric(vertical: 10.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Focus( + onFocusChange: (hasFocus) { + if (hasFocus) + _controller.forward(); + else + _controller.reverse(); + }, + child: KanjiSearchBar(), + ), + BlocBuilder( + builder: (context, state) { + return AnimatedSizeAndFade( + vsync: this, + child: _controller.value == 1 + ? KanjiGrid((state is KanjiSearchKeyboard) + ? state.kanjiSuggestions + : []) + // ? Container() + : KanjiSearchOptionsBar(), + fadeDuration: const Duration(milliseconds: 200), + sizeDuration: const Duration(milliseconds: 300), + ); + }, + ) + ], + ), + ); + }, + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/view/screens/kanji/view.dart b/lib/view/screens/kanji/view.dart index 77c1daf..25c4c12 100644 --- a/lib/view/screens/kanji/view.dart +++ b/lib/view/screens/kanji/view.dart @@ -4,12 +4,9 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart'; import 'package:jisho_study_tool/view/screens/loading.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_grid.dart'; -import 'package:jisho_study_tool/view/components/kanji/kanji_search_bar.dart'; -import 'init.dart'; +import 'search.dart'; import 'result.dart'; -import 'search/grid.dart'; class KanjiView extends StatelessWidget { @override @@ -25,8 +22,8 @@ class KanjiView extends StatelessWidget { child: BlocBuilder( builder: (context, state) { if (state is KanjiSearch) { - if (state.type == KanjiSearchType.Initial) return InitScreen(); - else if (state is KanjiSearchKeyboard) return SearchGrid(state.kanjiSuggestions); + if (state.type == KanjiSearchType.Initial) return SearchScreen(); + else if (state is KanjiSearchKeyboard) return SearchScreen(); } else if (state is KanjiSearchLoading) return LoadingScreen(); else if (state is KanjiSearchFinished)