Study Record

[Flutter] slider() 본문

Flutter/widget

[Flutter] slider()

초코초코초코 2023. 2. 5. 19:28
728x90

Slider Widget

사용자가 인디케이터를 움직임으로써 값을 설정할 수 있는 위젯이다.

 

import 'package:flutterd/material.art';

Slider({   
  Key? key,  
  required double value,
  required void Function(double)? onChanged, 
  void Function(double)? onChangeStart,  
  void Function(double)? onChangeEnd,  
  double min = 0.0,   
  double max = 1.0, 
  int? divisions,  
  String? label, 
  Color? activeColor,   
  Color? inactiveColor,  
  Color? thumbColor, 
  MouseCursor? mouseCursor, 
  String Function(double)? semanticFormatterCallback,   
  FocusNode? focusNode,
  bool autofocus = false, 
})

 

기본 인자값

  • double value : Slider에서 현재 선택된 값
  • void Function(double)? onChanged : 값이 선택될 때마다 호출되는 함수
  • void Function(double)? onChangeStart : 값이 선택되기 직전에 호출되는 함수
  • void Function(double)? onChangeEnd : 값이 선택된 후(사용자가 인디케이터에서 손을 뗐을 때 호출되는 함수 
  • double min = 0.0 : Slider 에서 사용자가 선택할 수 있는 가장 작은 값
  • double max = 1.0 : Slider 에서 사용자가 선택할 수 있는 가장 큰 값
  • Color? activeColor : 활성 상태 색상
  • Colors? inactiveColor : 비활성 상태 색상
  • Colors? thumbColor : thumb 색상(인디케이터 색상)

예시)

class SliderTestScreen extends StatefulWidget {
  const SliderTestScreen({Key? key}) : super(key: key);

  @override
  State<SliderTestScreen> createState() => _SliderTestScreenState();
}

class _SliderTestScreenState extends State<SliderTestScreen> {
  int value = 100;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Text(
              value.toString(),
              style: const TextStyle(color: Colors.white, fontSize: 20.0),
            ),
            Slider(
              value: value.toDouble(),
              onChanged: (selectedValue) {
                print("onChanged : $selectedValue");
                setState(() {
                  value = selectedValue.toInt();
                });
              },
              onChangeStart: (selectedValue) {print("onChangeStart : $selectedValue");},
              onChangeEnd: (selectedValue) {print("onChangeEnd : $selectedValue");},
              min: 0.0,
              max: 200.0,
            )
          ],
        ),
      ),
    );
  }
}

 

min = 0.0 , max = 200.0이고 value 값이 100.0 이므로 처음에는 딱 인디케이터가 반을 차지하고 Slider의 현재 값을 표시하는 Text() 도 100을 보여주고 있다. Slider() 위젯은 인디케이터를 움직여 값을 선택해도 그 자체로는 아무런 반응이 없다. 위의 gif 이미지처럼 인디케이터를 이동하는 대로 자연스럽게 움직히지 않는다. 

인디케이터를 움직여 값이 바뀔때마다 위젯을 다시 그려 Slider()의 value 값이 바뀌는 과정을 반복함으로써 gif 이미지처럼 자연스럽게 인디케이터를 움직이는 대로 Slider의 모양도 바뀌고 Text()의 값도 바뀐다.

이 과정을 간단히 설명하면, Slider() 의 값이 바뀌는 대로 (onChanged 호출) setState()를 실행해 변경된 값을 저장해 build() 함수가 다시 실행됨으로써 Text() 도 변경된 값으로 바뀌고 Slider() 도 변경된 값으로 적용된다. 이 과정이 복잡해 보이고 build() 함수를 계속 다시 호출하는 것이 효율적이지 않아 보여도 이것이 Flutter 가 의도하는 방식이므로 신경 쓰지 않아도 된다.

 

+ 색상 바꾸기

activeColor와 inactiveColor, thumbColor를 설정하면 다음과 같이 활성 상태와 비활성 상태, thumb의 생삭을 바꿀 수 있다.

Slider(
  ...
  activeColor: Colors.pink[200],
  inactiveColor: Colors.lightBlue,
  thumbColor: Colors.white,
)

 

+ 그 외 Silder 의 여러 가지 요소 바꾸는 방법

