1

What I wanted to do seems easy, but I couldn't figure out how to do it. Data is coming through the API in my listview. What I want to do is sort the data coming to listview alphabetically.

Briefly, I want to sort the data coming from API in listview alphabetically.

This is how I get the data :

Future<List<Word>> getWord() async {
    var response =
        await http.get(Uri.parse('myAPIURL'));
    var _words = List<Word>();
    _words = (json.decode(utf8.decode(response.bodyBytes)) as List)
        .map((singleWordMap) => Word.fromJson(singleWordMap))
        .toList();
    return _words;
  }

My init state here :

void initState() {
    super.initState();
    data = getWord();
    data.then(
      (value) {
        setState(
          () {
            _words.addAll(value);
            _wordsForDisplay = _words;
          },
        );
      },
    );
    }

My future builder here :

FutureBuilder<List<Word>> myFutureBuilder() {
    return FutureBuilder(
      future: data,
      builder: (context, AsyncSnapshot<List<Word>> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(
            child: CircularProgressIndicator(),
          );
        } else {
          return myWordListView();
        }
      },
    );
  }

And my listview :

ListView myWordListView() {
    return ListView.builder(
      itemCount: _wordsForDisplay.length,
      itemBuilder: (context, index) {
        return Dismissible(
          background: Container(
            alignment: Alignment.centerRight,
            padding: EdgeInsets.only(right: 20.0),
            color: Colors.teal,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: Text(
                    'share',
                    style: TextStyle(
                        color: Colors.white, fontWeight: FontWeight.bold),
                  ),
                ),
                Icon(Icons.share_outlined, color: Colors.white),
              ],
            ),
          ),
          secondaryBackground: Container(
            alignment: Alignment.centerRight,
            padding: EdgeInsets.only(right: 20.0),
            color: Colors.teal,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: Text(
                    'favorite',
                    style: TextStyle(
                        color: Colors.white, fontWeight: FontWeight.bold),
                  ),
                ),
                Icon(Icons.favorite_rounded, color: Colors.red),
              ],
            ),
          ),
          direction: DismissDirection.horizontal,
          key: Key(index.toString()),
          confirmDismiss: (direction) async {
            if (direction == DismissDirection.endToStart) {
              _addFavorite(
                Favorites(
                  _wordsForDisplay[index].word,
                  _wordsForDisplay[index].pronunciation,
                  _wordsForDisplay[index].meaning,
                ),
              );
              return false;
            } else {
              Share.share('something');
              return false;
            }
          },
          child: ExpansionTile(
            title: Text(
              _wordsForDisplay[index].word,
              style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16.0),
            ),
            subtitle: Text(
              _wordsForDisplay[index].pronunciation[0].toUpperCase() +
                  _wordsForDisplay[index].pronunciation.substring(1),
            ),
            leading: CircleAvatar(
              child: Text(_wordsForDisplay[index].word[0]),
            ),
            children: [
              Column(
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Container(
                        width: MediaQuery.of(context).size.width,
                        child: Padding(
                          padding: const EdgeInsets.symmetric(
                              vertical: 7.0, horizontal: 19.0),
                          child: RichText(
                            text: TextSpan(
                              style: DefaultTextStyle.of(context).style,
                              children: <TextSpan>[
                                TextSpan(
                                  text: _wordsForDisplay[index].word + ' : ',
                                  style: TextStyle(fontWeight: FontWeight.bold),
                                ),
                                TextSpan(text: _wordsForDisplay[index].meaning),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
        );
      },
    );
  }

My word model :

// To parse this JSON data, do
//
//     final word = wordFromJson(jsonString);

import 'dart:convert';

List<Word> wordFromJson(String str) =>
    List<Word>.from(json.decode(str).map((x) => Word.fromJson(x)));

String wordToJson(List<Word> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Word {
  Word({
    this.word,
    this.pronunciation,
    this.meaning,
  });

  String word;
  String pronunciation;
  String meaning;

  factory Word.fromJson(Map<String, dynamic> json) => Word(
        word: json["word"],
        pronunciation: json["pronunciation"],
        meaning: json["meaning"],
      );

  Map<String, dynamic> toJson() => {
        "word": word,
        "pronunciation": pronunciation,
        "meaning": meaning,
      };
}

2
  • I updated my question. I added the word model. Commented May 9, 2021 at 13:38
  • ya, now it's easier to answer Commented May 9, 2021 at 13:38

2 Answers 2

3

Since it is a list you can make use of the sort() function

Just,sort the list before you use it in the builder.

_wordsForDisplay.sort((a, b) => a.word.compareTo(b.word));

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, that's exactly what I wanted to do, thank you very much.
1

I'm on my phone so I cannot fully write or test code for now.

The fastest way is to do sort the list in the onState method by passing your Comparable: And then

            _words.sort((a,b) => a.word.compareTo(word))

The cleanest one that will let you implement only once the comparator if you need to sort the list elsewhere, in my opinion, is:

  1. Make Word Class implement Comparable.
  2. Override the compareTo method
  3. Sort the list in your onSet method
class Word implement Comparable {
...
@override
int compareTo(Word other) => this.word.compareTo(other.word);

And then

setState(
          () {
            _words.addAll(value);
            _words.sort();
            _wordsForDisplay = _words;
          },
        );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.