#目的
このように映画のAPI(TMDB API)を使って、映画を検索できるようにしたいです。
また、どのように実装すれば良いのか良くわからないので、とりあえずこちらを参考にしてChangeNotifierProvider
とConsumer
を使っています。
#発生してるエラー
検索用のTextField
に文字を入れて、検索をかけるとエラーが発生します。。。
参考動画はこちら
console
1flutter: type 'List<dynamic>' is not a subtype of type 'List<Movie>'
このように型のエラーが発生しています。。
#該当のソースコード
※全てのソースは下記にあります。
https://github.com/gentixyann/konomiru-flutter
##検索画面
dart:search_movie_screen.dart
1import 'package:flutter/material.dart'; 2import 'dart:convert'; 3import 'package:http/http.dart' as http; 4import 'package:provider/provider.dart'; 5import '../config.dart'; 6import '../widgets/movie_card.dart'; 7import '../providers/search_movie.dart'; 8import '../providers/movie.dart'; 9 10class SearchMovieScreen extends StatelessWidget { 11 12 13 Widget build(BuildContext context) { 14 final moviesData = Provider.of<SearchMovie>(context); 15 final searchedMovies = moviesData.movies; 16 17 return ChangeNotifierProvider<SearchMovie>( 18 create: (_) => SearchMovie(), 19 child: Consumer<SearchMovie>( 20 builder: (context, model, child) { 21 return Scaffold( 22 body: Container( 23 child: Column( 24 children: <Widget>[ 25 TextField( 26 onChanged: (inputText) { 27 print(inputText); 28 model.text = inputText; 29 model.search(); 30 }, 31 decoration: InputDecoration( 32 prefixIcon: Icon( 33 Icons.search, 34 color: Colors.grey, 35 ), 36 hintText: 'タイトルを入れてね'), 37 ), 38 Expanded( 39 child: ListView.builder( 40 scrollDirection: Axis.vertical, 41 itemCount: model.movies.length, 42 itemBuilder: (BuildContext context, int index) { 43 return Container( 44 padding: EdgeInsets.all(20), 45 child: Column( 46 children: <Widget>[ 47 MovieCard( 48 searchedMovies[index].title, 49 searchedMovies[index].releaseDate, 50 searchedMovies[index].overview, 51 searchedMovies[index].posterPath, 52 ), 53 ], 54 ), 55 ); 56 }), 57 ) 58 ], 59 )), 60 ); 61 }, 62 ), 63 ); 64 } 65}
##型を決めているMovie class
dart:movie.dart
1import 'package:flutter/material.dart'; 2 3class Movie with ChangeNotifier { 4 int voteCount; 5 int id; 6 bool video; 7 num voteAverage; 8 String title; 9 double popularity; 10 String posterPath; 11 String originalLanguage; 12 String originalTitle; 13 String backdropPath; 14 bool adult; 15 String overview; 16 String releaseDate; 17 18 Movie({ 19 this.voteCount, 20 this.id, 21 this.video, 22 this.voteAverage, 23 this.title, 24 this.popularity, 25 this.posterPath, 26 this.originalLanguage, 27 this.originalTitle, 28 this.backdropPath, 29 this.adult, 30 this.overview, 31 this.releaseDate, 32 }); 33 34// 参考にしたコードに書いてあったが、どうやって使うのかわからない。。。 35 static Movie fromJson(Map<String, dynamic> json) { 36 return Movie( 37 voteCount: json['vote_count'], 38 id: json['id'], 39 video: json['video'], 40 voteAverage: json['vote_average'], 41 title: json['title'], 42 popularity: json['popularity'], 43 posterPath: json['poster_path'], 44 originalLanguage: json['original_language'], 45 originalTitle: json['original_title'], 46 backdropPath: json['backdrop_path'], 47 adult: json['adult'], 48 overview: json['overview'], 49 releaseDate: json['release_date'], 50 ); 51 } 52}
##検索した時に値の変更を知らせるSearchMovie class
dart:search_movie.dart
1import 'package:flutter/material.dart'; 2import 'dart:convert'; 3import 'package:http/http.dart' as http; 4import '../config.dart'; 5import './movie.dart'; 6 7class SearchMovie with ChangeNotifier { 8 String text = ''; 9 10 List<Movie> _movies = []; 11 12 List<Movie> get movies { 13 return [..._movies]; 14 } 15 16 search() async { 17 if (this.text.isNotEmpty) { 18 var searchUrl = 19 '${MOVIE_DB_BASE_URL}/search/movie?api_key=${API_KEY}&language=en-US&query=${text}&page=1'; 20 21 try { 22 final response = await http.get(searchUrl); 23 final List<Movie> extractedData = json.decode(response.body)['results']; 24 if (extractedData == null) { 25 print('nothing to get'); 26 return; 27 } 28 29 _movies = extractedData; 30 notifyListeners(); 31 } catch (error) { 32 print(error); 33 throw (error); 34 } 35 } 36 } 37}
#把握している問題点
dart:search_movie.dart
1final List<Movie> extractedData = json.decode(response.body)['results'];
ここでjson.decode
して取得している値が**List<dynamic>
**になっているため、List<Movie>
に代入?できない。
ここを解決すると目指している実装ができるかは定かではないですが、とりあえずjson.decode
した物をどうやって別のclassの型に変換するのかがわからないです。。。
#参考情報
##Movie class作成で参考にしたコード
https://github.com/myotive/flutter_movie_db/blob/master/lib/data/models/search_result.dart
##APIのレスポンスについては
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/04/16 02:14