Flutter ListView 列表點選和網頁載入
阿新 • • 發佈:2018-11-01
上一篇講了使用ListView載入列表資料,本篇,我們講下列表項的點選,因為本篇的例子點選後是載入一個網頁,所以本篇也講下類似於Android的WebView和iOS的UIWebView載入網頁。效果如下:
item點選
在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();
}
}
專案原始碼地址,此專案為持續開發專案,歡迎Start和Fork