Flutter Cubit 获取和显示数据

Flutter Cubit fetching and displaying data

我正在尝试从 Genshin API 获取数据,下面的代码有效,但只是有延迟(在 GenshinCubit class 中),它看起来很旧,因为不知道要延迟多少时间。我认为,代码中存在问题,导致它不能在 loadedList 完成之前设置 GenshinLoaded 状态。现在,如果我删除延迟,它只会在列表仍在工作且未完成时设置 GenshinLoaded,等待没有帮助。因此,我得到了一个白屏,需要热重载才能显示我的列表。

class Repository {
  final String characters = 'https://api.genshin.dev/characters/';


  Future<List<Character>> getCharactersList() async {
    List<Character> charactersList = [];
    List<String> links = [];
    final response = await http.get(Uri.parse(characters));```

    List<dynamic> json = jsonDecode(response.body);
    json.forEach((element) {
      links.add('$characters$element');
    });
    links.forEach((element) async {
      final response2 = await http.get(Uri.parse(element));

        dynamic json2 = jsonDecode(response2.body);

        charactersList.add(Character.fromJson(json2));

    });
    return charactersList;

  }
}

class GenshinCubit extends Cubit<GenshinState> {
  final Repository repository;
  GenshinCubit(this.repository) : super(GenshinInitial(),);

  getCharacters() async {
    try {
      emit(GenshinLoading());
      List<Character> list = await repository.getCharactersList();
      await Future<void>.delayed(const Duration(milliseconds: 1000));
      emit(GenshinLoaded(loadedList: list));
    }catch (e) {
      print(e);
      emit(GenshinError());
    }
  }
}

class HomeScreen extends StatelessWidget {
  final userRepository = Repository();

  HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider<GenshinCubit>(
      create: (context) => GenshinCubit(userRepository)..getCharacters(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(body: Container(child: const CharactersScreen())),
      ),
    );
  }
}

class CharactersScreen extends StatefulWidget {
  const CharactersScreen({
    Key? key,
  }) : super(key: key);

  @override
  State<CharactersScreen> createState() => _CharactersScreenState();
}

class _CharactersScreenState extends State<CharactersScreen> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        BlocBuilder<GenshinCubit, GenshinState>(
            builder: (context, state) {
          if (state is GenshinLoading) {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
          if (state is GenshinLoaded) {
            return SafeArea(
              top: false,
              child: Column(
                children: [
                  Container(
                    color: Colors.black,
                    height: MediaQuery.of(context).size.height,
                    child: ListView.builder(
                        scrollDirection: Axis.horizontal,
                        shrinkWrap: true,
                        itemCount: state.loadedList.length,
                        itemBuilder: ((context, index) {
                          return Padding(
                            padding: const EdgeInsets.symmetric(
                                vertical: 50.0, horizontal: 50),
                            child: GestureDetector(
                              onTap: () => Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) => CharacterDetailsPage(
                                    character: state.loadedList[index],
                                  ),
                                ),
                              ),
                              child: Container(
                                height: MediaQuery.of(context).size.height,
                                width: MediaQuery.of(context).size.width,
                                decoration: BoxDecoration(
                                    color: Colors.blueAccent.withOpacity(0.3),
                                    borderRadius: const BorderRadius.all(
                                      Radius.circular(
                                        30,
                                      ),
                                    )),
                                child: Align(
                                  alignment: Alignment.bottomRight,
                                  child: Padding(
                                    padding: const EdgeInsets.only(
                                        right: 30.0, bottom: 30),
                                    child: Column(
                                      mainAxisSize: MainAxisSize.min,
                                      mainAxisAlignment: MainAxisAlignment.end,
                                      children: [
                                        Text(
                                          state.loadedList[index].name
                                              .toString(),
                                          style: TextStyle(
                                              color: Colors.black,
                                              fontSize: 50),
                                        ),
                                        RatingBarIndicator(
                                            itemPadding: EdgeInsets.zero,
                                            rating: double.parse(
                                              state.loadedList[index].rarity
                                                  .toString(),
                                            ),
                                            itemCount: int.parse(
                                              state.loadedList[index].rarity
                                                  .toString(),
                                            ),
                                            itemBuilder: (context, index) =>
                                                Icon(
                                                  Icons.star_rate_rounded,
                                                  color: Colors.amber,
                                                ))
                                      ],
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          );
                        })),
                  ),
                ],
              ),
            );
          }
          if (state is GenshinInitial) {
            return Text('Start');
          }
          if (state is GenshinError) {
            return Text('Error');
          }
          return Text('Meow');
        }),
      ],
    );
  }
}

我找到了解决办法! 由于forEach,我遇到了这个问题。 - 有解决办法。