上一篇讲了使用ListView加载列表数据,本篇,我们讲下列表项的点击,因为本篇的例子点击后是加载一个网页,所以本篇也讲下类似于Android的WebView和iOS的UIWebView加载网页。效果如下:
在Android中,您可以通过调用方法setOnClickListener将OnClick绑定到按钮等view上. 在Flutter中,添加触摸监听器有两种方法: 具体可以查阅我之前的博客Flutter中的点击、拖动和其它手势
上篇博客中我们使用了Row、Column等Widget绘制了item,我们再在原来的Widget的外层包装个GestureDetector,添加手势,然后使用onTap处理点击,完整代码如下:
new GestureDetector( child: Padding( padding: new EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0), child: new Column( children: <Widget>[ new Row( crossAxisAlignment: CrossAxisAlignment.start, //纵向对齐方式:起始边对齐 mainAxisSize: MainAxisSize.max, children: <Widget>[ new Expanded( child: Container( height: 95.0, child: getImage(data.articleThumbnail), alignment: FractionalOffset.center, ), flex: 1, ), new Expanded( child: Container( height: 95.0, margin: new EdgeInsets.fromLTRB(5.0, 0.0, 0.0, 0.0), child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ new Container( child: new Text( articleTitle, style: new TextStyle( fontSize: 20.0, fontWeight: FontWeight.w700), maxLines: 1, overflow: TextOverflow.ellipsis, ), alignment: FractionalOffset.topLeft, ), new Container( child: new Text("${data.articleBrief}", style: new TextStyle(fontSize: 16.0), maxLines: 2, overflow: TextOverflow.ellipsis), alignment: Alignment.topLeft, ), new Expanded( child: new Container( margin: new EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0), child: new Stack( children: <Widget>[ new Container( child: new Text("${data.articleAuthor}", style: new TextStyle(fontSize: 10.0)), alignment: FractionalOffset.bottomLeft, ), new Container( child: new Text(time_str, style: new TextStyle(fontSize: 10.0)), alignment: FractionalOffset.bottomRight, ), ], ), ), ) ], ), ), flex: 3, ), ], ), new Divider(), //分割线 ], ), ), onTap: () { onItemClick(i, articleTitle); //处理点击事件 });点击事件进行页面跳转
/** * 列表点击 */ void onItemClick(int i, String articleTitle) { String h5_url = (listData[i].data as Data).url; Navigator.push( context, new MaterialPageRoute( builder: (context) => new NewsWebPage(h5_url, articleTitle))); }网页加载使用组件flutter_webview_plugin 具体实现如下:
import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; /** * @Description 新闻网页,h5 * @Author zhibuyu * @Date 2018/10/19 9:09 * @Version 1.0 */ class NewsWebPage extends StatefulWidget{ String news_url; String title; NewsWebPage(this.news_url,this.title); @override State<StatefulWidget> createState()=>new NewsWebPageState(news_url,title); } class NewsWebPageState extends State<NewsWebPage>{ String news_url; String title; // 标记是否是加载中 bool loading = true; // 标记当前页面是否是我们自定义的回调页面 bool isLoadingCallbackPage = false; GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey(); // URL变化监听器 StreamSubscription<String> onUrlChanged; // WebView加载状态变化监听器 StreamSubscription<WebViewStateChanged> onStateChanged; // 插件提供的对象,该对象用于WebView的各种操作 FlutterWebviewPlugin flutterWebViewPlugin = new FlutterWebviewPlugin(); NewsWebPageState(this.news_url, this.title); @override void initState() { onStateChanged = flutterWebViewPlugin.onStateChanged.listen((WebViewStateChanged state){ // state.type是一个枚举类型,取值有:WebViewState.shouldStart, WebViewState.startLoad, WebViewState.finishLoad switch (state.type) { case WebViewState.shouldStart: // 准备加载 setState(() { loading = true; }); break; case WebViewState.startLoad: // 开始加载 break; case WebViewState.finishLoad: // 加载完成 setState(() { loading = false; }); if (isLoadingCallbackPage) { // 当前是回调页面,则调用js方法获取数据 parseResult(); } break; } }); } // 解析WebView中的数据 void parseResult() { // flutterWebViewPlugin.evalJavascript("get();").then((result) { // // result json字符串,包含token信息 // // }); } @override Widget build(BuildContext context) { List<Widget> titleContent = []; titleContent.add(new Text( // title, "新闻详情", style: new TextStyle(color: Colors.white), )); if (loading) { // 如果还在加载中,就在标题栏上显示一个圆形进度条 titleContent.add(new CupertinoActivityIndicator()); } titleContent.add(new Container(width: 50.0)); // WebviewScaffold是插件提供的组件,用于在页面上显示一个WebView并加载URL return new WebviewScaffold( key: scaffoldKey, url:news_url, // 登录的URL appBar: new AppBar( title: new Row( mainAxisAlignment: MainAxisAlignment.center, children: titleContent, ), iconTheme: new IconThemeData(color: Colors.white), ), withZoom: true, // 允许网页缩放 withLocalStorage: true, // 允许LocalStorage withJavascript: true, // 允许执行js代码 ); } @override void dispose() { // 回收相关资源 // Every listener should be canceled, the same should be done with this stream. onUrlChanged.cancel(); onStateChanged.cancel(); flutterWebViewPlugin.dispose(); super.dispose(); } }项目源代码地址,此项目为持续开发项目,欢迎Star和Fork