Open jol5 opened 4 years ago
我的建议:封装成一个独立的widget,在框架内调用。不是一切都必须要使用fish-redux,切勿迷信
import 'package:flutter/material.dart';
import 'package:dudulive/global/constants/asset.dart';
typedef OnSearch(String value);
class SearchInputWidget extends StatefulWidget {
final OnSearch onSearch;
/// 前缀小玩意儿
final Widget prefixWidget;
final Widget suffixWidget;
final double radius;
final double boxHeight;
/// 资源由外部传入,保证独立
final String inputClearIcon;
const SearchInputWidget(
{Key key,
this.prefixWidget,
this.suffixWidget,
this.onSearch,
this.radius = 16,
this.boxHeight = 34,
this.inputClearIcon})
: super(key: key);
@override
_SearchInputWidgetState createState() => _SearchInputWidgetState();
}
class _SearchInputWidgetState extends State<SearchInputWidget> {
TextEditingController _searchCtrl;
@override
Widget build(BuildContext context) {
final radius = Radius.circular(widget.radius);
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(radius),
color: Colors.white,
),
constraints: BoxConstraints(maxHeight: widget.boxHeight),
child: Row(
children: <Widget>[
widget.prefixWidget ?? Container(),
Padding(
padding: const EdgeInsets.only(right: 8),
child: VerticalDivider(
color: Color(0xFFEEEEEE),
width: 1,
thickness: 1,
indent: 8,
endIndent: 8,
),
),
Expanded(
child: TextField(
maxLines: 1,
controller: _searchCtrl,
autocorrect: false,
textInputAction: TextInputAction.search,
style: TextStyle(fontSize: 14.0),
decoration: InputDecoration(
border: InputBorder.none,
enabledBorder: InputBorder.none,
disabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
isDense: true,
hintText: '请输入关键字',
hintStyle: TextStyle(
fontSize: 12.0,
color: Color(0xFFBDBDBD),
fontFamily: 'PingFang-SC-Medium'),
fillColor: Colors.white,
),
cursorColor: Color(0xFFFF7043),
autofocus: true,
onSubmitted: widget.onSearch,
onChanged: (value) => setState(() {}),
)),
_searchCtrl.value.text.length > 0
? IconButton(
icon: Image.asset(
widget.inputClearIcon,
width: 10,
height: 10,
),
onPressed: () {
_searchCtrl.clear();
setState(() {});
})
: Container(),
widget.suffixWidget ?? Container(),
],
),
);
}
@override
void initState() {
super.initState();
_searchCtrl = TextEditingController();
}
@override
void dispose() {
_searchCtrl.dispose();
_searchCtrl = null;
super.dispose();
}
}
我的建议:封装成一个独立的widget,在框架内调用。不是一切都必须要使用fish-redux,切勿迷信
import 'package:flutter/material.dart'; import 'package:dudulive/global/constants/asset.dart'; typedef OnSearch(String value); class SearchInputWidget extends StatefulWidget { final OnSearch onSearch; /// 前缀小玩意儿 final Widget prefixWidget; final Widget suffixWidget; final double radius; final double boxHeight; /// 资源由外部传入,保证独立 final String inputClearIcon; const SearchInputWidget( {Key key, this.prefixWidget, this.suffixWidget, this.onSearch, this.radius = 16, this.boxHeight = 34, this.inputClearIcon}) : super(key: key); @override _SearchInputWidgetState createState() => _SearchInputWidgetState(); } class _SearchInputWidgetState extends State<SearchInputWidget> { TextEditingController _searchCtrl; @override Widget build(BuildContext context) { final radius = Radius.circular(widget.radius); return Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(radius), color: Colors.white, ), constraints: BoxConstraints(maxHeight: widget.boxHeight), child: Row( children: <Widget>[ widget.prefixWidget ?? Container(), Padding( padding: const EdgeInsets.only(right: 8), child: VerticalDivider( color: Color(0xFFEEEEEE), width: 1, thickness: 1, indent: 8, endIndent: 8, ), ), Expanded( child: TextField( maxLines: 1, controller: _searchCtrl, autocorrect: false, textInputAction: TextInputAction.search, style: TextStyle(fontSize: 14.0), decoration: InputDecoration( border: InputBorder.none, enabledBorder: InputBorder.none, disabledBorder: InputBorder.none, errorBorder: InputBorder.none, isDense: true, hintText: '请输入关键字', hintStyle: TextStyle( fontSize: 12.0, color: Color(0xFFBDBDBD), fontFamily: 'PingFang-SC-Medium'), fillColor: Colors.white, ), cursorColor: Color(0xFFFF7043), autofocus: true, onSubmitted: widget.onSearch, onChanged: (value) => setState(() {}), )), _searchCtrl.value.text.length > 0 ? IconButton( icon: Image.asset( widget.inputClearIcon, width: 10, height: 10, ), onPressed: () { _searchCtrl.clear(); setState(() {}); }) : Container(), widget.suffixWidget ?? Container(), ], ), ); } @override void initState() { super.initState(); _searchCtrl = TextEditingController(); } @override void dispose() { _searchCtrl.dispose(); _searchCtrl = null; super.dispose(); } }
兄弟说的好啊!确实,这种还是不能都用fish,被困住了。我都换provider了,虽然fish理念是很不错。
合理的使用GlobalKey也可以达到局部刷新效果:
==== State ====
class NumLoginState implements Cloneable<NumLoginState> {
// 用于控制按钮状态
GlobalKey<GradientButtonState> gradientButtonKey =
new GlobalKey<GradientButtonState>();
}
=======Effect=======
void _onChangeLoginBt(Action action, Context<NumLoginState> ctx) {
String name = ctx.state.phoneController.text;
String password = ctx.state.passwordController.text;
if (name.length == 0 || password.length < 6) {
ctx.state.gradientButtonKey.currentState.onDisabled(true);
} else {
ctx.state.gradientButtonKey.currentState.onDisabled(false);
}
}
=====StatefulWidget=====
class GradientButton extends StatefulWidget {
GradientButton({
Key key}): super(key: key);
@override
GradientButtonState createState() => GradientButtonState(disabled);
}
class GradientButtonState extends State<GradientButton> {
GradientButtonState(this._disabled);
bool _disabled = false;
void onDisabled(bool disabled) {
if (disabled != _disabled) {
setState(() {
_disabled = disabled;
});
}
}
@override
Widget build(BuildContext context) {
// 使用_disabled
}
}
目前,我想到的就是利用 输入框的 onChange了,如此,又要走一遍fish_redux的Action,好麻烦啊;有没有类似于MVVM一样,Text改变后,自动更新使用了该值的Widget啊?
如: Offstage( offstage: state.usernameController.text.length<=0, child:Icon(....) .....