带有多个链接的 Flutter webview

Posted

技术标签:

【中文标题】带有多个链接的 Flutter webview【英文标题】:Flutter webview with multiple links 【发布时间】:2021-02-18 19:35:57 【问题描述】:

我正在尝试将Webview 与本机 UI 设计相结合。我已经完成了本机 UI,单击 InkWell 后,它将重定向到特定的 html 页面。我现在卡住所有InkWell 打开相同的网址,还有其他方法可以重定向吗?现在我被一个Webview 卡住了,它只显示一个网址。我将需要大约 40 个不同的网址。例如,"https://example.com/data1.html""https://example.com/data2.html""https://example.com/data3.html" 谢谢!

代码

...

child: ListView(
                        children: [
                          buildCalc('img/O1-resize.png','O1'),
                          buildCalc('img/O2-resize.png', 'O2'),
                          buildCalc('img/O3-resize.png', 'O3'),
                          buildCalc('img/O4-resize.png', 'O4'),
                          buildCalc('img/O5-resize.png', 'O5')
                        ]
                        )
...

Widget buildCalc(String imgPath, String topic)
    return Padding(
      padding: EdgeInsets.only(left:10.0, right:10.0, top:10.0),
      child: InkWell(
        onTap: ()
          Navigator.push(
            context,
           MaterialPageRoute(builder:(context)=>Opticsdata()),);
        ,
        child:Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Container(
              child: Row(
                children: [
                  Hero(
                    tag: imgPath,
                    child: Image(
                      image: AssetImage(imgPath),
                      fit: BoxFit.cover,
                      height: 75.0,
                      width: 75.0,
                      )
                    
                    ),
                    SizedBox(width:10.0),
                    Column(
                      crossAxisAlignment:CrossAxisAlignment.start,
                      children: [
                        Text(
                          topic,
                          style: TextStyle(
                            fontFamily: 'Montserrat',
                            fontSize: 17.0,
                            fontWeight: FontWeight.bold,
                          ),
                        )
                      ],
                    )
                ],
              )
              ),
           /* IconButton(icon: Icon(Icons.arrow_forward_ios),
            color: Colors.black,
            onPressed: (),
            )*/
          ],
        )
        ),
      );
  




...


class Opticsdata extends StatefulWidget  
  @override 
  _OpticsState createState() => _OpticsState(); 

 
  
class _OpticsState extends State  
  
  TextEditingController controller=TextEditingController(); 
  FlutterWebviewPlugin flutterWebviewPlugin= FlutterWebviewPlugin(); 
  var url= "https://example.com/data1.html"; 
  
  @override 
  void initState()  
    super.initState(); 
    flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged wvs) ); 
   
   
  @override 
  Widget build(BuildContext context)  
    return WebviewScaffold( 
      url: url, 
      withZoom: true, 
      hidden: true, 
      useWideViewPort: true,
      
      // initialChild: Container( 
      //   child:Center(child: Text("Loading"),) 
      // ), 
      
    ); 
   
 

为任何需要的人编辑下面的工作代码 下面是一个工作示例,它更易于理解。我使用StreamBuilder 并使用来自sites 的声明数据来构建带有标题、url、图像的ListView

 final data = sites;
...
child: StreamBuilder<List<WebSite>>(           
            initialData: data,
            builder: (ctx, snapshot) 
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (ctx, i) => ListTile(
                   contentPadding:EdgeInsets.only(top: 20.0,left: 20.0,bottom:10.0),
                    leading:  ClipRRect(
                    borderRadius: BorderRadius.circular(10.0),//or 15.0
                    child: Container(
                    width: 60,height: 60,
                    child: Image.asset(snapshot.data[i].imageurl,fit: BoxFit.cover),
                    ),
                    
                  ),
                  title: Text(snapshot.data[i].name),
                  onTap: () 
                    print(snapshot.data[i].url);
                     
...

class WebSite 
  final String name;
  final String url;
  final String imageurl;

  WebSite(this.name, this.url, this.imageurl);


final sites = [
   WebSite('title1', 'https://example.com/data1.html','img1'),
   WebSite('title2', 'https://example.com/data2.html','img2'),
   WebSite('title3', 'https://example.com/data3.html','img3'),
   ...
];

在这里,我用 url 和图片声明 ListView 的标题名称。

【问题讨论】:

【参考方案1】:

试试这个。

首先创建一个数据模型,您将在其中保存所有与图像相关的数据。

 class Data
  String image;
  String id;
  Data(this.id,this.image);

然后用图片数据初始化

List<Data> data = [Data(id: '01',image: 'img/O1-resize.png'),Data(id: '01',image: 'img/O1-resize.png'),];

更改您的列表视图

Container(
              child: ListView.builder(
                padding: EdgeInsets.all(8.0),
                itemBuilder: (context, index) 
                  return buildCalc(data[index],context);
                ,
                itemCount: data.length,
              ),
            )

重构这个方法。

     Widget buildCalc(Data data,context)
  return Padding(
    padding: EdgeInsets.only(left:10.0, right:10.0, top:10.0),
    child: InkWell(
        onTap: ()
          Navigator.push(
            context,
            MaterialPageRoute(builder:(context)=>Opticsdata(data: data,)),);
        ,
        child:Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            Container(
                child: Row(
                  children: [
                    Hero(
                        tag: data.id,
                        child: Image(
                          image: AssetImage(data.image),
                          fit: BoxFit.cover,
                          height: 75.0,
                          width: 75.0,
                        )

                    ),
                    SizedBox(width:10.0),
                    Column(
                      crossAxisAlignment:CrossAxisAlignment.start,
                      children: [
                        Text(
                          data.id,
                          style: TextStyle(
                            fontFamily: 'Montserrat',
                            fontSize: 17.0,
                            fontWeight: FontWeight.bold,
                          ),
                        )
                      ],
                    )
                  ],
                )
            ),
            /* IconButton(icon: Icon(Icons.arrow_forward_ios),
            color: Colors.black,
            onPressed: (),
            )*/
          ],
        )
    ),
  );

修改您的光学数据页面。

class Opticsdata extends StatelessWidget

  final Data data;

  const Opticsdata(Key key, this.data) : super(key: key);

  @override
  Widget build(BuildContext context) 
    // TODO: implement build
    return Container();
  

【讨论】:

感谢您的回答!但现在我被 buildCalc 方法困住了,无法生成唯一的 url。我已将 return Container(); 更改为 webview 方法来显示 url。 有没有合适的方法来查看 Opticsdata 页面传递过来的数据值是多少?

以上是关于带有多个链接的 Flutter webview的主要内容,如果未能解决你的问题,请参考以下文章

带有 url 更新和超链接支持的 Flutter web 底部导航栏

带有多个电话号码的 Flutter url_launcher

Flutter/Dart:我的小部件树中可以有多个带有状态的小部件吗?

在 Xcode 升级后 Flutter iOS 构建失败错误并带有多个命令

使用带有Flutter的完整Dart SDK

Flutter:带有嵌套导航的底部导航栏和更改选项卡时恢复根页面