如何在 Flutter 中自定义 Slider 小部件?

Posted

技术标签:

【中文标题】如何在 Flutter 中自定义 Slider 小部件?【英文标题】:How to customize Slider widget in Flutter? 【发布时间】:2019-11-25 05:16:49 【问题描述】:

是否可以在 Flutter 中自定义 Slider Widget?

像这样:

【问题讨论】:

如果您询问 Slider thumb Image,请查看此答案***.com/questions/58116843/… 【参考方案1】:

用 SliderTheme 包裹你的滑块

SliderTheme(
    data: SliderThemeData(
            thumbColor: Colors.green,
            thumbShape: RoundSliderThumbShape(enabledThumbRadius: 20)),
    child: Slider(
          value: _value,
          onChanged: (val) 
            _value = val;
            setState(() );
          ,
        ),
      ),

【讨论】:

但是如何在 thumbShape 上添加自定义图标? —— 您必须通过从SliderComponentShape 扩展来创建自定义拇指并覆盖paint 方法。然后,在paint 方法中使用context.canvas 来绘制您的自定义形状。如果要使用图像,请选中canvas.drawImage 以使用图像。 @MarcelGolob 这篇博文讨论了如何做到这一点:medium.com/flutter-community/…【参考方案2】:

我认为你必须使用 SliderTickMarkShape 类

滑块刻度线形状的基类。

如果您想要自定义滑块刻度线,请创建它的子类 形状。

简单的方法是获取在您的上下文中使用的实际 SliderTheme 并仅修改您需要的属性。例如,要修改一张幻灯片:

SliderTheme(
    data: SliderTheme.of(context).copyWith(
    activeTrackColor: Colors.white,
    thumbShape: RoundSliderThumbShape(enabledThumbRadius: 15.0),
    overlayShape: RoundSliderOverlayShape(overlayRadius: 30.0),
    ),
    child: Slider(
             value: height.toDouble(),
             min: 120.0,
             max: 220.0,
             activeColor: Colors.white,
             inactiveColor: Color(0xFF8D8E98),
             onChanged: (double newValue) 
                 setState(() 
                        height = newValue.round();
                      );
                    ,
                  ),
                ),

另一个选项是修改您在应用中使用的主题;这样你就可以修改应用中的所有滑块:

MaterialApp(
      theme: ThemeData.dark().copyWith(
          sliderTheme: SliderTheme.of(context).copyWith( //slider modifications
            thumbColor: Color(0xFFEB1555),
            inactiveTrackColor: Color(0xFF8D8E98),
            activeTrackColor: Colors.white,
            overlayColor: Color(0x99EB1555),
            thumbShape: RoundSliderThumbShape(enabledThumbRadius: 15.0),
            overlayShape: RoundSliderOverlayShape(overlayRadius: 30.0),
          ),
          primaryColor: Color(0xFF0A0E21), // theme color
          scaffoldBackgroundColor: Color(0xFF0A0E21)), // theme background color
      home: InputPage(),
);

【讨论】:

【参考方案3】:

我记得,我也遇到过同样的挑战。

我创建了自己的波浪滑块:

import 'dart:math';

import 'package:flutter/material.dart';

List<int> bars = [];
const barWidth = 5.0;
double screenWidth;
int numberOfBars;

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Home(),
    );
  


void randomNumberGenerator() 
  Random r = Random();
  for (var i = 0; i < numberOfBars; i++) 
    bars.add(r.nextInt(40) + 10);
  


class Home extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    if (bars.isEmpty) 
      screenWidth = MediaQuery.of(context).size.width;
      numberOfBars = screenWidth ~/ barWidth;
      randomNumberGenerator();
    
    return Container(child: WaveSlider());
  


class WaveSlider extends StatefulWidget 
  @override
  State<StatefulWidget> createState() => WaveSliderState();


class WaveSliderState extends State<WaveSlider> 
  double bar2Position = 180.0;

  _onTapDown(TapDownDetails details) 
    var x = details.globalPosition.dx;
    print("tap down " + x.toString());
    setState(() 
      bar2Position = x;
    );
  

  @override
  Widget build(BuildContext context) 
    int barItem = 0;
    return Scaffold(
      body: Center(
        child: Stack(
          alignment: Alignment.centerLeft,
          children: <Widget>[
            GestureDetector(
              onTapDown: (TapDownDetails details) => _onTapDown(details),
              onHorizontalDragUpdate: (DragUpdateDetails details) 
                setState(() 
                  bar2Position = details.globalPosition.dx;
                );
              ,
              child: Container(
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: bars.map((int height) 
                    Color color = barItem + 1 < bar2Position / barWidth
                        ? Colors.deepPurple
                        : Colors.blueGrey;
                    barItem++;
                    return Container(
                      color: color,
                      height: height.toDouble(),
                      width: 5.0,
                    );
                  ).toList(),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  


【讨论】:

以上是关于如何在 Flutter 中自定义 Slider 小部件?的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 中自定义画笔 Painter

Flutter自定义绘制组件

在android studio中自定义flutter app:打开android flutter代码

[flutter专题]详解AppBar小部件

oc之mac中自定义NSSlider

Flutter Slider 未在 ExpansionPanel 内部重建