mirror of
https://github.com/h7x4/Jisho-Study-Tool.git
synced 2024-12-21 13:37:29 +01:00
Animate kanji search UI
This commit is contained in:
parent
25e270ec1d
commit
99912333ac
@ -15,6 +15,7 @@ class KanjiGrid extends StatelessWidget {
|
|||||||
horizontal: 40.0,
|
horizontal: 40.0,
|
||||||
),
|
),
|
||||||
child: GridView.count(
|
child: GridView.count(
|
||||||
|
shrinkWrap: true,
|
||||||
crossAxisCount: 3,
|
crossAxisCount: 3,
|
||||||
mainAxisSpacing: 10.0,
|
mainAxisSpacing: 10.0,
|
||||||
crossAxisSpacing: 10.0,
|
crossAxisSpacing: 10.0,
|
||||||
|
@ -4,6 +4,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart';
|
import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart';
|
||||||
|
|
||||||
class KanjiSearchBar extends StatefulWidget {
|
class KanjiSearchBar extends StatefulWidget {
|
||||||
|
|
||||||
|
const KanjiSearchBar();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_KanjiSearchBarState createState() => new _KanjiSearchBarState();
|
_KanjiSearchBarState createState() => new _KanjiSearchBarState();
|
||||||
}
|
}
|
||||||
@ -18,7 +21,7 @@ class _KanjiSearchBarState extends State<KanjiSearchBar> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
focus.addListener(_onFocusChange);
|
// focus.addListener(_onFocusChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getKanjiSuggestions(String text) =>
|
void _getKanjiSuggestions(String text) =>
|
||||||
@ -26,19 +29,6 @@ class _KanjiSearchBarState extends State<KanjiSearchBar> {
|
|||||||
|
|
||||||
void updateSuggestions() => _getKanjiSuggestions(textController.text);
|
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() {
|
void _clearText() {
|
||||||
textController.text = '';
|
textController.text = '';
|
||||||
updateSuggestions();
|
updateSuggestions();
|
||||||
@ -63,27 +53,23 @@ class _KanjiSearchBarState extends State<KanjiSearchBar> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return TextField(
|
return TextField(
|
||||||
focusNode: focus,
|
|
||||||
controller: textController,
|
controller: textController,
|
||||||
onChanged: (text) => _getKanjiSuggestions(text),
|
onChanged: (text) => _getKanjiSuggestions(text),
|
||||||
onSubmitted: (text) =>
|
onSubmitted: (text) => {},
|
||||||
BlocProvider.of<KanjiBloc>(context).add(GetKanji(text)),
|
// BlocProvider.of<KanjiBloc>(context).add(GetKanji(text)),
|
||||||
decoration: new InputDecoration(
|
decoration: new InputDecoration(
|
||||||
|
|
||||||
prefixIcon: Icon(Icons.search),
|
prefixIcon: Icon(Icons.search),
|
||||||
hintText: 'Search',
|
hintText: 'Search',
|
||||||
fillColor: Colors.white,
|
fillColor: Colors.white,
|
||||||
filled: true,
|
filled: true,
|
||||||
|
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(10.0),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
),
|
),
|
||||||
contentPadding: EdgeInsets.symmetric(vertical: 10.0),
|
|
||||||
isDense: false,
|
isDense: false,
|
||||||
suffixIcon: (button == TextFieldButton.clear) ? clearButton : pasteButton,
|
suffixIcon: (button == TextFieldButton.clear) ? clearButton : pasteButton,
|
||||||
),
|
),
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.0,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
52
lib/view/components/kanji/kanji_search_options_bar.dart
Normal file
52
lib/view/components/kanji/kanji_search_options_bar.dart
Normal file
@ -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<KanjiBloc>(context).add(ReturnToInitialState()),
|
||||||
|
),
|
||||||
|
_IconButton(
|
||||||
|
icon: Icon(Icons.category),
|
||||||
|
onPressed: () =>
|
||||||
|
BlocProvider.of<KanjiBloc>(context).add(ReturnToInitialState()),
|
||||||
|
),
|
||||||
|
_IconButton(
|
||||||
|
icon: Icon(Icons.mode),
|
||||||
|
onPressed: () =>
|
||||||
|
BlocProvider.of<KanjiBloc>(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);
|
||||||
|
}
|
||||||
|
}
|
@ -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(),
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
95
lib/view/screens/kanji/search.dart
Normal file
95
lib/view/screens/kanji/search.dart
Normal file
@ -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<SearchScreen>
|
||||||
|
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<KanjiBloc, KanjiState>(
|
||||||
|
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),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -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/bloc/kanji/kanji_bloc.dart';
|
||||||
import 'package:jisho_study_tool/view/screens/loading.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 'result.dart';
|
||||||
import 'search/grid.dart';
|
|
||||||
|
|
||||||
class KanjiView extends StatelessWidget {
|
class KanjiView extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
@ -25,8 +22,8 @@ class KanjiView extends StatelessWidget {
|
|||||||
child: BlocBuilder<KanjiBloc, KanjiState>(
|
child: BlocBuilder<KanjiBloc, KanjiState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is KanjiSearch) {
|
if (state is KanjiSearch) {
|
||||||
if (state.type == KanjiSearchType.Initial) return InitScreen();
|
if (state.type == KanjiSearchType.Initial) return SearchScreen();
|
||||||
else if (state is KanjiSearchKeyboard) return SearchGrid(state.kanjiSuggestions);
|
else if (state is KanjiSearchKeyboard) return SearchScreen();
|
||||||
}
|
}
|
||||||
else if (state is KanjiSearchLoading) return LoadingScreen();
|
else if (state is KanjiSearchLoading) return LoadingScreen();
|
||||||
else if (state is KanjiSearchFinished)
|
else if (state is KanjiSearchFinished)
|
||||||
|
Loading…
Reference in New Issue
Block a user