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

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

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

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

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

Dart

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

Q&A

解決済

1回答

3330閲覧

【flutter】選択されたリストタイルの背景色のみを変更したい

arumazirou

総合スコア1

Flutter

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

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

Dart

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

0グッド

0クリップ

投稿2020/12/18 02:22

編集2020/12/18 02:44

前提・実現したいこと

リストタイルタップしたらBottomSheatでメッセージを表示するリストを作成しています。
タップされる度にリストタイルの背景色を変更する機能を実装したいのですが、画面に表示されているリストタイル全ての背景色が変更されるコードの書き方しか分かりません。
背景色を変更したいのはタップしたリストタイルのみなのですが、良い方法はありませんでしょうか。ご教授いただければ幸いです。

該当のソースコード

flutter

1import 'package:flutter/material.dart'; 2 3void main() { 4 runApp(MyApp()); 5} 6// 日付リストのデータ 7List<String> dateList = []; 8// タイトルリストのデータ 9List<String> titleList = []; 10// テキストリストのデータ 11List<String> textList = []; 12 13String _date; 14String _title; 15String _text; 16 17// リスト背景色変更用 18bool _isColor = false; 19 20class MyApp extends StatelessWidget { 21 @override 22 Widget build(BuildContext context) { 23 return MaterialApp( 24 home: Scaffold(backgroundColor: Color.fromRGBO(242, 203, 5, 1.0), body: MainPage()), 25 ); 26 } 27} 28 29 30// アプリ内容表示部分 31class MainPage extends StatefulWidget { 32 33 @override 34 _MainPageState createState() => _MainPageState(); 35} 36 37class _MainPageState extends State<MainPage> { 38 39 @override 40 Widget build(BuildContext context) { 41 return SingleChildScrollView( 42 child: Column( 43 children: <Widget>[ 44 PageTitle(), 45 TopPagePage(), 46 FloatingActionButton( 47 onPressed: () async { 48 // リスト追加画面から渡される値を受け取る 49 final newListText = await Navigator.of(context).push( 50 MaterialPageRoute(builder: (context) { 51 // 遷移先の画面としてリスト追加画面を指定 52 return TodoAddPage(); 53 }), 54 ); 55 // 再描画 56 setState(() {}); 57 }, 58 child: Icon(Icons.add), 59 ), 60 ], 61 ) 62 ); 63 } 64} 65 66 67// トップタイトル 68Widget PageTitle() { 69 return Container( 70 child: Align( 71 alignment: Alignment.center, 72 child: Container( 73 margin: EdgeInsets.fromLTRB(0, 100, 0, 0), 74 alignment: Alignment.center, 75 child: 76 Text('お知らせ', style: TextStyle(color: Colors.white, fontSize: 20)), 77 width: 320.0, 78 height: 100.0, 79 ), 80 ), 81 ); 82} 83 84class TopPagePage extends StatefulWidget{ 85 @override 86 _TopPageState createState() => _TopPageState(); 87} 88 89class _TopPageState extends State<TopPagePage> { 90 @override 91 Widget build(BuildContext context) { 92 return Column( 93 children: <Widget>[ 94 mainTop(), 95 mainBox(context), 96 mainUnder(), 97 ], 98 ); 99 } 100} 101 102 103// メイントップ 104Widget mainTop() { 105 return Container( 106 width: 320.0, 107 height: 45.0, 108 color: Color.fromRGBO(242, 139, 12, 1.0), 109 child: mainTopBox(), 110 ); 111} 112 113Widget mainTopBox() { 114 return Row( 115 children: <Widget>[ 116 mainTopLeft(), 117 mainTopText(), 118 ], 119 ); 120} 121 122Widget mainTopLeft() { 123 return Container( 124 child: Align( 125 alignment: Alignment.topLeft, 126 child: Container( 127 width: 10.0, 128 height: 45.0, 129 color: Color.fromRGBO(34, 139, 34, 1.0), 130 ), 131 ), 132 ); 133} 134 135Widget mainTopText() { 136 return Container( 137 margin: EdgeInsets.fromLTRB(20, 0, 0, 0), 138 child: Text('リスト', 139 style: TextStyle( 140 color: Colors.white, fontFamily: 'MPLUS1p-Regular', fontSize: 20) 141 ), 142 ); 143} 144 145 146// メインコンテンツ 147Widget mainBox(BuildContext context) { 148 return Container( 149 width: 320.0, 150 height: 380.0, 151 color: Colors.white, 152 child: mainBoxWidget() 153 ); 154} 155 156 157// メインコンテンツカラム 158class mainBoxWidget extends StatefulWidget { 159 @override 160 _mainBoxState createState() => _mainBoxState(); 161} 162 163// ignore: camel_case_types 164class _mainBoxState extends State<mainBoxWidget> { 165 @override 166 Widget build(BuildContext context) { 167 return Column( 168 children: <Widget>[ 169 // Expandedで残りスペースを拡張 170 Expanded( 171 // データを元にListViewを作成 172 child: ListView.builder( 173 itemCount: dateList.length, 174 itemBuilder: (context, index) { 175 return Ink( 176 child: Card( 177 color : _isColor ? Colors.white : Colors.white38, 178 child: ListTile( 179 // tileColor : _isColor ? Colors.white : Colors.red, 180 title: Text(dateList[index],style: TextStyle(color: Colors.black),), 181 subtitle: Column(children: <Widget>[ 182 Text(titleList[index],style: TextStyle(color: Colors.black),),Text('(タップで詳細を確認)',style: TextStyle(color: Colors.black),),]), 183 onTap: (){ 184 // BottomSheet作成 185 showModalBottomSheet<int>( 186 builder: (BuildContext context) { 187 return Container( 188 height: MediaQuery.of(context).size.height / 2, 189 width: MediaQuery.of(context).size.width / 2, 190 color: Color.fromRGBO(245, 165, 66, 1.0), 191 child: new Column( 192 children: <Widget>[ 193 // シート右上にcloseボタン配置 194 Align( 195 alignment: Alignment.topRight, 196 child: IconButton( 197 onPressed: () => 198 Navigator.pop(context), 199 icon: Icon(Icons.close), 200 color: Colors.black, 201 iconSize: 30, 202 )), 203 Text(titleList[index], 204 style: TextStyle( 205 color: Colors.white, 206 fontFamily: 'MPLUS1p-Regular', 207 fontSize: 35)), 208 Divider( 209 thickness: 1.5, color: Colors.white), // 区切り線 210 211 Text(textList[index], 212 textAlign: TextAlign.center, 213 style: TextStyle( 214 color: Colors.white, 215 fontFamily: 'MPLUS1p-Regular', 216 fontSize: 25)), 217 ], 218 ) 219 ); 220 }, 221 context: context, 222 ); 223 setState(() {_isColor = !_isColor;}); 224 print("_isColorの状態=" '$_isColor'); 225 }, 226 ), 227 ) 228 ); 229 }, 230 ), 231 ) 232 ], 233 ); 234 } 235} 236 237 238// メインアンダー 239Widget mainUnder() { 240 return Container( 241 width: 320, height: 7, color: Color.fromRGBO(242, 139, 12, 1.0)); 242} 243 244 245 246// リスト追加用 247class TodoAddPage extends StatefulWidget { 248 @override 249 _TodoAddPageState createState() => _TodoAddPageState(); 250} 251 252class _TodoAddPageState extends State<TodoAddPage> { 253 254 255// データを元に表示 256 @override 257 Widget build(BuildContext context) { 258 return Scaffold( 259 appBar: AppBar( 260 title: Text('リスト追加'), 261 ), 262 body: Container( 263 // 余白を付ける 264 padding: EdgeInsets.all(64), 265 child: Column( 266 mainAxisAlignment: MainAxisAlignment.center, 267 children: <Widget>[ 268 // テキスト入力フォーム 269 TextField( 270 // 入力されたテキストの値を受け取る 271 onChanged: (String value) { 272 // データが変更したことを知らせる 273 setState(() { 274 // データを変更 275 _date = value; 276 }); 277 }, 278 ), 279 TextField( 280 onChanged: (String value) { 281 setState(() { 282 _title = value; 283 }); 284 }, 285 ), 286 TextField( 287 onChanged: (String value) { 288 setState(() { 289 _text = value; 290 }); 291 }, 292 ), 293 Container( 294 width: double.infinity, 295 // リスト追加ボタン 296 child: RaisedButton( 297 color: Colors.blue, 298 onPressed: () { 299 Navigator.of(context).pop(dateList + titleList + textList); 300 }, 301 child: Text('リスト追加', style: TextStyle(color: Colors.white)), 302 ), 303 ), 304 Container( 305 // 横幅いっぱいに広げる 306 width: double.infinity, 307 // キャンセルボタン 308 child: FlatButton( 309 onPressed: () { 310 Navigator.of(context).pop(); 311 }, 312 child: Text('キャンセル'), 313 ), 314 ), 315 ], 316 ), 317 ), 318 ); 319 } 320}

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

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

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

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

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

