【问题标题】:Flutter gridview item navigation with Json data带有 Json 数据的 Flutter gridview 项目导航
【发布时间】:2021-03-15 16:23:39
【问题描述】:

我想从网格视图中的主页项目导航到根据所做选择显示数据的页面/屏幕。 gridview 中的项目来自 JSON API(使用 HTTP),我希望选择一个项目来导航到一个页面,该页面列出主页上各个项目的数据。全部来自 JSON。我需要你的帮助,我很陌生。 这是我的带有网格视图项的主页代码。

import 'package:best_flutter_ui_templates/que/que_app_theme.dart';
import 'package:best_flutter_ui_templates/que/models/category.dart';
import 'package:best_flutter_ui_templates/main.dart';
import 'package:best_flutter_ui_templates/que/que_map.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'map_search.dart';
import 'que_map.dart';
import 'models/branches.dart';
import 'services/places_service.dart';

class CompanyListView extends StatefulWidget {
  const CompanyListView({Key key, this.callBack}) : super(key: key);

  final Function callBack;
  @override
  _CompanyListViewState createState() => _CompanyListViewState();
}

class _CompanyListViewState extends State<CompanyListView>
    with TickerProviderStateMixin {
  AnimationController animationController;
  final String url = "https://que-api.herokuapp.com/companies";
  List data;
  @override
  void initState() {
    animationController = AnimationController(
        duration: const Duration(milliseconds: 2000), vsync: this);
    super.initState();
    this.getJsonData();
  }

  Future<String> getJsonData() async {
    var response = await http.get(
        //Encode the url
        Uri.encodeFull(url),
        //only accept json response
        headers: {"Accept": "application/json"});

    if (mounted)
      setState(() {
        var convertDataToJson = json.decode(response.body);
        data = convertDataToJson['data']['companies'];
      });
    print(data);
    return "Success";
  }

  Future<bool> getData() async {
    await Future<dynamic>.delayed(const Duration(milliseconds: 200));
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: 8),
      child: FutureBuilder<String>(
          future: getJsonData(),
          builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            return GridView(
              padding: const EdgeInsets.all(8),
              physics: const BouncingScrollPhysics(),
              scrollDirection: Axis.vertical,
              children: List<Widget>.generate(
                data.length,
                (int index) {
                  final int count = data.length;
                  final Animation<double> animation =
                      Tween<double>(begin: 0.0, end: 1.0).animate(
                    CurvedAnimation(
                      parent: animationController,
                      curve: Interval((1 / count) * index, 1.0,
                          curve: Curves.fastOutSlowIn),
                    ),
                  );
                  animationController.forward();
                  return AnimatedBuilder(
                    animation: animationController,
                    builder: (BuildContext context, Widget child) {
                      return FadeTransition(
                        opacity: animation,
                        child: Transform(
                          transform: Matrix4.translationValues(
                              0.0, 50 * (1.0 - animation.value), 0.0),
                          child: InkWell(
                            splashColor: Colors.transparent,
                            onTap: () {
                              Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                    builder: (context) => MapSearch(),
                                  ));
                            },
                            child: SizedBox(
                              height: 280,
                              child: Stack(
                                alignment: AlignmentDirectional.bottomCenter,
                                children: <Widget>[
                                  Container(
                                    child: Column(
                                      children: <Widget>[
                                        Expanded(
                                          child: Container(
                                            decoration: BoxDecoration(
                                              color: HexColor('#F8FAFB'),
                                              borderRadius:
                                                  const BorderRadius.all(
                                                      Radius.circular(16.0)),
                                              // border: new Border.all(
                                              //     color: QueAppTheme.notWhite),
                                            ),
                                            child: Column(
                                              children: <Widget>[
                                                Expanded(
                                                  child: Container(
                                                    child: Column(
                                                      children: <Widget>[
                                                        Padding(
                                                          padding:
                                                              const EdgeInsets
                                                                      .only(
                                                                  top: 16,
                                                                  left: 16,
                                                                  right: 16),
                                                          child: Text(
                                                            (data[index]
                                                                ['name']),
                                                            textAlign:
                                                                TextAlign.left,
                                                            style: TextStyle(
                                                              fontWeight:
                                                                  FontWeight
                                                                      .w600,
                                                              fontSize: 16,
                                                              letterSpacing:
                                                                  0.27,
                                                              color: QueAppTheme
                                                                  .darkerText,
                                                            ),
                                                          ),
                                                        ),
                                                        Padding(
                                                          padding:
                                                              const EdgeInsets
                                                                      .only(
                                                                  top: 8,
                                                                  left: 16,
                                                                  right: 16,
                                                                  bottom: 8),
                                                          child: Row(
                                                            mainAxisAlignment:
                                                                MainAxisAlignment
                                                                    .spaceBetween,
                                                            crossAxisAlignment:
                                                                CrossAxisAlignment
                                                                    .center,
                                                        
                                                          ),
                                                        ),
                                                      ],
                                                    ),
                                                  ),
                                                ),
                                                const SizedBox(
                                                  width: 48,
                                                ),
                                              ],
                                            ),
                                          ),
                                        ),
                                        const SizedBox(
                                          height: 48,
                                        ),
                                      ],
                                    ),
                                  ),
                                  Container(
                                    child: Padding(
                                      padding: const EdgeInsets.only(
                                          top: 20, right: 16, left: 16),
                                      child: Container(
                                        decoration: BoxDecoration(
                                          borderRadius: const BorderRadius.all(
                                              Radius.circular(16.0)),
                                          boxShadow: <BoxShadow>[
                                            BoxShadow(
                                                color: QueAppTheme.grey
                                                    .withOpacity(0.2),
                                                offset: const Offset(0.0, 0.0),
                                                blurRadius: 6.0),
                                          ],
                                        ),
                                        child: ClipRRect(
                                          borderRadius: const BorderRadius.all(
                                              Radius.circular(16.0)),
                                          child: AspectRatio(
                                              aspectRatio: 1.0,
                                              child: Image.network(
                                                  (data[index]['logo']))),
                                        ),
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        ),
                      );
                    },
                  );
                 
                },
              ),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                mainAxisSpacing: 32.0,
                crossAxisSpacing: 32.0,
                childAspectRatio: 0.8,
              ),
            );
          }),
    );
  }
}

这是我要导航到的页面的代码,以及相应的 json 数据

import 'package:best_flutter_ui_templates/que/models/branches.dart';
import 'package:best_flutter_ui_templates/que/que_app_theme.dart';
import 'package:best_flutter_ui_templates/que/screens/Selectcentservice.dart';
import 'package:best_flutter_ui_templates/que/services/geolocator_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
import 'package:geolocator/geolocator.dart';
import 'models/branches.dart';
import 'company_info_screen.dart';
import 'models/location.dart';
import 'services/marker_service.dart';
import 'services/places_service.dart';

class MapSearch extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final currentPosition = Provider.of<Position>(context);
    final placesProvider = Provider.of<Future<List<Branches>>>(context);
    final geoservice = GeoLocatorService();
    final markerService = MarkerService();

    return FutureProvider(
      create: (context) => placesProvider,
      child: Scaffold(
        body: (currentPosition != null)
            ? Consumer<List<Branches>>(
                builder: (_, places, __) {
                  var markers = (places != null)
                      ? markerService.getMarkers(places)
                      : List<Marker>();
                  return (places != null)
                      ? Column(
                          children: <Widget>[
                            Container(
                              height: MediaQuery.of(context).size.height / 3,
                              width: MediaQuery.of(context).size.width,
                              child: GoogleMap(
                                initialCameraPosition: CameraPosition(
                                    target: LatLng(currentPosition.latitude,
                                        currentPosition.longitude),
                                    zoom: 16.0),
                                zoomGesturesEnabled: true,
                                markers: Set<Marker>.of(markers),
                              ),
                            ),
                            SizedBox(
                              height: 10.0,
                            ),
                            Expanded(
                              child: ListView.builder(
                                  itemCount: places.length,
                                  itemBuilder: (context, index) {
                                    return FutureProvider(
                                      create: (context) =>
                                          geoservice.getDistance(
                                              currentPosition.latitude,
                                              currentPosition.longitude,
                                              places[index].latitude,
                                              places[index].longitude),
                                      child: Card(
                                        child: ListTile(
                                            title: Text(places[index].name),
                                            subtitle: Column(
                                              crossAxisAlignment:
                                                  CrossAxisAlignment.start,
                                              children: <Widget>[
                                                SizedBox(
                                                  height: 3.0,
                                                ),
                                              
                                                Consumer<double>(builder:
                                                    (context, meters, widget) {
                                                  return (meters != null)
                                                      ? Text(
                                                          '${places[index].vicinity}\u00b7 ${(meters / 1000).round()} km')
                                                      : Container();
                                                }),
                                              ],
                                            ),
                                            trailing: IconButton(
                                              icon: Icon(Icons.arrow_forward),
                                              color: QueAppTheme.nearlyBlue,
                                              onPressed: () {
                                                Navigator.push(
                                                    context,
                                                    MaterialPageRoute(
                                                        builder: (context) =>
                                                            Selectcentservice()));
                                              },
                                            )),
                                      ),
                                    );
                                  }),
                            )
                          ],
                        )
                      : Center(child: CircularProgressIndicator());
                },
              )
            : Center(
                child: CircularProgressIndicator(),
              ),
      ),
    );
  }
}

【问题讨论】:

    标签: json flutter dart flutter-navigation


    【解决方案1】:

    在 MapSearch 类中添加带参数的构造函数

    class MapSearch extends StatelessWidget {
    final jsonData;
    MapSearch({key Key,this.jsonData}):super(key:key);
      @override
      Widget build(BuildContext context) {
    .......
    }
    

    现在您可以在地图搜索中应用 jsonData。

    在 _CompanyListViewState 类中 Inkwell 的 onTap 中

         child: InkWell(
                splashColor: Colors.transparent,
                onTap: () {
                      Navigator.push(context,
                      MaterialPageRoute(builder: (context) => MapSearch(jsonData: /*Add your json data here*/),
                 ));
             },
    ....
    

    【讨论】:

    • 我做了以上步骤。然后在 _CompanyListViewState 的 Inkwell 的 onTap 中,通过 jsonData 我使用了 jsonData:places[index].name,但是存在未定义名称场所的语法错误,当我使用 jsonData:data[index].name 时,我得到一个当我单击列表项时,应用程序中出现错误。没有这样的方法错误类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 2023-02-25
    相关资源
    最近更新 更多