본문 바로가기

소프트웨어 /Flutter

[Flutter] Slider TickMark 커스텀하기

반응형

음량을 조절하고자 할 때, 단계별로 값을 조절해야 할 때 Slider를 많이 사용합니다.

 

이번엔 위와 같은 슬라이더로 커스텀을 해보려고 합니다.

 

야매지만 자주 쓰이는 위젯이니 봐두면 좋을 것 같아요.

 

먼저 기본 Slider를 사용하면 아래와 같이 만들 수 있는데요.

 

 

 double _counter = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Slider Widget'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Slider(value: _counter,
              min: 0,
              max: 10,
              onChanged: (value) {
              setState(() {
                _counter = value;
              });
              },
            )
          ],
        ),
      ),
    );
  }

 

Class 안에 _counter라는 double형 변수를 선언해주고 Slider 위젯을 만들어줍니다.

기본 value값이 double형으로 사용되기 때문에 int형보단 double형으로 만들어줍니다.

 

조금 밋밋한 슬라이더를 좀 더 예쁘게 꾸며보겠습니다.

SliderThemeData를 사용해서 track과 tick, thumb을 커스텀 할 수 있습니다.

 

 

SliderTheme(data: const SliderThemeData(
                    inactiveTickMarkColor: Colors.black,
                    activeTickMarkColor: Colors.white,
                    valueIndicatorColor: Colors.black,
                    trackHeight: 12,
                    activeTrackColor: Colors.blue,
                    thumbColor: Colors.white,
                    thumbShape: RoundSliderThumbShape(enabledThumbRadius: 10)
                ),

 

일반적인 tickmark를 사용했을 때 기본 TickMark는 생각보다 예쁘진 않은 것 같아요.

 

그래서 기본 tickmark를 없애주고 Stack과 Container를 사용해서 tickmark를 따로 만들어 주었습니다.

 

 

showTrack(){
    return Padding(padding: const EdgeInsets.fromLTRB(23, 23, 23, 23),
      child: Row(
        children: [
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
        ],
      ),);
  }

야매지만 구분자를 만들어 Stack으로 쌓아주었습니다..

 

기본보다는 좀 더 깔끔한 느낌이지 않은가요???

 

더 좋은 방법이 있다면 공유해주시면 감사하겠습니다 ㅎㅎ

 

 

아래는 전체코드입니다.

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  double _counter = 0.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Slider Widget'),
      ),
      body: Column(
          children: [
            SliderTheme(data: SliderThemeData(
                tickMarkShape: SliderTickMarkShape.noTickMark,
                trackHeight: 12,
                inactiveTrackColor: Colors.amber[200],
                activeTrackColor: Colors.amber,
                thumbColor: Colors.white,
                thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 10)
            ),
                child: Stack(
                  children: [
                    showTrack(),
                    Padding(
                      padding: const EdgeInsets.only(top: 12),
                      child: Slider(value: _counter,
                        min: 0,
                        max: 5,
                        divisions: 5,
                        onChanged: (value) {
                          setState(() {
                            _counter = value;
                          });
                        },
                      ),
                    )
                  ],
                ))
          ],
      ),
    );
  }

  showTrack(){
    return Padding(padding: const EdgeInsets.fromLTRB(23, 23, 23, 23),
      child: Row(
        children: [
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
          const Spacer(),
          Container( height:6.0, width:2.0, color:Colors.blueGrey,),
        ],
      ),);
  }
}