guest

回答1

0

自己解決

List.generate()を扱った方法で上手くいきました。
自分が行った方法について記載しておきます。

flutter

1 2// リスト背景色変更用 3List<bool> _selected = List.generate(10, (i) => false); // indexを引数とした関数の返す値に従って初期化されたListを返す 45678 9// メインコンテンツカラム制御ウィジェット 10// ignore: camel_case_types 11class mainBoxWidget extends StatefulWidget { 12 @override 13 _mainBoxState createState() => _mainBoxState(); 14} 15 16// ignore: camel_case_types 17class _mainBoxState extends State<mainBoxWidget> { 18 @override 19 Widget build(BuildContext context) { 20 return Column( 21 children: <Widget>[ 22 // Expandedで残りスペースを拡張 23 Expanded( 24 // データを元にListViewを作成 25 child: ListView.builder ( 26 padding: EdgeInsets.fromLTRB(0, 0, 0, 0), 27 itemCount: dateList.length, 28 itemBuilder: (context, index) { 29 return ConstrainedBox ( 30 constraints: BoxConstraints(maxHeight: 95.0), 31 child: Card ( 32 margin: EdgeInsets.fromLTRB(3.0, 2.0, 3.0, 2.0), 33 color: _selected[index] ? Color.fromRGBO(171, 177, 181, 1.0) : Color.fromRGBO(255, 255, 255, 1.0), 34 elevation: 2.0, 35 child: Container( 36 decoration: BoxDecoration(border: Border.all(color: Color.fromRGBO(36, 20, 14, 1.0)),), // 枠線 37 child: ListTile( 38 title: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, 39 children: <Widget>[ 40 Text(dateList[index],style: TextStyle(color: Colors.black,fontSize: 18,),), 41 ] 42 ), 43 subtitle: Center( 44 child: Column( 45 children: <Widget>[ 46 Text(titleList[index],style: TextStyle(color: Colors.black,fontSize: 20,locale: const Locale("ja"))), 47 Text('(タップで詳細を確認)',style: TextStyle(color: Colors.black87,fontFamily: 'MPLUS1p-Regular',fontSize: 15,decoration: TextDecoration.underline,locale: const Locale("ja"))) 48 ] 49 ) 50 ), 51 52 onTap: (){ 53 setState(() { 54 // _selected[index]の変更&変更後はfalseに戻さない 55 if(_selected[index].toString() == "false") { 56 _selected[index] = !_selected[index]; 57 } 58 }); 59 // BottomSheet表示 60 showModalBottomSheet<int>( 61 builder: (BuildContext context) { 62 return Container( 63 height: MediaQuery.of(context).size.height / 2, 64 width: MediaQuery.of(context).size.width / 2, 65 color: Color.fromRGBO(243, 152, 29, 1.0), 66 child: new ListView( 67 children: <Widget>[ 68 // 右上にcloseボタン配置 69 Align(alignment: Alignment.topRight, 70 child: IconButton( 71 onPressed: () => Navigator.pop(context), 72 icon: Icon(Icons.close), 73 color: Colors.black, 74 iconSize: 35, 75 ) 76 ), 77 Text(titleList[index], textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontFamily: 'MPLUS1p-Regular',locale: const Locale("ja"), fontSize: 30,)), 78 Divider(thickness: 1.5, color: Colors.white), // 区切り線 79 Text(textList[index], textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontFamily: 'MPLUS1p-Regular', locale: const Locale("ja"), fontSize: 20)), 80 ], 81 ) 82 );}, 83 context: context, 84 );}, 85 ), 86 ), 87 ) 88 ); 89 }, 90 ), 91 ) 92 ], 93 ); 94 } 95} 96 97//

投稿2020/12/22 08:19

arumazirou

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問