Flutterで⭐️のスライダーを作る

2024/02/10に公開

Tips

SwiftUIで星のスライダーを作ったのですが、Flutterでもパッケージなしでできないのかな〜と思って試しにやってみたらできました笑

SwiftUIだとこれ💁‍♂️

Flutterだとこんな感じです💁‍♂️

コンポーネントを作ってみる。

main.dartのColumnで呼び出すので、Scaffoldは不要。

このコードでは、_importanceという状態を持つStatefulWidgetを作成しています。Textウィジェットでは、_importanceの値に基づいて星を表示します。Sliderウィジェットでは、_importanceの値をユーザーが変更できるようにしています。Sliderの値が変更されると、onChangedコールバックが呼び出され、_importanceの値が更新され、UIが再描画されます。

import 'package:flutter/material.dart';

class StarSlider extends StatefulWidget {
  const StarSlider({super.key});

  
  _StarSliderState createState() => _StarSliderState();
}

class _StarSliderState extends State<StarSlider> {
  double _importance = 1;

  
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text('⭐️' * _importance.toInt()),
        Slider(
          value: _importance,
          min: 1,
          max: 5,
          divisions: 4,
          onChanged: (double value) {
            setState(() {
              _importance = value;
            });
          },
        ),
      ],
    );
  }
}

こちらで、importしてビルドしてね。

import 'package:flutter/material.dart';
import 'package:ui_example/star_slider/start_slider.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('UI Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            StarSlider(),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

まとめ

SwiftUIで書いた場合だと、@State var importance: Double = 1と書いてrange使って、ロジックを作ります。FlutterだとsetStateとSlider Widgetを使って自作できます。
⭐️のスライダー使いたい人いたら試してみてね💙🧡

SwiftUIだとこんな感じです💁‍♂️

import SwiftUI

struct AddTodoView: View {
    @Environment(\.modelContext) private var modelContext
    @Environment(\.dismiss) var dismiss
    
    @State var title: String = ""
    @State var note: String = ""
    @State var importance: Double = 1
    @State var date: Date = Date()
    
    var body: some View {
        // Form can write multiple parts when written inside NavigationStack
        
        NavigationStack{
//            Group Forms and DatePickers
            Form{
                TextField("Title", text: $title)
                DatePicker("Date", selection: $date, displayedComponents: .date)
                Text(String(repeating:"⭐️", count: Int(importance)))
                Slider(value: $importance, in: 1...5, step:1)
                TextEditor(text: $note)
            }
            // By adding toolbar to the navigationTitle, you can place Buttons on the screen.
            .navigationTitle("New Todo")
            .toolbar{
                ToolbarItem(placement: .navigationBarLeading){
                    Button("Cancel") {
                        dismiss()
                    }
                }
                ToolbarItem(placement: .navigationBarTrailing){
                    Button("Save") {
                        let newTodo = Todo(title: title, note: note, importance: importance, date: date
                        )
                        modelContext.insert(newTodo)
                        dismiss()
                    }
                }
            }
        }
    }
}

#Preview {
    AddTodoView()
}

Discussion