Flutter: как передавать одни и те же данные между двумя виджетами? - PullRequest
0 голосов
/ 17 июня 2020

Я создавал приложение, которое показывает список команд по их имени в поиске. Теперь я хочу перейти к новому экрану и показать подробную информацию о команде при нажатии на элементы списка.

Вот блок кода для представления списка:

import 'package:fetchuser/team_details.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

class TeamList extends StatefulWidget {
  String category;

  TeamList({this.category});

  _TeamListState createState() {
    return _TeamListState(category: category);
  }
}

class _TeamListState extends State<TeamList> {
  String category;

  _TeamListState({this.category});

  Future<List<dynamic>> fetchTeams() async {
    var result;
    try {
      result = await http.get(
          "https://www.thesportsdb.com/api/v1/json/1/searchteams.php?t=${widget.category}");
      return json.decode(result.body)['teams'];
    } catch (e) {
      print(e);
    }
  }

  String _teamName(dynamic user) {
    return user['strTeam'];
  }

  String _location(dynamic user) {
    return user['strCountry'];
  }

  String _description(dynamic user){
    return user['strStadiumDescription'];
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: FutureBuilder<List<dynamic>>(
        future: fetchTeams(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.data == null) {
            return Center(
              child: Text("No Teams found"),
            );
          }
          if (snapshot.hasData) {
            return ListView.builder(
                shrinkWrap: true,
                padding: EdgeInsets.all(8),
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return GestureDetector(
                    onTap: () {

                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => TeamDetails(teamList: TeamList(category: category,),)));
                    },
                    child: Card(
                      child: Column(
                        children: <Widget>[
                          ListTile(
                            leading: CircleAvatar(
                                radius: 30,
                                backgroundImage: NetworkImage(
                                    snapshot.data[index]['strTeamBadge'])),
                            title: Text(_teamName(snapshot.data[index])),
                            subtitle: Text(_location(snapshot.data[index])),
                          )
                        ],
                      ),
                    ),
                  );
                });
          }
          if (snapshot.hasError) {
            return Center(
              child: Text(snapshot.error),
            );
          }
          return Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
} 

А это блок кода для страницы описания:

import 'package:fetchuser/team_list.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

class TeamDetails extends StatelessWidget {
  final TeamList teamList;

  const TeamDetails({ this.teamList});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        elevation: 0.0,
        leading: IconButton(
          icon: Icon(Icons.arrow_back,color: Colors.black,),
          onPressed: (){
            Navigator.pop(context);
          },
        ),

      ),
      body: Column(children: <Widget>[
          Text(_description(snapshot.data[index]['strStadiumDescription'])),
      ],),
    );
  }
}  

У меня только что начал работать с флаттером, что мне делать, чтобы это работало правильно?

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

Вы можете скопировать и вставить полный код ниже
Вы можете передать snapshot.data[index] и получить с Map<String, dynamic>
фрагмент кода

Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) => TeamDetails(
                        teamList: snapshot.data[index],
                      )));
...
class TeamDetails extends StatelessWidget {
  final Map<String, dynamic> teamList;

...
 Text("${teamList['strStadiumDescription']}"),

рабочая демонстрация

enter image description here

полный код

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class TeamList extends StatefulWidget {
  String category;

  TeamList({this.category});
  @override
  _TeamListState createState() => _TeamListState();
}

class _TeamListState extends State<TeamList> {
  Future<List<dynamic>> fetchTeams() async {
    var result;
    try {
      result = await http.get(
          "https://www.thesportsdb.com/api/v1/json/1/searchteams.php?t=${widget.category}");
      return json.decode(result.body)['teams'];
    } catch (e) {
      print(e);
    }
  }

  String _teamName(dynamic user) {
    return user['strTeam'];
  }

  String _location(dynamic user) {
    return user['strCountry'];
  }

  String _description(dynamic user) {
    return user['strStadiumDescription'];
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: FutureBuilder<List<dynamic>>(
        future: fetchTeams(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.data == null) {
            return Center(
              child: Text("No Teams found"),
            );
          }
          if (snapshot.hasData) {
            return ListView.builder(
                shrinkWrap: true,
                padding: EdgeInsets.all(8),
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return GestureDetector(
                    onTap: () {
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => TeamDetails(
                                    teamList: snapshot.data[index],
                                  )));
                    },
                    child: Card(
                      child: Column(
                        children: <Widget>[
                          ListTile(
                            leading: CircleAvatar(
                                radius: 30,
                                backgroundImage: NetworkImage(
                                    snapshot.data[index]['strTeamBadge'])),
                            title: Text(_teamName(snapshot.data[index])),
                            subtitle: Text(_location(snapshot.data[index])),
                          )
                        ],
                      ),
                    ),
                  );
                });
          }
          if (snapshot.hasError) {
            return Center(
              child: Text(snapshot.error),
            );
          }
          return Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

class TeamDetails extends StatelessWidget {
  final Map<String, dynamic> teamList;

  const TeamDetails({this.teamList});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        elevation: 0.0,
        leading: IconButton(
          icon: Icon(
            Icons.arrow_back,
            color: Colors.black,
          ),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
      body: Column(
        children: <Widget>[
          Text("${teamList['strStadiumDescription']}"),
        ],
      ),
    );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: TeamList(
        category: "football",
      ),
    );
  }
}
0 голосов
/ 17 июня 2020

Вы передаете данные правильно, но чтобы получить данные из виджета (TeamDetails), вы должны использовать этот код:

widget.teamlist

Вы можете вызвать widget.teamlist, чтобы получить данные и использовать их в любом месте виджета.

...