首页 > 解决方案 > 颤振 json 导航

问题描述

我有两个页面从不同的 url 接收 json 数据,但使用相同的 api。我想从第一页的gridview选择导航到该选择下的相应数据列表到下一页。请帮助我解决这个问题。

第一页代码:

import 'package:best_flutter_ui_templates/que/branch-screen.dart';
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 'package:provider/provider.dart';
import 'dart:convert';
import 'dart:async';
import 'map_search.dart';
import 'que_map.dart';
import 'models/branches.dart';
import 'services/places_service.dart';
import 'que_map.dart';

class CompanyListView extends StatefulWidget {
  final companyData;
  const CompanyListView({Key key, this.callBack, this.companyData})
      : 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_extended";
  List data;
  List branches;

  get places => Provider.of<Future<List<Branches>>>(context);
  @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'];
        // branches = convertDataToJson['data']['companies']['branches'];
      });
    print(data);
    //print(branches);
    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(
                places.length,
                (int index) {
                  final int count = places.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: () {
                              // print(
                              //     "companyid:" + data[index]['id'].toString());
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) => ListPage(),
                                ),
                              );
                            },
                            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(
                                                            (places[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,
              ),
            );
          }),
    );
  }
}

class Company {
  final int id;

  Company({this.id});

  Company.fromJson(Map<dynamic, dynamic> parsedJson) : id = parsedJson['id'];
}

第二页代码:

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';
import 'company_list_view.dart';

class MapSearch extends StatelessWidget {
  final jsonData;
  MapSearch({Key key, this.jsonData}) : super(key: key);

  get data => List(data);
  @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) =>
                                                            CompanyInfoScreen()));
                                              },
                                            )),
                                      ),
                                    );
                                  }),
                            )
                          ],
                        )
                      : Center(child: CircularProgressIndicator());
                },
              )
            : Center(
                child: CircularProgressIndicator(),
              ),
      ),
    );
  }
}

第二页的api调用代码:

import 'package:best_flutter_ui_templates/que/models/companies.dart';
import 'package:flutter/material.dart';

import '../models/branches.dart';
import 'package:http/http.dart' as http;
//import 'package:provider/provider.dart';
import 'dart:convert' as convert;
//import '../company_list_view.dart';

class PlacesService {
  final key = 'AIzaSyD5koOEOmBEm-kyfRig_gF6HCbdbvvZrL8';

  Future<List<Branches>> getPlaces(double latitude, double longitude) async {
    var response =
        await http.get('https://que-api.herokuapp.com/branches');
    var json = convert.jsonDecode(response.body);
    var jsonResults = json['data']['branches'] as List;
    return jsonResults.map((place) => Branches.fromJson(place)).toList();
  }
}

标签: jsonrestflutterhttpdart

解决方案


推荐阅读