LoginSignup
0
0

More than 1 year has passed since last update.

Freezedを使ってラジオボタン付きリストを作成

Last updated at Posted at 2022-07-25

スクリーンショット 2022-07-25 14.48.54.png
このようなラジオボタン入りのリストを作成してみたかったのですが、RadioListTileウィジェットを利用すると高さに限界値があってスリムにスタイル良くいきませんでした。
スクリーンショット 2022-07-25 15.06.34.png
これ以上は狭めれないのです。これで問題なければ、下記↓実装でいいと思います。

Container(
          width: double.infinity,
          height: 40.0,
          child: textGrey('Radio List', 15),
          padding: const EdgeInsets.only(top: 15.0, left: 15.0)
),
SafeArea(
         child: Column(
         children: [
           Card(
           child: Container(
           child: RadioListTile(
           title: Text('選択肢1',
             style: TextStyle(
               fontSize: 16,
               fontWeight: FontWeight.bold,
               color: Colors.black87,
                       ),
               ),
               value: RadioValue.FIRST,
               groupValue: _gValue,
               onChanged: (value) => _onRadioSelected(value),
              ),
            ),
          ),
          Card(
          child: RadioListTile(
          title: text('選択肢2', 16),
          value: RadioValue.SECOND,
          groupValue: _gValue,
          onChanged: (value) => _onRadioSelected(value),
            ),
          ),
          Card(
          child: RadioListTile(
          title: text('選択肢3', 16),
          value: RadioValue.THIRD,
          groupValue: _gValue,
          onChanged: (value) => _onRadioSelected(value),
            ),
          ),
        ],
      ),
),

スクリーンショット 2022-07-25 15.22.39.png
ただ、スクロールせずにスッキリとまとめるにはやはりこの方が見栄えがいいかと、そこで下記ウィジェットを作成しました。

Widget radioBox<T>(
  String label,
  Color color,
  T groupValue,
  T value,
  void Function(T?) onChange,
) {
  return Container(
      decoration: BoxDecoration(
        boxShadow: [
          BoxShadow(
            color: Colors.grey.withOpacity(0.5),
            spreadRadius: 0.2,
            blurRadius: 0.5,
            offset: Offset(0.1, 0.7),
          ),
        ],
        borderRadius: BorderRadius.circular(3),
        color: Colors.white,
      ),
      width: 367,
      height: 40,
      child: Container(
          child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [
        SizedBox(
          width: 10,
        ),
        new Radio<T>(
          activeColor: color,
          groupValue: groupValue,
          value: value,
          onChanged: onChange,
        ),
        SizedBox(
          width: 15,
        ),
        text(label, 16)
      ])));
}

この作成したradioBoxウィジェットを利用したUIが以下になります。

enum RadioList { OptionA, OptionB, OptionC }

// build内
Container(
  width: double.infinity,
  height: 40.0,
  child: textGrey('Radio List', 15),
  padding: const EdgeInsets.only(top: 15.0, left: 15.0)
),
                      
radioBox<radioList>(
  '選択肢1',
  Colors.blue,
  provider.Provider.of<AppDetailState>(
    context, listen: true
  ).setting.radioList,
  radioList.OptionA, (val) {
    provider.Provider.of<AppStateNotifier>(
      context, listen: false
    ).updateRadioList(val!);
     
    }),
SizedBox(height: 2),
radioBox<radioList>(
  '選択肢2',
  Colors.blue,
  provider.Provider.of<AppDetailState>(
    context, listen: true
  ).setting.radioList,
  radioList.OptionB, (val) {
    provider.Provider.of<AppStateNotifier>(
      context, listen: false
    ).updateRadioList(val!);
     
    }),
SizedBox(height: 2),
radioBox<radioList>(
  '選択肢3',
  Colors.blue,
  provider.Provider.of<AppDetailState>(
    context, listen: true
  ).setting.radioList,
  radioList.OptionC, (val) {
    provider.Provider.of<AppStateNotifier>(
      context, listen: false
    ).updateRadioList(val!); 
     
    }),
SizedBox(height: 2),

あとは、Providerを使って状態管理をしてあげれば完成です。

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../models/setting.dart';
import '../models/user.dart';

part 'app_state.freezed.dart';

@freezed
class AppState with _$AppState {
  const factory AppState(Setting setting) = AppDetailState;
}
class AppStateNotifier extends StateNotifier<AppDetailState> {
  AppStateNotifier(Setting setting)
      : super(AppDetailState(setting)) {}

  static Future<AppStateNotifier> async {
    final setting = await settingsService.fetchSetting();
  return AppStateNotifier(setting);
  }

// (メソッド例)
// radioList(radioList v) async {
//    final prefs = await SharedPreferences.getInstance();
//    await prefs.setString("radioList", v.name);
//    state = state.copyWith(setting: state.setting.copyWith(radioList: v));
//  }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0