Flutter实战一Flutter聊天应用(四)
首先,我要对上一篇文章进行一点补充,在添加动画效果后,需要重新启动应用程序。使用重新启动而不是热重新加载,因为需要清除任何没有动画控制器的现有消息。 目前在我们的应用程序中,即使输入字段中没有文本,也会启用“发送”按钮,我们可以根据该字段是否包含要发送的文本来决定是否启用发送按钮,并更改按钮的外观。定义 class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
final List<ChatMessage> _messages = <ChatMessage>[];
final TextEditingController _textController = new TextEditingController();
bool _isComposing = false;
//...
要在用户与该字段交互时通知文本的更改,需要将 class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
//...
Widget _buildTextComposer() {
return new IconTheme(
data: new IconThemeData(color: Theme.of(context).accentColor),child: new Container(
margin: const EdgeInsets.symmetric(horizontal: 8.0),child: new Row(
children: <Widget> [
new Flexible(
child: new TextField(
controller: _textController,onChanged: (String text) {
setState((){
_isComposing = text.length > 0;
});
},onSubmitted: _handleSubmitted,decoration: new InputDecoration.collapsed(hintText: '发送消息'),)
),new Container(
margin: new EdgeInsets.symmetric(horizontal: 4.0),child: new IconButton(
icon: new Icon(Icons.send),onPressed: _isComposing ?
() => _handleSubmitted(_textController.text) : null
),)
]
)
)
);
//...
}
当文本字段被清除时,修改 class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
//...
void _handleSubmitted(String text) {
_textController.clear();
setState((){
_isComposing = false;
});
ChatMessage message = new ChatMessage(
text: text,animationController: new AnimationController(
duration: new Duration(milliseconds: 300),vsync: this
)
);
setState((){
_messages.insert(0,message);
});
message.animationController.forward();
}
//...
}
接下来,为了让应用程序的UI具有自然的外观,我们可以为 首先,定义一个名为 final ThemeData kIOSTheme = new ThemeData(
primarySwatch: Colors.orange,primaryColor: Colors.grey[100],primaryColorBrightness: Brightness.light,);
final ThemeData kDefaultTheme = new ThemeData(
primarySwatch: Colors.purple,accentColor: Colors.orangeAccent[400],);
修改 //...
import 'package:flutter/foundation.dart';
//...
class TalkcasuallyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: '谈天说地',theme: defaultTargetPlatform == TargetPlatform.iOS
? kIOSTheme
: kDefaultTheme,home: new ChatScreen(),);
}
}
//...
我们还需要将所选主题应用到 class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
//...
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('谈天说地'),elevation:
Theme.of(context).platform == TargetPlatform.iOS ? 0.0 : 4.0,),//...
//...
}
通过在_buildTextComposer方法中修改其Container父窗口控件来自定义发送图标。使用child属性和条件运算符构建一个用于选择按钮的表达式。 //...
import 'package:flutter/cupertino.dart';
//...
class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
//...
Widget _buildTextComposer() {
return new IconTheme(
data: new IconThemeData(color: Theme.of(context).accentColor),child: new Container(
margin: const EdgeInsets.symmetric(horizontal: 8.0),child: new Row(
children: <Widget> [
//...
new Container(
margin: new EdgeInsets.symmetric(horizontal: 4.0),child: Theme.of(context).platform == TargetPlatform.iOS ?
new CupertinoButton(
child: new Text('发送'),onPressed: _isComposing ?
() => _handleSubmitted(_textController.text) : null
) :
new IconButton(
icon: new Icon(Icons.send),onPressed: _isComposing ?
() => _handleSubmitted(_textController.text) : null
),)
]
)
)
);
}
//...
}
将顶级 class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
//...
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('谈天说地'),body: new Container(
child: new Column(
children: <Widget>[
new Flexible(
child: new ListView.builder(
padding: new EdgeInsets.all(8.0),reverse: true,itemBuilder: (_,int index) => _messages[index],itemCount: _messages.length,new Divider(height: 1.0),new Container(
decoration: new BoxDecoration(
color: Theme.of(context).cardColor,child: _buildTextComposer(),)
]
),decoration: Theme.of(context).platform == TargetPlatform.iOS ?
new BoxDecoration(
border: new Border(
top: new BorderSide(color: Colors.grey[200]))
) : null
)
);
}
//...
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |