Flutter

Provider 사용하기.

Michelle Hwang 2021. 5. 8. 14:19

pub.dev/packages/provider

 

provider | Flutter Package

A wrapper around InheritedWidget to make them easier to use and more reusable.

pub.dev

 

내가 만든 영화정보를 가져오고 글자로 검색하는 테스트 앱이 있다. 화면은 다음과 같다. 

꾸미지 않고 정보만 나열한 디테일 페이지도 가지고 있다. 

영화정보 / 검색시 / 디테일 페이지

소스 페이지는 다음과 같다.

github.com/Michellehwang001/findMovie

 

Michellehwang001/findMovie

영화 정보 보여주는 앱. Contribute to Michellehwang001/findMovie development by creating an account on GitHub.

github.com

 

이것을 Provider 를 사용해서 로직과 데이터를 분리해 보자. 

1. 데이터를 가진 Object . class 만들기. 

* MovieProvider 는 ChangeNotifier를 사용할 수 있다.

with 키워드를 사용하면 상속하지 않고 다른 클래스의 기능을 가져오거나 오버라이드 할 수 있고, 이러한 기능을 mixin믹스인이라고 합니다. 이제 MovieProvider는 ChangeNotifier클래스의 기능을 가지고 있습니다. 

import 'package:find_movie/widget/movies.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class MovieProvider with ChangeNotifier{
  // 필요한 movie정보를 담은 Movies
  Movies _movies;
  // 데이터를 받아왔는지 체크. 
  bool _isDone = false;

  // getter
  Movies get movies => _movies;
  bool get isDone => _isDone;

  // Movie 정보를 가져온다. 
  Future<Movies> _fetchData() async {
    var uri = Uri.parse(
        'https://api.themoviedb.org/3/movie/upcoming?api_key=a64533e7ece6c72731da47c9c8bc691f&language=ko-KR&page=1');
    var response = await http.post(uri);
    Movies movies = Movies.fromJson(json.decode(response.body));
    return movies;
  }

  // _fetchData를 실행하고, 데이터를 받아 넣어준다. 
  void fetchData() {
    _fetchData().then((movies) {
      _movies = movies;
      _isDone = true;
      notifyListeners();
    });
  }

}

2. Provider 생성 - 난 MultiProvider를 만들었다. 

데이터가 필요한 클래스 위에 Provider를 생성해야 한다. 난 MyApp에 생성했다. 

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => MovieProvider()),
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: FindMovie(),
      ),
    );
  }
}

MultiProvider에 위에서 생성한 MovieProvider() 를 꽂아준다.!

 

 

3. initState에서 데이터 실행. 

먼저 첫 화면에 데이터를 받아와야 하므로 initState() 에서 fetchData() 를 실행합니다. 

두가지 방법이 있는데, 둘다 데이터를 받아오는데 무리가 없었다. 어떤 차이인지 정확히 알수 없으나. listen:false 속성을 줄 수 있는 방법을 사용하고, 나머지는 주석처리 했다.  listen:false를 사용하면 데이터가 변했을 때 여기에 알려주지 않는다. 한번만 실행하고 계속 알림을 받을 이유가 없으므로 listen:false 하였습니다. 

  void initState() {
    super.initState();
    //context.read<MovieProvider>().fetchData();
    Provider.of<MovieProvider>(context, listen: false).fetchData();
  }

 

4. Provider 제공 데이터 사용

    //Provider를 제공받는다.
    MovieProvider movieProvider = Provider.of<MovieProvider>(context);
    if(movieProvider.isDone == true) {
      movies = movieProvider.movies.results;
    }

 이제 moves를 이용해 데이터를 원하는 곳에 넣어주자~

'Flutter' 카테고리의 다른 글

Positioned / Positioned.fill  (0) 2021.05.25
[Error] Vertical viewport was given unbounded height  (0) 2021.05.20
WebView_flutter 플러그인  (0) 2021.05.03
Elevated button 모서리 둥글게  (0) 2021.04.16
Widgets  (0) 2021.03.22