Flutter实战一Flutter聊天应用(十)
首先,我们要修复一下之前几篇文章中存在的缺陷。在发送超过两行的消息时,屏幕上显示的消息不会自动换行,会超出最大宽度。我们可以通过将 class ChatMessage extends StatelessWidget {
//...
@override
Widget build(BuildContext context) {
return new SizeTransition(
//...
new Container(
margin: const EdgeInsets.only(top: 5.0),child: snapshot.value['imageUrl'] != null ?
new Image.network(
snapshot.value['imageUrl'],width: 250.0,):
new Container(
width: MediaQuery.of(context).size.width * 0.8,child: new Text(snapshot.value['text']),),//...
);
}
}
使用 现在应用程序不会因为消息太长而超出屏幕宽度,但这是通过硬编码的方式解决的。我们有更好的解决方案,将显示发送人姓名和消息的 class ChatMessage extends StatelessWidget {
//...
@override
Widget build(BuildContext context) {
return new SizeTransition(
//...
child: new Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
new Container(
//...
),new Flexible(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[
new Text(
snapshot.value['senderName'],style: Theme.of(context).textTheme.subhead
),new Container(
margin: const EdgeInsets.only(top: 5.0),child: snapshot.value['imageUrl'] != null ?
new Image.network(
snapshot.value['imageUrl'],):
new Text(snapshot.value['text']),)
//...
);
}
}
回到正题,如果用户想要点击查看原图,这是一个很常见的用户操作,因此我们将实现这个功能。首先,我们在项目的 import 'package:flutter/material.dart';
class ImageZoomable extends StatefulWidget {
ImageZoomable({Key key}) : super(key: key);
@override
_ImageZoomableState createState() => new _ImageZoomableState();
}
class _ImageZoomableState extends State<ImageZoomable> {
@override
Widget build(BuildContext context) {
return new Text('图片查看屏幕');
}
}
现在回到 import 'image_zoomable.dart';
为了使用户能够点击应用程序中的图片,我们在 class ChatMessage extends StatelessWidget {
//...
@override
Widget build(BuildContext context) {
return new SizeTransition(
//...
new Container(
margin: const EdgeInsets.only(top: 5.0),child: snapshot.value['imageUrl'] != null ?
new GestureDetector(
onTap: (){
Navigator.of(context).push( new MaterialPageRoute<Null>(
builder: (BuildContext context) {
return new ImageZoomable();
}
));
},child: new Image.network(
snapshot.value['imageUrl'],)
//...
);
}
}
如果我们只是想显示图片,不需要放大、缩小和移动图片,可以使用 import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:ui' as ui;
//...
class _ImageZoomablePainter extends CustomPainter {
const _ImageZoomablePainter({this.image,this.offset,this.zoom});
final ui.Image image;
final Offset offset;
final double zoom;
@override
void paint(Canvas canvas,Size size) {
paintImage(canvas: canvas,rect: offset & (size * zoom),image: image);
}
@override
bool shouldRepaint(_ImageZoomablePainter old) {
return old.image != image || old.offset != offset || old.zoom != zoom;
}
}
在 class ImageZoomable extends StatefulWidget {
ImageZoomable(this.image,{Key key}) : super(key: key);
final ImageProvider image;
@override
_ImageZoomableState createState() => new _ImageZoomableState();
}
现在将图像文件传到新的 class _ImageZoomableState extends State<ImageZoomable> {
ImageStream _imageStream;
//...
void _resolveImage() {
_imageStream = widget.image.resolve(createLocalImageConfiguration(context));
_imageStream.addListener(_handleImageLoaded);
}
//...
}
我们通过抽像类 接下来,我们在 class _ImageZoomableState extends State<ImageZoomable> {
ImageStream _imageStream;
ui.Image _image;
//...
void _handleImageLoaded(ImageInfo info,bool synchronousCall) {
setState(() {
_image = info.image;
});
}
//...
}
我们现在需要调用 class _ImageZoomableState extends State<ImageZoomable> {
//...
@override
void didChangeDependencies() {
_resolveImage();
super.didChangeDependencies();
}
//...
}
为了防止图像缓存被刷新,我们需要使用 class _ImageZoomableState extends State<ImageZoomable> {
//...
@override
void reassemble() {
_resolveImage();
super.reassemble();
}
//...
}
我们需要dispose方法在当前对象永久从树中删除时调用 class _ImageZoomableState extends State<ImageZoomable> {
//...
@override
void dispose() {
_imageStream.removeListener(_handleImageLoaded);
super.dispose();
}
//...
}
现在我们修改一下 class _ImageZoomableState extends State<ImageZoomable> {
//...
@override
Widget build(BuildContext context) {
return new Transform(
transform: new Matrix4.diagonal3Values(1.0,1.0,1.0),child: new CustomPaint(
painter: new _ImageZoomablePainter(
image: _image,offset: Offset.zero,zoom: 1.0,)
)
);
}
//...
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |