从API数据中进行Flutter多选ListView

问题描述 投票:0回答:1

我正在尝试从json API创建列表而且我希望用户能够从列表中选择多个对象。有人可以帮忙吗?我尝试使用状态,但是每次单击setState函数时,它都会刷新整个屏幕,因此我的选择将被删除。

 import 'dart:convert';

 import 'package:delivery_app/models/product.dart';
 import 'package:delivery_app/screens/payment_page.dart';
 import 'package:delivery_app/services/api_manager.dart';
 import 'package:delivery_app/services/api_services.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_money_formatter/flutter_money_formatter.dart';
 import 'package:http/http.dart' as http;
 import 'package:provider/provider.dart';

 class ServiceDetails extends StatefulWidget {
     final service;

     ServiceDetails({Key key, @required this.service}) : super(key: key);

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

 class _ServiceDetailsState extends State<ServiceDetails> {
 ProductManager pdtManager = new ProductManager();
 String dropdownValue;
 bool isSelected;
 List<Product> products;
 List<String> selectedList = List();
 List data = List();


 Future<String> getSWData() async {
    final String url = "http://beventsgn.com/delivery_app/api/get_agence.php/? 
    service_id=${widget.service.id}";
    try {
        http.Response response = await http.get(url);
        List collection = json.decode(response.body);
        print(collection.toString());
        setState(() {
           data = collection;
        });
    } catch (e) {
        print('Connection impossible');
    }
    return "Sucess";
  }



  @override
  void initState() {
      super.initState();
this.getSWData();
}

@override
Widget build(BuildContext context) {

// TODO: implement build
return Scaffold(
  appBar: AppBar(
    elevation: 0,
    title: Text('${widget.service.name}'),
  ),
  body: Column(
    children: <Widget>[
      Padding(
        padding: EdgeInsets.all(10),
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 10.0),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(15.0),
            border: Border.all(
                color: Colors.amber, style: BorderStyle.solid, width: 0.80),
          ),
          height: 50,
          width: double.infinity,
          child: DropdownButton<String>(
            hint: Text('Sélectionner une agence'),
            value: dropdownValue,
            icon: Icon(Icons.arrow_drop_down),
            iconSize: 34,
            elevation: 16,
            isExpanded: true,
            style: TextStyle(color: Colors.black),
            onChanged: (String newValue) {
              setState(() {
                print(dropdownValue.toString());
                dropdownValue = newValue;
              });
            },
            items: data.map((item) {
              return new DropdownMenuItem(
                child: new Text(item['name']),
                value: item['id'].toString(),
              );
            }).toList(),
          ),
        )
      ),
      Expanded(
        child: Container(
          width: MediaQuery.of(context).size.width,
          child: FutureBuilder(
            future: fetchProduct(6),
            builder: (context, AsyncSnapshot snapshot) {
              print('Test State');
              if(snapshot.hasData) {
                return ListView.builder(
                    itemCount: snapshot.data.length,
                    itemBuilder: (BuildContext context, int index) => _getListProductTile(context, index, snapshot)
                );
              }

              return CircularProgressIndicator();
            },
          )
        ),
      ),
      SizedBox(
        height: 50,
        width: double.infinity,
        child: RaisedButton(
          onPressed: () {
            Navigator.push(context, MaterialPageRoute(builder: (context) => PaymentPage()));
          },
          color: Colors.amber,
          child: Text('${selectedList.length} COMMANDE', style: TextStyle(fontWeight: FontWeight.bold),),
        ),
      )
    ],
  )
);


 }


  Widget _getListProductTile(BuildContext context, int index, AsyncSnapshot snapshot) {
    FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
        amount: double.parse((snapshot.data[index].price)),
        settings: MoneyFormatterSettings(
          symbol: 'GNF',
          thousandSeparator: '.',
          decimalSeparator: ',',
          symbolAndNumberSeparator: ' ',
          fractionDigits: 2,
        )
    );
    MoneyFormatterOutput fo = fmf.output;
    return new GestureDetector(
      onTap: () {
        //print('Befor ${snapshot.data[index].isSelected}');
        //print(snapshot.data[index].id);
        if(selectedList.contains(snapshot.data[index].id)) {
          print("Product alredy selected");
          selectedList.remove(snapshot.data[index].id);
        }else{
            setState(() {
              snapshot.data[index].isSelected = !snapshot.data[index].isSelected;
            });
            selectedList.add(snapshot.data[index].id);
        }
        selectedList.forEach((item) => print('Data $item'));
        //print('After ${snapshot.data[index].isSelected}');
      },
      child: Container(
        height: 90,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(10.0),
        ),
        child: Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(10.0)),
          ),
          color: snapshot.data[index].isSelected ? Colors.red[100] : Colors.white,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Padding(padding: EdgeInsets.all(10),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text('${snapshot.data[index].name}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),),
                    Text('${snapshot.data[index].name}'),
                    Padding(
                      padding: EdgeInsets.only(top: 5),
                      child: Text(fo.symbolOnRight, style: TextStyle(fontSize: 18),),
                    )
                  ],
                ),
              ),
              Container(
                width: 80,
                height: 80,
                child: Card(
                  margin: EdgeInsets.all(0),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.circular(10.0)),
                  ),
                  semanticContainer: true,
                  clipBehavior: Clip.antiAliasWithSaveLayer,
                  child: Image(image: AssetImage('assets/images/fastfood_1.jpg'), fit: BoxFit.fill,),
                ),
              )
            ],
          ),
        ),
      ),
    );

  }

}
api listview flutter multi-select
1个回答
0
投票

随着Flutter重建用于正确设置UI的框架。我们需要使用称为备忘录的方法。更多细节...访问这个网站https://flutterigniter.com/future-async-called-multiple-times/

© www.soinside.com 2019 - 2024. All rights reserved.