Flutter 从 API 内容中多选芯片

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

我正在使用这个多选颤振包。它已经有查看芯片的内容,但我想从 API 加载内容来做到这一点。

我已经添加了一个

fetchData()
函数来从 API 下载数据。现在,如何将 JSON 数据放入芯片多选中?

这是我的代码:

import 'dart:convert';

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

import 'Includes/APILinks.dart';

void main() => runApp(Sample());

class Sample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List _myActivities;
  String _myActivitiesResult;
  final formKey = new GlobalKey<FormState>();

  @override
  void initState() {
    super.initState();
    _myActivities = [];
    this.fetchData();
  }

  _saveForm() {
    var form = formKey.currentState;
    if (form.validate()) {
      form.save();
      setState(() {
        _myActivitiesResult = _myActivities.toString();
      });
    }
  }

  fetchData() async{
    var url = CategorySection;
    var response = await http.get(url);
    if(response.statusCode == 200){
      var items = json.decode(response.body);
      print(items);
      setState(() {
        _myActivities = items;
      });
    } else {
      setState(() {
        _myActivities = [];
      });
    }
  }

  @override
  Widget build(BuildContext context) {

    final double maxWidth = MediaQuery.of(context).size.width;
    final double maxHeight = MediaQuery.of(context).size.height;

    return Scaffold(
      appBar: AppBar(
        title: Text('MultiSelect Formfield Example'),
      ),
      body: Center(
        child: Form(
          key: formKey,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Container(
                height: maxHeight/2,
                width: maxWidth,
                padding: EdgeInsets.all(16),
                child: getListView(),
              ),
              Container(
                padding: EdgeInsets.all(8),
                child: RaisedButton(
                  child: Text('Save'),
                  onPressed: _saveForm,
                ),
              ),
              Container(
                padding: EdgeInsets.all(16),
                child: Text(_myActivitiesResult),
              )
            ],
          ),
        ),
      ),
    );
  }

  Widget getListView() {
    return ListView.builder(
        itemCount: _myActivities.length,
        itemBuilder: (context, index){
          return cardView(_myActivities[index]);
        },
    );
  }

  Widget cardView(item) {

    var fullName = item;

    return MultiSelectDialogField(
      items: _myActivities,
      title: Text("Animals"),
      selectedColor: Colors.blue,
      decoration: BoxDecoration(
        color: Colors.blue.withOpacity(0.1),
        borderRadius: BorderRadius.all(Radius.circular(40)),
        border: Border.all(
          color: Colors.blue,
          width: 2,
        ),
      ),
      buttonIcon: Icon(
        Icons.pets,
        color: Colors.blue,
      ),
      buttonText: Text(
        "Favorite Animals",
        style: TextStyle(
          color: Colors.blue[800],
          fontSize: 16,
        ),
      ),
      onConfirm: (results) {
        _myActivities = results;
      },
    );
  }
}
android ios flutter dart flutter-dependencies
2个回答
0
投票

FilterChip
类提供了多选芯片。使用
FutureBuilder
我们可以获取 future 数据并构建芯片列表。我们也可以先调用API,然后将结果与过滤芯片进行映射

这是

FilterChip
的示例,其中使用
FutureBuilder
从 API 填充芯片:

import 'dart:convert';

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FilterChip Sample',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'FilterChip Sample'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool favorite = false;
  final List<int> _filters = <int>[];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: <Widget>[
            FutureBuilder<List<Album>>(
              future: _fetchAlbums(),
              builder:
                  (BuildContext context, AsyncSnapshot<List<Album>> snapshot) {
                Widget result;
                if (snapshot.hasData) {
                  result = Wrap(
                    spacing: 5.0,
                    children: snapshot.data!.map((Album album) {
                      return FilterChip(
                        label: Text(album.title),
                        selected: _filters.contains(album.id),
                        onSelected: (bool value) {
                          setState(() {
                            if (value) {
                              if (!_filters.contains(album.id)) {
                                _filters.add(album.id);
                              }
                            } else {
                              _filters.removeWhere((int id) {
                                return id == album.id;
                              });
                            }
                          });
                        },
                      );
                    }).toList(),
                  );
                } else if (snapshot.hasError) {
                  result = Text('Error: ${snapshot.error}');
                } else {
                  result = const Text('Awaiting result...');
                }
                return result;
              },
            ),
          ],
        ),
      ),
    );
  }

  Future<List<Album>>? _fetchAlbums() async {
    final response = await http
        .get(Uri.parse('https://jsonplaceholder.typicode.com/albums/'));

    if (response.statusCode == 200) {
      var json = jsonDecode(response.body);
      var albums = List<Album>.from(json.map((i) => Album.fromJson(i)));
      return albums;
    } else {
      throw Exception('Failed to get albums');
    }
  }
}

0
投票

您可以使用具有所需返回类型的

Future
函数,在这种情况下它将是
Future<List<MultiSelectItem>>
,然后您将使用
async
await
,它将是这样的:

Future<List<Item>> fetchItems(BuildContext context) async {
  http.Response response = await http.get(
      Uri.parse('your link for ur api'),
      //you can ignore that part
      headers: <String, String>{
        'Authorization':
            'Token ${Provider.of<Token>(context, listen: false).token}'
      });
//here you turn the json to a <String, dynamic> map
  var data = jsonDecode(response.body);
  List<Item> result = [];
  for (var item in data) {
    //use your factory if you wanna to parse the data the way you want it
    result.add(Item.fromJson(item));
  }
//that should be your disered list
  return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.