首页 文章

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

提问于
浏览
1

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

How can I open a new view (or any type of widget) when one of the listtiles is pressed?

// 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();
  }
}

Diplay.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;

}

2 回答

  • 1

    用回调替换 onTap

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

    您也可以使用 ExpansionListTile 小部件,并使用您想要打开的小部件作为 ExpansionListTile 的子级 . 它易于使用,并很好地处理动画 .

相关问题