dart 如何在应用程序启动时运行Provider方法?

8qgya5xd  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(88)

我正在构建一个应用程序,从一个流行的动漫网站流动漫。但是,我想在应用程序启动时运行一定的Provider方法。一旦应用程序加载,我想从API获取一些动漫,在用户点击“搜索”选项卡之前。
我想指出这个解决方案对我不起作用:How to call method at App start if I am using provider?
这是我的应用程序的外观:x1c 0d1x


我的代码:

main.dart

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

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

class AnimeGO extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Anime()..addAnimeList(),
      child: MaterialApp(
        theme: ThemeData(
          primaryColor: Colors.blueGrey[800],
        ),
        title: 'title'.tr(),
        localizationsDelegates: context.localizationDelegates,
        supportedLocales: context.supportedLocales,
        locale: context.locale,
        home: HomeScreen(),
      ),
    );
  }
}

字符串

providers/anime.dart

import 'package:anime_go/services/anime_twist.dart';
import 'package:flutter/cupertino.dart';

class Anime extends ChangeNotifier {
  var allAnimeList;
  final AnimeTwistApiService api = AnimeTwistApiService();

  void addAnimeList() async {
    allAnimeList = await api.getAllAnime();
    notifyListeners();
  }
}

pages/tabs/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 allAnimeList = context.watch<Anime>().allAnimeList;
    return Center(
      child: Column(
        children: <Widget>[
          for (var i = 0; i < allAnimeList.length; i++)
            Text(allAnimeList[i].title.toString())
        ],
      ),
    );
  }
}

pages/home.dart

import 'package:anime_go/pages/tabs/home.dart';
import 'package:anime_go/pages/tabs/search.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;

  final List<Widget> _children = <Widget>[
    HomeTab(),
    SearchTab(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey[700],
      appBar: AppBar(
        title: Text('title').tr(),
      ),
      body: _children[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
          backgroundColor: Colors.blueGrey[800],
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              title: Text('home').tr(),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search),
              title: Text('search').tr(),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.settings),
              title: Text('settings').tr(),
            )
          ],
          currentIndex: _selectedIndex,
          selectedItemColor: Colors.white,
          unselectedItemColor: Colors.grey,
          onTap: _onItemTapped),
    );
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
}

lb3vh1jj

lb3vh1jj1#

ChangeNotifier类中,添加一个init()方法,该方法将在提供程序示例化时运行:

class Anime extends ChangeNotifier {
    Anime() {
        init();
    }
    var allAnimeList;
    final AnimeTwistApiService api = AnimeTwistApiService();

    void init() async {
        allAnimeList = await api.getAllAnime();
        notifyListeners();
    }
}

字符串
然后,在主构建方法中,将提供程序的lazy属性设置为false

return ChangeNotifierProvider(
          create: (_) => Anime(), 
          lazy: false,
          child: MaterialApp(


这样,您的提供程序的init方法将在第一次遇到时、应用程序启动时运行,而不是在第一次需要时运行。

sy5wg1nm

sy5wg1nm2#

如果您希望在应用程序启动或导航到其他屏幕时自动调用任何方法,请使用以下技术:

Widget build(BuildContext context) {
  return MultiProvider(
    providers: [
      ChangeNotifierProvider<ThemeProvider>(
          create: (context) => ThemeProvider()..getThemeFromSP()),
    ],
    child: MaterialApp(),
  );
}

字符串
您可以在MultiProvider()小部件中观察到这一点。我正在创建ThemeProvider()的示例,并通过使用级联运算符..,调用getThemeFromSP()方法。这种方法允许您在应用程序启动或导航到任何屏幕时调用任何方法。它将与StatefulWidget中的init()方法一样工作。

xuo3flqw

xuo3flqw3#

在主屏幕内调用Provider

var allAnimeList

  final List<Widget> _children = <Widget>[
    HomeTab(),
    SearchTab(allAnimeList),
  ];

 @override
  Widget build(BuildContext context) {
   allAnimeList = context.watch<Anime>().allAnimeList;
    return Scaffold(
      backgroundColor: Colors.blueGrey[700],
      appBar: AppBar(
        title: Text('title').tr(),
      ),
      // Rest code

字符串

相关问题