Как прослушивать изменения поставщика?

#flutter #dart

#flutter #dart

Вопрос:

Я создаю приложение, которое позволяет пользователю транслировать аниме на свои телефоны. Тем не менее, мне сложно создавать приложение по шаблону поставщика.

Вот что я хочу, чтобы мое приложение выполняло:

  • Я хотел бы получить все аниме с сайта twist.moe,
  • Я хотел бы прослушать все аниме, используя провайдера,
  • Я хотел бы иметь доступ к списку аниме с помощью провайдера.

В файле search.dart ошибка, я не могу получить доступ к заголовку.

Мой код:

провайдеры/anime.dart

 import 'package:anime_go/models/anime_all.dart';
import 'package:anime_go/services/anime_twist.dart';
import 'package:flutter/material.dart';

class AnimeModel extends ChangeNotifier {
  final AnimeTwistApiService api = AnimeTwistApiService();

  final List<List<AnimeAll>> allAnimeList = [];

  void addAnimeList() async {
    final List<AnimeAll> animeList = await api.getAllAnime();

    allAnimeList.add(animeList);
    notifyListeners();
  }
}
  

модели/anime_all.dart

 import 'dart:convert';

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

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

class AnimeAll {
  AnimeAll({
    this.id,
    this.title,
    this.altTitle,
    this.season,
    this.ongoing,
    this.hbId,
    this.createdAt,
    this.updatedAt,
    this.hidden,
    this.malId,
    this.slug,
  });

  int id;
  String title;
  String altTitle;
  int season;
  int ongoing;
  int hbId;
  DateTime createdAt;
  DateTime updatedAt;
  int hidden;
  int malId;
  Slug slug;

  factory AnimeAll.fromJson(Map<String, dynamic> json) => AnimeAll(
        id: json["id"],
        title: json["title"],
        altTitle: json["alt_title"] == null ? null : json["alt_title"],
        season: json["season"],
        ongoing: json["ongoing"],
        hbId: json["hb_id"] == null ? null : json["hb_id"],
        createdAt: DateTime.parse(json["created_at"]),
        updatedAt: DateTime.parse(json["updated_at"]),
        hidden: json["hidden"],
        malId: json["mal_id"] == null ? null : json["mal_id"],
        slug: Slug.fromJson(json["slug"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "title": title,
        "alt_title": altTitle == null ? null : altTitle,
        "season": season,
        "ongoing": ongoing,
        "hb_id": hbId == null ? null : hbId,
        "created_at": createdAt.toIso8601String(),
        "updated_at": updatedAt.toIso8601String(),
        "hidden": hidden,
        "mal_id": malId == null ? null : malId,
        "slug": slug.toJson(),
      };
}

class Slug {
  Slug({
    this.id,
    this.slug,
    this.animeId,
    this.createdAt,
    this.updatedAt,
  });

  int id;
  String slug;
  int animeId;
  DateTime createdAt;
  DateTime updatedAt;

  factory Slug.fromJson(Map<String, dynamic> json) => Slug(
        id: json["id"],
        slug: json["slug"],
        animeId: json["anime_id"],
        createdAt: DateTime.parse(json["created_at"]),
        updatedAt: DateTime.parse(json["updated_at"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "slug": slug,
        "anime_id": animeId,
        "created_at": createdAt.toIso8601String(),
        "updated_at": updatedAt.toIso8601String(),
      };
}
  

сервисы/anime_twist.dart

 import 'package:anime_go/models/anime_all.dart';
import 'package:anime_go/.env.dart';
import 'package:http/http.dart' as http;

class AnimeTwistApiService {
  static const baseUrl = 'https://twist.moe/api/anime';

  Future<List<AnimeAll>> getAllAnime() async {
    final http.Response response = await http
        .get(baseUrl, headers: {'x-access-token': EnvironmentVariables.token});

    return animeAllFromJson(response.body);
  }
}
  

страницы / вкладки /search.dart

 import 'package:anime_go/providers/anime.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class SearchTab extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final animeList = context.watch<AnimeModel>().addAnimeList();
    return Text(animeList.title.toString()); // here's the error, I can't access "title"
  }
}
  

main.dart

 import 'package:anime_go/pages/home.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:anime_go/providers/anime.dart';

void main() {
  runApp(
    EasyLocalization(
        supportedLocales: [Locale('en', 'US')],
        path: 'lib/assets/translations',
        fallbackLocale: Locale('en', 'US'),
        child: AnimeGo()),
  );
}

class AnimeGo extends StatelessWidget {
  final AnimeModel _animeModel = AnimeModel();

  AnimeGo() {
    _animeModel.addAnimeList();
  }

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => AnimeModel(),
        )
      ],
      child: MaterialApp(
        localizationsDelegates: context.localizationDelegates,
        supportedLocales: context.supportedLocales,
        locale: context.locale,
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primaryColor: Colors.blueGrey[800],
        ),
        title: 'title'.tr(),
        home: HomeScreen(),
      ),
    );
  }
}
  

Комментарии:

1. Какую ошибку вы получаете?

2. Я получаю сообщение об ошибке при использовании animelist.title. toString() в pages / tabs /search.dart

3. Хорошо, но что говорит ошибка?

4. «Средство получения ‘title’ не определено для типа ‘AnimeModel’. Попробуйте импортировать библиотеку, которая определяет ‘title’, исправив имя на имя существующего средства получения или определив средство получения или поле с именем ‘title'»

5. Не могли бы вы добавить ту часть ошибки, которая относится к имени файла и номеру строки. Или просто добавьте полный код ошибки в свой вопрос

Ответ №1:

Вы возвращаете объект AnimeModel, который имеет список<Список>.

Название принадлежит AnimeAll. Сначала вам нужно получить к нему доступ внутри возвращаемого объекта следующим образом:

AnimeList[index_1][index_2].title