質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

1回答

810閲覧

Flutter type 'List<dynamic>' is not a subtype of type 'List<Movie>'を解決したい

Gento

総合スコア77

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2021/04/07 07:49

編集2021/04/07 12:30

#目的

このように映画のAPI(TMDB API)を使って、映画を検索できるようにしたいです。

また、どのように実装すれば良いのか良くわからないので、とりあえずこちらを参考にしてChangeNotifierProviderConsumerを使っています。

#発生してるエラー
検索用の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のレスポンスについては

https://developers.themoviedb.org/3/search/search-movies

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

JSON にシリアライズすると、Flutterのクラス情報は消えるので、
デシリアライズする場合は直接クラスへ変換できません。

自分で地道にクラスへ変換するロジックを記述するか、
以下のようなライブラリを使用するとよいです。

投稿2021/04/12 16:49

satokei

総合スコア1217

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Gento

2021/04/16 02:14

ありがとうございます! ライブラリの使用を検討してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問