在 ListTile 中打开一个新视图 - Flutter

Posted

技术标签:

【中文标题】在 ListTile 中打开一个新视图 - Flutter【英文标题】:Opening a new view inside of ListTile - Flutter 【发布时间】:2018-12-23 10:51:00 【问题描述】:

我正在创建一个颤振应用程序,它使用来自 REST API 的数据来构建一个列表视图。 列表视图内部是列表图块。加载此数据工作正常,但我希望在点击每个列表标题时显示一个新视图。修改 listtile 小部件的 onTap 属性会导致错误: “参数类型‘future’不能应用于参数类型‘()->(void)’”

当按下其中一个列表图块时,如何打开新视图(或任何类型的小部件)?

// Import packages
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:crypto_updater/Currency.dart';
import 'Display.dart';

class Market extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new Container(color: Colors.black, child: MarketBody());
  


class MarketBody extends StatefulWidget 
  @override
  MarketBodyState createState() => MarketBodyState();



class MarketBodyState extends State<MarketBody> 

  // REST API endpoint
  final String url = "https://api.coinmarketcap.com/v2/ticker/";

  // Map containing API data
  Map<String, dynamic> data;

  // List containing all currency objects created from API data
  var currencyList = new List();


  void addCurrency(key, val) 
    Currency coin = Currency.fromJSON(data, key);
    currencyList.add(coin);
  

  // Asynchronously gets currency data from basecoin API
  Future fetchData() async 
    final response =
        await http.get(this.url, headers: "Accept": "application/json");
    if (response.statusCode == 200) 
      data = json.decode(response.body);
      // iterate through each of the currencies listed under "data" in API's returned JSON data
      data["data"].forEach((k, v) => addCurrency(k, v));

      // Sort the list
        currencyList.sort((a, b) => b.price.compareTo(a.price));

     else 
      currencyList.add("Could not load currencies");
    

  

  Future<Null> _refresh() async 
    currencyList.clear();
    await fetchData();
    setState(() 
      build(context);
    );
  


  @override
  Widget build(BuildContext context) 
    return (new Container(
        child: new RefreshIndicator(
            child: ListView.builder(
                itemCount: currencyList == null ? 0 : currencyList.length,
                itemBuilder: (BuildContext context, int index) 
                  return new Container(
                      child: Center(
                          child: Column(children: <Widget>[
                    getListTile(currencyList[index])
                  ])));
                ), onRefresh: _refresh)
    ));
  

  @override
  void initState() 
    super.initState();
    this.fetchData();
  

显示.dart:

import 'package:flutter/material.dart';
import 'package:crypto_updater/Currency.dart';


ListTile getListTile(Currency currency) 

  return new ListTile(
    leading: currency.percentChange_1h > 0 ? Icon(
        Icons.trending_up, color: Colors.green) : Icon(
        Icons.trending_down, color: Colors.red),
    title: Text('$currency.name',
        style: TextStyle(fontSize: 20.0, color: Colors.white)),
    subtitle: currency.percentChange_1h > 0 ? Text('Hourly change: +$currency.percentChange_1h%', style: TextStyle(fontSize: 15.0, color: Colors.white)): Text('Hourly change: $currency.percentChange_1h%', style: TextStyle(fontSize: 15.0, color: Colors.white)),
    trailing: Text('$currency.price',
        style: TextStyle(fontSize: 18.0, color: Colors.white)),
    enabled: true,
//    onTap: Navigator.push(context,MaterialPageRoute(builder: (context) => DetailedView())
  );

Currency.dart:

// A class representing a cryptocurrency
class Currency 

  // Constructor
  Currency(this.name, this.symbol, this.rank,
  this.circulatingSupply, this.totalSupply, this.maxSupply, this.price,
  this.volume_24h, this.marketCap, this.percentChange_1h, this.percentChange_7d, this.percentChange_24h);

  // Returns a string version of the currency
  String toString() 
    return "Name: $this.name, Rank: $this.rank, Price: $this.price";
  


  factory Currency.fromJSON(Map<String, dynamic> json, String key) 
    return Currency(
      name: json['data'][key]['name'] as String,
      symbol: json['data'][key]['symbol'] as String,
      rank: json['data'][key]['rank'] as int,
      circulatingSupply: json['data'][key]['circulating_supply'] as double,
      totalSupply: json['data'][key]['total_supply'] as double,
      maxSupply: json['data'][key]['max_supply'] as double,
      price: json['data'][key]['quotes']['USD']['price'] as double,
      volume_24h: json['data'][key]['quotes']['USD']['volume_24h'] as double,
      marketCap: json['data'][key]['quotes']['USD']['market_cap'] as double,
      percentChange_1h: json['data'][key]['quotes']['USD']['percent_change_1h'] as double,
      percentChange_24h: json['data'][key]['quotes']['USD']['percent_change_24h'] as double,
      percentChange_7d: json['data'][key]['quotes']['USD']['percent_change_7d'] as double,
    );
  

  final String name;
  final String symbol;
  final int rank;
  final double circulatingSupply;
  final double totalSupply;
  final double maxSupply;
  final double price;
  final double volume_24h;
  final double marketCap;
  final double percentChange_1h;
  final double percentChange_24h;
  final double percentChange_7d;


【问题讨论】:

【参考方案1】:

用回调替换您的onTap

onTap:()=>Navigator.push(context,MaterialPageRoute(builder: (context) => DetailedView())

【讨论】:

【参考方案2】:

您也可以改用ExpansionListTile 小部件,并将您想要在点击时打开的小部件用作ExpansionListTile 的子级。它也易于使用 并且很好地处理了动画。

【讨论】:

以上是关于在 ListTile 中打开一个新视图 - Flutter的主要内容,如果未能解决你的问题,请参考以下文章

在点击按钮之前执行的颤动代码

我的 ListView 构建器的 ListTile 小部件不可滚动并且显示渲染问题

如何用颤振在listTile中制作控件

在 ListTile 中更改 CircleAvatar 大小

在 StreamBuilder 中渲染 ListView.ListTile

Flutter Provider-重建列表项而不是列表视图