flutter 项目实战五 item 点击跳转,webview加载

本项目借用 逛丢 网站的部分数据,仅作为 flutter 开发学习之用。 逛丢官方网址:https://guangdiu.com/

flutter windows开发环境设置

flutter 项目实战一 新建 flutter 项目

flutter 项目实战二 网络请求

flutter 项目实战三 json数据解析以及Gson格式化flutter 项目实战二 网络请求

flutter 项目实战四 列表数据展示

flutter 项目实战五 item 点击跳转,webview加载

flutter 项目实战六 drawer侧边栏

flutter 项目实战七 bottomNavigationBar

flutter 项目实战八 下拉刷新 上拉加载

flutter 项目实战九 小时风云榜

在上一部分完成了列表数据的展示,我们可以将item的数据抽出来作为一个单独的widget ,这样在其他的地方我们也直接可以引用了。

新建 index_item.dart

class IndexItem extends StatelessWidget{

  RstData rstData;

  IndexItem({this.rstData}):assert(rstData!=null);//参数rstData必填且不为空

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return _listItem(this.rstData);
  }

  //list列表的item
  Widget _listItem(RstData rstdata){
    return Container(
      height: 110,//设置item的高度
      margin: EdgeInsets.only(left: 5,right: 5,top: 5),//设置item的边距
      decoration: BoxDecoration(
        border: Border.all(color: Colors.black54,width: 1),//设置边框的宽度 以及 颜色
        borderRadius: BorderRadius.all(Radius.circular(5)),//设置圆角
      ),
      child: Row(
        children: <Widget>[
          Container(
            height: 100,
            margin: EdgeInsets.all(5),//设置图片的边距
            child: Image.network(rstdata.image),
          ),//涉及到widget的大小或者边框的时候,使用container包裹
          Expanded(
            child: Container(
              margin: EdgeInsets.only(right: 5),
              child: Column(
                children: <Widget>[
                  Text(rstdata.title),
                  Expanded( //此处使用expanded 填充,然后设置container 的对其方式确保 在底部显示
                    child:  Row(
                      children: <Widget>[
                        Container(
                          alignment: Alignment.bottomLeft,//设置container的对其方式
                          child: Text(rstdata.mall,style: TextStyle(color: Colors.green[500]),),
                        ),
                        Expanded(
                          child: Container(
                            alignment: Alignment.bottomRight,//设置container的对其方式
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.end,//设置ROW的对其显示方式
                              children: <Widget>[
                                Text("${rstdata.pubtime}-",style: TextStyle(color: Colors.green[500],fontSize: 10),),
                                Text(rstdata.fromsite,style: TextStyle(color: Colors.green[500],fontSize: 10),),
                              ],
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),//expanded类似于Android View的layout_weight属性按照比例填充,flex: 为1 时可以不填写此属性
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

}

 

修改 home_index.dart的 _listInfos() 方法,因为对于每一个item都要添加点击事件,但是container不提供点击事件,所有需要把每一个的item包裹一个支持点击事件的widget,此处我们使用 GestureDetector() ,GestureDetector支持各种触摸事件:

代码修改为:

//list列表
Widget _listInfos(){
  return ListView.builder(
      itemCount: _listData==null?0:_listData.length,
      itemBuilder: (content,index){
          RstData data=_listData[index];
         return GestureDetector(
           child: IndexItem(rstData: data,),
           onTap: (){
              _itemClick(data);
           },
         );
      }
  );
}

由于 逛丢的item详情是html页面,所以需要使用webview来加载。flutter 本身不提供 webview 所有此处我们需要导入插件flutter_webview_plugin,在 pubspec.yaml 中添加 flutter_webview_plugin: ^0.2.1+2

然后编写详情加载页:

import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';

class ItemInfoDetail extends StatefulWidget{

  int id;
  String title;
  ItemInfoDetail({this.id,this.title});

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return InfoDetail(id: id,title: title);
  }

}

class InfoDetail extends State<ItemInfoDetail>{

  int id;
  String title;
  String url="https://guangdiu.com/api/showdetail.php";

  InfoDetail({this.id,this.title});

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return WebviewScaffold(
      appBar: AppBar(
        title: Text(title),
        leading: IconButton(
            icon: Icon(Icons.arrow_back_ios,color: Colors.white,),
            onPressed: (){
                Navigator.pop(context);
            }),
      ),
      url: "$url?id=$id&btn=1&kepler=1&bc=1",
      withJavascript: true,
      withLocalStorage: true,
      withZoom: false,
    );
  }

}

_itemClick(data);中的代码

void _itemClick(RstData data){
  Navigator.push(context, MaterialPageRoute(builder: (cx)=>ItemInfoDetail(id: data.id,title: data.title,)));
}

这是写就直接可以加载详情页了,其中 Navigator.push 与 Navigator.pop 为页面间跳转的代码,Navigator.push 类似Android的 startActivity ,Navigator.pop 相当于 finish ,如果返回时需要带参数,可以直接写成 Navigator.pop(context,"参数一",参数二,.....),相比较于 react native 的路由跳转,这是相当的方便了。

上面的内容只是加载了网页,但是在实际使用的时候可能会出现各种各样的问题,所以我们还得给webview的加载加上监听,来监听状态的变化以及添加加载错误时的操作。

修改代码为

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';

class ItemInfoDetail extends StatefulWidget{

  int id;
  String title;
  ItemInfoDetail({this.id,this.title});

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return InfoDetail(id: id,title: title);
  }

}

class InfoDetail extends State<ItemInfoDetail>{

  int id;
  String title;
  String url="https://guangdiu.com/api/showdetail.php";

  InfoDetail({this.id,this.title});

  FlutterWebviewPlugin flutterWebviewPlugin=FlutterWebviewPlugin();
  StreamSubscription<String> _urlchange;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _urlchange=flutterWebviewPlugin.onUrlChanged.listen((loadUrl){
      //WebviewScaffold 加载的url变化时触发此方法
      print(loadUrl);
    });

    //加载错误时监听
    flutterWebviewPlugin.onHttpError.listen((error){
      print(error.code);
    });

    //加载状态变化监听
    flutterWebviewPlugin.onStateChanged.listen((state){
      print(state.type.toString());
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return WebviewScaffold(
      appBar: AppBar(
        title: Text(title),
        leading: IconButton(
            icon: Icon(Icons.arrow_back_ios,color: Colors.white,),
            onPressed: (){
                Navigator.pop(context);
            }),
      ),
      url: "$url?id=$id&btn=1&kepler=1&bc=1",
      withJavascript: true,
      withLocalStorage: true,
      withZoom: false,
    );
  }

}

 

码云 git 下载

kotlin版本的源码下载:git下载地址

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值