Home > Net >  How to update UI in Flutter
How to update UI in Flutter

Time:07-26

I'm reading a list from my local Json file and i'm trying to sort the list by either number or alphabet and update the UI depend on user choice.

I'm able to filter the List but not really sure how to update the UI when a user press a either button so I would be really appreciated if I can get any help or suggestion.

Right now, I just called one function in my FutureBuilder and not sure how to modify it.

class _SawnawkScreenState extends State<SawnawkScreen> {
  @override
  Widget build(BuildContext context) {
    bool isSwitched = false;

    return Scaffold(
      body: FutureBuilder(
        future: SortbyNumber(), // Need to do something here
        builder: (context, data) {
          if (data.hasError) {
            return Center(child: Text("${data.error}"));
          } else if (data.hasData) {
            var items = data.data as List<SawnAwkModel>;

            return ListView.builder(
                itemCount: items == null ? 0 : items.length,
                itemBuilder: (context, index) {

                  return SawnawkCardWidget(
                    id: items[index].id!,
                  );
                });

          } else {
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
      floatingActionButton: SpeedDial(
        children: [
          SpeedDialChild(
              child: Icon(Icons.sort_by_alpha_outlined),
              backgroundColor: Colors.white,
              label: 'Sort by alphabet',
              onTap: () => {
                    print('sort by alphabet'),

                    //Do something here
             
                  }),

         SpeedDialChild(
              child: Icon(Icons.sort_by_number),
              backgroundColor: Colors.white,
              label: 'Sort by number',
              onTap: () => {
                    print('sort by number'),

                    //Do something here
             
                  }),
        ],
      ),
    );
  }
}

Future<List<SawnAwkModel>> SortbyNumber() async {
  final jsondata =
      await rootBundle.rootBundle.loadString('assets/data/sawnawk_data.json');
  final list = json.decode(jsondata) as List<dynamic>;

  return list.map((e) => SawnAwkModel.fromJson(e)).toList();
}


Future<List<SawnAwkModel>> SortbyAlphabet() async {
  final jsondata =
      await rootBundle.rootBundle.loadString('assets/data/sawnawk_data.json');
  final list = json.decode(jsondata) as List<dynamic>;

  List<SawnAwkModel> profileList =
      list.map((e) => SawnAwkModel.fromJson(e)).toList();

  profileList.sort((a, b) {
    return a.titleFalam.toLowerCase().compareTo(b.titleFalam.toLowerCase());
  });

  return profileList;
}

CodePudding user response:

In order to update the UI, the code that changes the UI must be in a setState({}) function. In your case, try this:

SpeedDialChild(
  child: Icon(Icons.sort_by_alpha_outlined),
  backgroundColor: Colors.white,
  label: 'Sort by alphabet',
  onTap: () => {
    print('sort by alphabet'),

    setState({
      final sorted = await SortbyAlphabet()
      //update widget contents with sorted value above
    })
        
}),

Your current code if difficult to update the UI, I suggest storing the ListView.builder items in a variable accessible by the function you want to use to update the UI, and change the contents there, like this:

class _SawnawkScreenState extends State<SawnawkScreen> {
    bool isSwitched = false;
    List items = [];
  @override
  Widget build(BuildContext context) {
    
    return Scaffold(
      body: FutureBuilder(
        future: SortbyNumber(), // Need to do something here
        builder: (context, data) {
          if (data.hasError) {
            return Center(child: Text("${data.error}"));
          } else if (data.hasData) {
            items.addAll(data.data as List<SawnAwkModel>);

            return ListView.builder(
                itemCount: items == null ? 0 : items.length,
                itemBuilder: (context, index) {
                  return SawnawkCardWidget(
                    id: items[index].id!,
                  );
                });
          } else {
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
      floatingActionButton: SpeedDial(
        children: [
          SpeedDialChild(
              child: Icon(Icons.sort_by_alpha_outlined),
              backgroundColor: Colors.white,
              label: 'Sort by alphabet',
              onTap: () async {
                    setState({
                      print('sort by alphabet'),
                      final newItems = await SortbyAlphabet();
                      items.clear();
                      items.addAll(newItems);
                    })
                  }),
          SpeedDialChild(
              child: Icon(Icons.sort_by_number),
              backgroundColor: Colors.white,
              label: 'Sort by number',
              onTap: () async {
                   setState({
                      print('sort by number'),
                      final newItems = await SortbyNumber();
                      items.clear();
                      items.addAll(newItems);
                    })
                  }),
        ],
      ),
    );
  }
}

Future<List<SawnAwkModel>> SortbyNumber() async {
  final jsondata =
      await rootBundle.rootBundle.loadString('assets/data/sawnawk_data.json');
  final list = json.decode(jsondata) as List<dynamic>;

  return list.map((e) => SawnAwkModel.fromJson(e)).toList();
}

Future<List<SawnAwkModel>> SortbyAlphabet() async {
  final jsondata =
      await rootBundle.rootBundle.loadString('assets/data/sawnawk_data.json');
  final list = json.decode(jsondata) as List<dynamic>;

  List<SawnAwkModel> profileList =
      list.map((e) => SawnAwkModel.fromJson(e)).toList();

  profileList.sort((a, b) {
    return a.titleFalam.toLowerCase().compareTo(b.titleFalam.toLowerCase());
  });

  return profileList;
}

CodePudding user response:

Please refer to this below code

Please refer to this https://stackoverflow.com/a/70202810/15215450 for example on ValueListenable Builder

final ValueNotifier<List> items = ValueNotifier([]);

floatingActionButton: SpeedDial(
        children: [
          SpeedDialChild(
              child: Icon(Icons.sort_by_alpha_outlined),
              backgroundColor: Colors.white,
              label: 'Sort by alphabet',
              onTap: () => {
                    print('sort by alphabet'),

                    //Do something here
                    items.value.clear();
                    items.value = await SortbyAlphabet();
                    items.notifyListeners();
             
                  }),

         SpeedDialChild(
              child: Icon(Icons.sort_by_number),
              backgroundColor: Colors.white,
              label: 'Sort by number',
              onTap: () => {
                    print('sort by number'),

                    //Do something here
                    items.value.clear();
                    items.value = await SortbyAlphabet();
                    items.notifyListeners();
             
                  }),
        ],
      ),


      ValueListenableBuilder(
            valueListenable: isSwitched,
            builder: (context, snapshot, child) {

            return ListView.builder(
                itemCount: items.value == null ? 0 : items.value.length,
                itemBuilder: (context, index) {

                  return SawnawkCardWidget(
                    id: items.value[index].id!,
                  );
                });

            }));



  • Related