ThemeDate()의 silderTheme를 이용하면 다양한 Silder를 구현할 수 있다.

void main() {
  runApp(
    MaterialApp(
      theme: ThemeData(
        sliderTheme: SliderThemeData(
          thumbShape: RoundSliderThumbShape(
            enabledThumbRadius: 5.0,
            elevation: 10.0,
          )
        )
      ),
      home: SliderTestScreen(),
    ),
  );
}

 

 

라벨(String? label)

라벨은 인디케이터가 활성화(사용자가 인디케이터를 움직이는 동안)할 때 보여주는 표시이다.

MaterialApp(
  theme: ThemeData(
    sliderTheme: SliderThemeData(
      showValueIndicator: ShowValueIndicator.always
    )
  ),
  home: SliderTestScreen(),
)

...

Slider(
  value: value.toDouble(),
  onChanged: (selectedValue) {
    setState(() {
      value = selectedValue.toInt();
    });
  },
  min: 0.0,
  max: 200.0,
  label: value.toString(), 
)

Slider()의 label 인자에 표시될 값을 지정해 주는 것 외에 SilderThemeData의 showValueIndicator 값도 설정해줘야 한다.

  • ShowValueIndicator.always : 항상 라벨을 보여준다.
  • ShowValueIndicator.never : 항상 라벨을 보여주지 않는다.
  • ShowValueIndicator.onlyForDiscrete : Slider() 의 divisions 속성이 null 이 아닐 경우 라벨을 보여준다. (Default)
  • ShowValueIndicator.onlyForContinuous : Slider() 의 divisions 속성이 null 일 경우 라벨을 보여준다.

 

 

+ 라벨의 색상, 모양을 바꿀 수 있다. (SilderThemeData , valueInficatorShape)

MaterialApp(
  theme: ThemeData(
    sliderTheme: SliderThemeData(
      showValueIndicator: ShowValueIndicator.always,
      valueIndicatorTextStyle: TextStyle(
        color: Colors.pink,
        fontSize: 15.0
      ),
      valueIndicatorColor: Colors.white,
      valueIndicatorShape: PaddleSliderValueIndicatorShape(),      
    )
  ),
  home: SliderTestScreen(),
)

 

 

 

구역 나누기(int? divisions)

구역을 나눈다는 것은 min = 0 ~ max = 200 일 때 0 ~ 200을 인디케이터의 움직임대로 값이 선택되는 것이 아니라 divisions = 5 이면 5개로 나눠 [0,  40 , 80 , 120 , 160 , 200]를 기준으로 5개의 구역으로 나눠지고 기준 값이 선택될 수 있다.

Slider(
  value: value.toDouble(),
  onChanged: (selectedValue) {
    setState(() {
      value = selectedValue.toInt();
    });
  },
  min: 0.0,
  max: 200.0,
  label: value.toString(), 
  divisions: 5,
)

 

 

✍ 기타

 

1. useMaterial3

 

Sliders – Material Design 3

Sliders allow users to make selections from a range of values.

m3.material.io

ThemeData 의 useMaterial3 Flag를 이용하면 간단하게 Materal Design 3 를 사용할 수 있다. 

 

import 'package:flutter/material.dart';

void main() => runApp(const SliderApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorSchemeSeed: const Color(0xff6750a4),
        useMaterial3: true,
      ),
      home: const SliderExample(),
    );
  }
}

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

  @override
  State<SliderExample> createState() => _SliderExampleState();
}

class _SliderExampleState extends State<SliderExample> {
  double _currentSliderValue = 20;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Slider')),
      body: Slider(
        value: _currentSliderValue,
        max: 100,
        divisions: 5,
        label: _currentSliderValue.round().toString(),
        onChanged: (double value) {
          setState(() {
            _currentSliderValue = value;
          });
        },
      ),
    );
  }
}

 

- 참고 사이트

https://api.flutter.dev/flutter/material/Slider-class.html

 

Slider class - material library - Dart API

A Material Design slider. Used to select from a range of values. The Sliders value is part of the Stateful widget subclass to change the value setState was called. link To create a local project with this code sample, run: flutter create --sample=material.

api.flutter.dev


 

 

728x90