繁体   English   中英

Flutter 更改 slider 拇指到图像

[英]Flutter change slider thumb to image

我想创造这样的东西。

在此处输入图像描述

我已经设法创建了它,但是每当我启动应用程序时,我都会收到LateInitializationError ,它说LateInitializationError: Field 'customImage' has not been initialized. 在 slider 显示之前。

这是我的代码。 我究竟做错了什么? 我还尝试了 flutter xlider package 但它不再工作了,因为它不支持 null 安全性。 如果您有更好的方法更换 slider 拇指,将不胜感激。

import 'package:flutter/material.dart';
import 'dart:ui' as ui;

import 'package:flutter/services.dart';

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

  @override
  _CustomSliderState createState() => _CustomSliderState();
}

class _CustomSliderState extends State<CustomSlider> {
  late ui.Image customImage;
  double sliderValue = 0.0;

  Future<ui.Image> loadImage(String assetPath) async {
    ByteData data = await rootBundle.load(assetPath);
    ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    ui.FrameInfo fi = await codec.getNextFrame();

    return fi.image;
  }

  @override
  void initState() {
    loadImage('images/star.png').then((image) {
      setState(() {
        customImage = image;
      });
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SliderTheme(
      data: SliderThemeData(
        trackHeight: 28,
        inactiveTrackColor: Colors.grey.shade300,
        activeTrackColor: const Color(0xFFFFE900),
        thumbShape: SliderThumbImage(customImage),
      ),
      child: Slider(
        value: 50,
        min: 0,
        max: 100,
        onChanged: (value) {},
      ),
    );
  }
}

class SliderThumbImage extends SliderComponentShape {
  final ui.Image image;

  SliderThumbImage(this.image);

  @override
  Size getPreferredSize(bool isEnabled, bool isDiscrete) {
    return const Size(0, 0);
  }

  @override
  void paint(PaintingContext context, Offset center,
      {required Animation<double> activationAnimation,
      required Animation<double> enableAnimation,
      required bool isDiscrete,
      required TextPainter labelPainter,
      required RenderBox parentBox,
      required SliderThemeData sliderTheme,
      required TextDirection textDirection,
      required double value,
      required double textScaleFactor,
      required Size sizeWithOverflow}) {
    final canvas = context.canvas;
    final imageWidth = image.width;
    final imageHeight = image.height;

    Offset imageOffset = Offset(
      center.dx - (imageWidth / 2),
      center.dy - (imageHeight / 2),
    );

    Paint paint = Paint()..filterQuality = FilterQuality.high;

    canvas.drawImage(image, imageOffset, paint);
  }
}

所有非后期变量都初始化为 null。 如果一个变量是不可为空的,如果它曾经包含 null,这将是一个错误,所以这是一个编译时错误:

int? number;  // initialized to null
var  str;  // compile-time error

使您的字段可以为空

  ui.Image? customImage;

initState在构建小部件之前运行,但不能是异步 function,所以customImage = image; 几乎肯定会比build function 运行得晚。 由于您在build function 中使用customImage ,并且customImage被标记为迟,因此您会收到此错误。

您可以删除late关键字,使customImage可以为空,并在build方法中检查其值。 如果是 null(图像尚未加载),例如显示进度指示器。

但这并不完美,因为根据图像加载所需的时间,在构建小部件时可能会调用setState ,这会触发另一个错误。

尽管您可以使用addPostFrameCallback解决上述问题,但最好的方法是使用FutureBuilder ,首先加载图像,然后构建您的小部件:


late Future<ui.Image> _loadImage;

@override
void initState() 
  super.initState();
  _loadImage = loadImage();
}

@override
Widget build(BuildContext context) {
  return FutureBuilder<ui.Image>(
      future: _loadImage,
      builder: (context, snapshot) {
        if (snapshot.hasData || snapshot.data != null) {
          return SliderTheme(
            data: SliderThemeData(
              trackHeight: 28,
              inactiveTrackColor: Colors.grey.shade300,
              activeTrackColor: const Color(0xFFFFE900),
              thumbShape: SliderThumbImage(snapshot.data!),
            ),
            child: Slider(
              value: 50,
              min: 0,
              max: 100,
              onChanged: (value) {},
            ),
          );
        }
        // progress indicator while loading image,
        // you can return and empty Container etc. if you like
        return CircularProgressIndicator();
      });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM