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

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

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

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Dart

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

Q&A

解決済

2回答

1460閲覧

一般的な検索機能 - QueryとDatabaseを紐付けたい

SuperJulior

総合スコア12

Flutter

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Dart

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

0グッド

0クリップ

投稿2020/07/06 14:52

編集2020/07/06 14:54

検索でDatabase内の言葉を検索対象にしたい

Flutter/Dartで辞書アプリを作っています。
こちらのソースコード(https://blog.usejournal.com/flutter-search-in-listview-1ffa40956685)を元に検索機能を追加していたのですが、queryを元にDatabaseから検索結果を割り出す作業がうまくいきません。
イメージ説明

問題のソースコード

Dart

1import 'package:flutter/material.dart'; 2import 'package:provider/provider.dart'; 3 4import 'package:dictionary/Services/database.dart'; 5import 'package:dictionary/Models/verbs_data.dart'; 6 7import 'words_list.dart'; 8import 'package:dictionary/MainTabs/Search/search_appbar_button.dart'; 9 10class Search extends StatefulWidget { 11 Search({Key key}) : super(key: key); 12 13 14 _Search createState() => new _Search(); 15} 16 17class _Search extends State<Search> { 18 TextEditingController editingController = TextEditingController(); 19 20 final duplicateItems = List<VerbsData>(); 21 final items = List<VerbsData>(); 22 final VerbsData verbsData; 23 24 _Search({this.verbsData}); 25 26 27 void initState() { 28 items.addAll(duplicateItems); 29 super.initState(); 30 } 31 32 void filterSearchResults(String query) { 33 List<VerbsData> dummySearchList = List<VerbsData>(); 34 dummySearchList.addAll(duplicateItems); 35 if (query.isNotEmpty) { 36 List<VerbsData> dummyListData = List<VerbsData>(); 37 dummySearchList.forEach((item) { 38 if (verbsData.romaji.contains(query)) { 39 dummyListData.add(item); 40 } 41 }); 42 setState(() { 43 items.clear(); 44 items.addAll(dummyListData); 45 }); 46 return; 47 } else { 48 setState(() { 49 items.clear(); 50 items.addAll(duplicateItems); 51 }); 52 } 53 } 54 55 56 Widget build(BuildContext context) { 57 return StreamProvider<List<VerbsData>>.value( 58 value: DatabaseService().verbs, 59 child: Scaffold( 60 appBar: AppBar( 61 leading: ButtonOnAppBar(), 62 title: Padding( 63 padding: const EdgeInsets.symmetric(vertical: 4.0), 64 child: TextField( 65 onChanged: (value) { 66 filterSearchResults(value); 67 }, 68 controller: editingController, 69 decoration: InputDecoration( 70 labelText: "Search", 71 fillColor: Colors.white, 72 filled: true, 73 prefixIcon: Icon(Icons.search), 74 border: OutlineInputBorder( 75 borderRadius: BorderRadius.all(Radius.circular(25.0)))), 76 ), 77 ), 78 ), 79 body: SingleChildScrollView( 80 child: Column( 81 crossAxisAlignment: CrossAxisAlignment.start, 82 children: <Widget>[DropdownForSorts(), WordsList()], 83 ), 84 ), 85 ), 86 ); 87 } 88}

関連ソースコード

verbs_data.dart

Dart

1class VerbsData { 2 final String main_word; 3 final int difficulty; 4 final int frequency; 5 final String en_meaning; 6 final String romaji; 7 final String furigana; 8 final String infinitive; 9 10 VerbsData( 11 {this.main_word, 12 this.difficulty, 13 this.frequency, 14 this.en_meaning, 15 this.romaji, 16 this.furigana, 17 this.infinitive,}); 18}

database.dart

Dart

1import 'package:cloud_firestore/cloud_firestore.dart'; 2import 'package:dictionary/Models/verbs_data.dart'; 3 4class DatabaseService { 5 final CollectionReference verbCollection = 6 Firestore.instance.collection('verbs'); 7 8 9 List<VerbsData> _verbsDataFromSnapshot(QuerySnapshot snapshot) { 10 return snapshot.documents.map((doc) { 11 return VerbsData( 12 main_word: doc.data['main_word'] ?? 'xx', 13 difficulty: doc.data['difficulty'] ?? 0, 14 frequency: doc.data['frequency'] ?? 0, 15 en_meaning: doc.data['en_meaning'] ?? 'xx', 16 romaji: doc.data['romaji'] ?? 'xx', 17 furigana: doc.data['furigana'] ?? 'xx', 18 infinitive: doc.data['infinitive'] ?? 'xx', 19 ); 20 }).toList(); 21 }

words_list.dart

Dart

1import 'package:dictionary/Models/singleton.dart'; 2import 'package:dictionary/Models/verbs_data.dart'; 3 4import 'package:provider/provider.dart'; 5import 'package:flutter/material.dart'; 6import 'package:dictionary/MainTabs/Search/Words/main_word_page.dart'; 7 8class WordsList extends StatefulWidget { 9 10 _WordsListState createState() => _WordsListState(); 11} 12 13class _WordsListState extends State<WordsList> { 14 15 Widget build(BuildContext context) { 16 final verbs = Provider.of<List<VerbsData>>(context); 17 18 return ListView.builder( 19 shrinkWrap: true, 20 itemCount: verbs?.length ?? 0, 21 itemBuilder: (context, index) { 22 return WordsTile(verbsData: verbs[index]); 23 }, 24 ); 25 } 26} 27 28class WordsTile extends StatelessWidget { 29 final VerbsData verbsData; 30 31 WordsTile({this.verbsData}); 32 33 34 Widget build(BuildContext context) { 35 return ListTile( 36 title: RichText( 37 text: TextSpan( 38 style: DefaultTextStyle.of(context).style, 39 children: <TextSpan>[ 40 TextSpan( 41 text: ('${verbsData.main_word}'), 42 style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0), 43 ), 44 TextSpan( 45 text: (' ${verbsData.romaji}'), 46 style: TextStyle( 47 fontWeight: FontWeight.w400, 48 fontSize: 20.0, 49 fontStyle: FontStyle.italic)), 50 TextSpan( 51 text: (' ${verbsData.en_meaning}'), 52 style: TextStyle(fontWeight: FontWeight.w400, fontSize: 20.0)) 53 ]), 54 ), 55 onTap: () { 56 Verb verb = Verb.getInstance(); 57 verb.verb = verbsData; 58 59 Navigator.push( 60 context, 61 MaterialPageRoute( 62 builder: (context) => MainWordPage(), 63 ), 64 ); 65 }, 66 ); 67 } 68} 69

試したこと

「問題のソースコード」にある

final duplicateItems = List<VerbsData>(); final items = List<VerbsData>(); final VerbsData verbsData;

を、words_list.dartのようにProviderを使用してみましたが(下記)

final duplicateItems = Provider.of<List<VerbsData>>(context); final items = Provider.of<List<VerbsData>>(context); final VerbsData verbsData;

この変数宣言がBuildContext外にあるので、(context) の部分で "static members can be accessed in initializers" とエラーが出ます。そもそもstatic memberとは具体的にどのようなものなのか、よくわかりません。

補足情報

Android Studioにて開発中。
プログラミング自体初学者ですので、矛盾等あるかもしれません。細かいところまでご指摘いただけるとありがたいです。よろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

動作させてみた結果を、別途回答します。

前回答のコードは以下の原因で、期待通りに動作していなかったです。

  • StatefulWidgetの中で、StreamProviderを使用している

 → setState()を呼ぶとStreamProviderがリビルド後、StreamProviderchildもリビルドされていました

  • filterSearchResultsメソッドが間違っている?

 → if (verbsData.romaji.contains(query))if (item.romaji.contains(query)) だと思われる
(※仕様が分からないため、verbsDataの用途が私には不明でした)

これらのことから下記のコードのように、
StreamProviderSearchの外側へ移動してみました。
ただ、Stream であるDatabaseService().verbsから流れてくるデータを
リストに追加していく仕様であれば、データを溜める仕組みが別途必要ですね....????


importは適宜補完してください
※提示されていない Widget はコメントアウトしています

Searchを使用する箇所

dart

1StreamProvider<List<VerbsData>>.value( 2 value: DatabaseService().verbs, 3 child: Builder(builder: (context) { 4 final verbs = context.watch<List<VerbsData>>(); 5 return Search(key: ValueKey(verbs) , verbs: verbs); 6 }), 7)

Search クラス

dart

1class Search extends StatefulWidget { 2 Search({Key key, this.verbs}) : super(key: key); 3 4 final List<VerbsData> verbs; 5 6 7 _Search createState() => new _Search(); 8} 9 10class _Search extends State<Search> { 11 TextEditingController editingController = TextEditingController(); 12 13 final items = List<VerbsData>(); 14 15 16 void initState() { 17 items.addAll(widget.verbs ?? []); 18 super.initState(); 19 } 20 21 void filterSearchResults(String query) { 22 List<VerbsData> dummySearchList = List<VerbsData>(); 23 dummySearchList.addAll(widget.verbs); 24 if (query.isNotEmpty) { 25 List<VerbsData> dummyListData = List<VerbsData>(); 26 dummySearchList.forEach((item) { 27 if (item.romaji.contains(query)) { 28 dummyListData.add(item); 29 } 30 }); 31 setState(() { 32 items.clear(); 33 items.addAll(dummyListData); 34 }); 35 return; 36 } else { 37 setState(() { 38 items.clear(); 39 items.addAll(widget.verbs); 40 }); 41 } 42 } 43 44 45 Widget build(BuildContext context) { 46 return Scaffold( 47 appBar: AppBar( 48 // leading: ButtonOnAppBar(), 49 title: Padding( 50 padding: const EdgeInsets.symmetric(vertical: 4.0), 51 child: TextField( 52 onChanged: (value) { 53 filterSearchResults(value); 54 }, 55 controller: editingController, 56 decoration: InputDecoration( 57 labelText: "Search", 58 fillColor: Colors.white, 59 filled: true, 60 prefixIcon: Icon(Icons.search), 61 border: OutlineInputBorder( 62 borderRadius: BorderRadius.all(Radius.circular(25.0)))), 63 ), 64 ), 65 ), 66 body: SingleChildScrollView( 67 child: Column( 68 crossAxisAlignment: CrossAxisAlignment.start, 69 children: <Widget>[ 70 // DropdownForSorts(), 71 WordsList(verbs: items), 72 ], 73 ), 74 ), 75 ); 76 } 77}

WordsList クラス
(理由がなければ、StatelessWidgetでよいと思います)

dart

1class WordsList extends StatelessWidget { 2 final List<VerbsData> verbs; 3 4 const WordsList({Key key, this.verbs}) : super(key: key); 5 6 7 Widget build(BuildContext context) { 8 return ListView.builder( 9 shrinkWrap: true, 10 itemCount: verbs?.length ?? 0, 11 itemBuilder: (context, index) { 12 return WordsTile(verbsData: verbs[index]); 13 }, 14 ); 15 } 16}

投稿2020/07/14 02:02

編集2020/07/14 02:09
satokei

総合スコア1217

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

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

SuperJulior

2020/07/18 15:32

お返事したつもりが出来ていませんでした。遅くなり申し訳ございません。 何度もご回答ありがとうございます。「データを溜める仕組み」とはどのようなものですか?
satokei

2020/07/20 00:52

> 「データを溜める仕組み」とはどのようなものですか? 別途用意したList型の変数に溜めることをイメージしていました。
SuperJulior

2020/07/22 03:38

わかりました。たくさん教えていただいたことを元に、頑張ってみます。ありがとうございました。
guest

0

動作させられないため、的外れかもしれませんが、
Builderを利用してduplicateItemsitemsに設定したらどうですかね....????

(コード修正しました)

_Searchクラス

dart

1 2 Widget build(BuildContext context) { 3 return StreamProvider<List<VerbsData>>.value( 4 value: DatabaseService().verbs, 5 child: Scaffold( 6 appBar: AppBar( 7 leading: ButtonOnAppBar(), 8 title: Padding( 9 padding: const EdgeInsets.symmetric(vertical: 4.0), 10 11 // Builderを利用 12 child: Builder(builder: (context) { 13 final verbs = Provider.of<List<VerbsData>>(context); 14 duplicateItems.addAll(verbs); 15 items.addAll(verbs); 16 17 return TextField( 18 onChanged: (value) { 19 filterSearchResults(value); 20 }, 21 controller: editingController, 22 decoration: InputDecoration( 23 labelText: "Search", 24 fillColor: Colors.white, 25 filled: true, 26 prefixIcon: Icon(Icons.search), 27 border: OutlineInputBorder( 28 borderRadius: BorderRadius.all(Radius.circular(25.0)))), 29 ); 30 }), 31 ), 32 ), 33 body: SingleChildScrollView( 34 child: Column( 35 crossAxisAlignment: CrossAxisAlignment.start, 36 children: <Widget>[DropdownForSorts(), WordsList(verbs: items)], 37 ), 38 ), 39 ), 40 ); 41 }

WordsListクラス

dart

1class WordsList extends StatefulWidget { 2 final List<VerbsData> verbs; 3 4 const WordsList({Key key, this.verbs}) : super(key: key); 5 6 7 _WordsListState createState() => _WordsListState(); 8} 9 10class _WordsListState extends State<WordsList> { 11 12 Widget build(BuildContext context) { 13 final verbs = widget.verbs; 14 15 return ListView.builder( 16 shrinkWrap: true, 17 itemCount: verbs?.length ?? 0, 18 itemBuilder: (context, index) { 19 return WordsTile(verbsData: verbs[index]); 20 }, 21 ); 22 } 23}

投稿2020/07/07 15:02

編集2020/07/12 03:16
satokei

総合スコア1217

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

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

SuperJulior

2020/07/09 17:40

迅速なご回答ありがとうございます。ただ今度は下記のようなエラーが表示されるようになりました。。。 W/IInputConnectionWrapper(23987): getSelectedText on inactive InputConnection W/IInputConnectionWrapper(23987): getTextAfterCursor on inactive InputConnection W/IInputConnectionWrapper(23987): getTextBeforeCursor on inactive InputConnection W/IInputConnectionWrapper(23987): getSelectedText on inactive InputConnection W/IInputConnectionWrapper(23987): getTextAfterCursor on inactive InputConnection W/IInputConnectionWrapper(23987): beginBatchEdit on inactive InputConnection W/IInputConnectionWrapper(23987): getTextBeforeCursor on inactive InputConnection W/IInputConnectionWrapper(23987): endBatchEdit on inactive InputConnection I/.dictionary.ap(23987): Background concurrent copying GC freed 23310(1114KB) AllocSpace objects, 2(104KB) LOS objects, 49% free, 2620KB/5241KB, paused 645us total 276.508ms V/NativeCrypto(23987): Read error: ssl=0xdee50618: I/O error during system call, Connection reset by peer V/NativeCrypto(23987): Write error: ssl=0xdee50618: I/O error during system call, Broken pipe V/NativeCrypto(23987): SSL shutdown failed: ssl=0xdee50618: I/O error during system call, Success W/.dictionary.ap(23987): Accessing hidden method Ldalvik/system/CloseGuard;->close()V (greylist,core-platform-api, linking, allowed) TextFieldを使うとよく出るエラーのようで、キーボードを閉じるとちゃんと動くようにおっしゃってる方もいるのですが、私の場合ですと何も変わりません。検索は引っかからないままです。何かご存知でしょうか?
satokei

2020/07/10 11:20

_WordsListState で「Provider.of<List<VerbsData>>(context)」を使用せずに、 WordsList へ items を渡すようにしてみてはどうでしょう。(以下参照) _WordsListState では、「widget.verbs」で参照できます。 ------------------------- class WordsTile extends StatefulWidget { final List<VerbsData> verbs; const WordsTile({Key key, this.verbs}) : super(key: key); @override _WordsListState createState() => _WordsListState(); }
SuperJulior

2020/07/11 16:51

ご回答ありがとうございます。 class WordsList extends StatefulWidget { final List<VerbsData> verbs; const WordsList({Key key, this.verbs}) : super(key: key); @override _WordsListState createState() => _WordsListState(); } class _WordsListState extends State<WordsList> { @override Widget build(BuildContext context) { final verbs = Provider.of<List<VerbsData>>(context); return ListView.builder( ... このような感じになりましたが、大丈夫でしょうか?ちなみに、まだ下記のエラーが出ます。 W/IInputConnectionWrapper(23987): endBatchEdit on inactive InputConnection W/IInputConnectionWrapper(23987): getSelectedText on inactive InputConnection W/IInputConnectionWrapper(23987): getTextAfterCursor on inactive InputConnection 質問記事にありますリンクのコードを写して、List<String>の部分をdatabaseに連携するだけでできそうなのですが、どのように変更すればいいのかわかりません。。。
satokei

2020/07/12 03:04

(私のコードはクラス名を間違えていました。失礼いたしました。) あと _WordsListState クラスでは、以下のようにしてみてください。 ------------------------- final verbs = Provider.of<List<VerbsData>>(context);  ↓ final verbs = widget.verbs; -------------------------
satokei

2020/07/12 03:16

回答のコードを修正しました。
SuperJulior

2020/07/12 08:01

何度もご回答ありがとうございます。 指定された部分を変更すると、Databaseの文字リスト自体が表示されなくなりました。やはりProviderを通してでないとDatabaseは使えないのでしょうか?
satokei

2020/07/12 09:57

最初の回答で提示した「Builder」は使用していますか? 回答のコードの通りにしてみてください。
SuperJulior

2020/07/13 14:17

WordsList(verbs: items)になっていませんでした。すみません。 リストの言葉は表示されるようになりましたが、下記の新たなエラーが表示されました。 I/flutter (23987): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter (23987): The following NoSuchMethodError was thrown building Builder(dirty, dependencies: I/flutter (23987): [InheritedProvider<List<VerbsData>>]): I/flutter (23987): The getter 'iterator' was called on null. I/flutter (23987): Receiver: null I/flutter (23987): Tried calling: iterator I/flutter (23987): I/flutter (23987): User-created ancestor of the error-causing widget was: I/flutter (23987): AppBar file:///dictionary_hands_on_hinagata-master%202/lib/MainTabs/Search/search.dart:60:17 I/flutter (23987): I/flutter (23987): When the exception was thrown, this was the stack: I/flutter (23987): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5) I/flutter (23987): #1 List.addAll (dart:core-patch/growable_array.dart:195:28) I/flutter (23987): #2 _Search.build.<anonymous closure> (package:dictionary/MainTabs/Search/search.dart:64:28) I/flutter (23987): #3 Builder.build (package:flutter/src/widgets/basic.dart:6660:41) I/flutter (23987): #4 StatelessElement.build (package:flutter/src/widgets/framework.dart:4009:28) ...と、同じような内容で長く連なっています。 読んでみて疑問に思ったことは、 ・iteratorを要求している?(Iteratorの記事を読んでみましたが、さっぱりわかりませんでした。) ・AppBar近辺で問題が起こっている? ちなみに、この部分では最初Paddingと出ていたので、追加したBuilderのすぐ上のPaddingをTextFieldの方にずらしたら、エラー表示がAppBarに変わりました。 長々と親切に対応していただき、感謝でいっぱいです。ダラダラとわからないことだらけなポンコツで本当に申し訳ありません。。。。。。
satokei

2020/07/14 01:29

items が null の場合があるからですね。 こちらでも動作させてみたので、別の回答をあげます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問