首页 > 解决方案 > Flutter 升级到 1.19.0-0.0.pre 后 SliderTheme 中断

问题描述

这是代码:

 Widget getSlider(BuildContext context) {
   return SliderTheme(
     data: SliderTheme.of(context).copyWith(
       overlayShape: RoundSliderThumbShape(enabledThumbRadius: 25.0),
       trackHeight: 0,
       thumbShape: RoundSliderThumbShape(enabledThumbRadius: 25.0),
       thumbColor: thumbColor,
    ),
    child: Slider(
      value: value,
      min: minValue,
      max: maxValue,
      onChanged: onChanged,
      onChangeEnd: onChangeEnd,
    ),
  );
}

一切似乎都很好。但是在我将 Flutter 升级到版本 1.19.0-0.0.pre 后,它会中断并给我这个错误:

 ════════ Exception caught by rendering library 
 The following NoSuchMethodError was thrown during paint():
 The getter 'isEmpty' was called on null.
 Receiver: null
 Tried calling: isEmpty

 The relevant error-causing widget was: 
 Slider file:///s_app/lib/components/ui_components/slider_components.dart:254:14
  When the exception was thrown, this was the stack: 
  #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
  #1      RoundSliderThumbShape.paint (package:flutter/src/material/slider_theme.dart:2373:30)
  #2      _RenderSlider.paint (package:flutter/src/material/slider.dart:1323:33)
  #3      RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2264:7)
  #4      PaintingContext.paintChild (package:flutter/src/rendering/object.dart:184:13)
  ...
  The following RenderObject was being processed when the exception was fired: _RenderSlider#4d553
  ...  parentData: <none> (can use size)
  ...  constraints: BoxConstraints(0.0<=w<=270.0, 0.0<=h<=30.0)
  ...  semantic boundary
  ...  size: Size(270.0, 30.0)
  RenderObject: _RenderSlider#4d553
    parentData: <none> (can use size)
    constraints: BoxConstraints(0.0<=w<=270.0, 0.0<=h<=30.0)
    semantic boundary
    size: Size(270.0, 30.0)
  ══════════════════════════════════════════════════════

这是我的颤振医生:

 [✓] Flutter (Channel dev, 1.19.0-0.0.pre, on Mac OS X 10.15.3 19D76, locale en-US)
   • Flutter version 1.19.0-0.0.pre at /Applications/flutter
   • Framework revision a849daf283 (4 days ago), 2020-05-07 18:59:02 -0700
   • Engine revision 3953c3ccd1
   • Dart version 2.9.0 (build 2.9.0-5.0.dev 4da5b40fb6)


 [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
   • Android SDK at /Applications/Android/sdk
   • Platform android-29, build-tools 29.0.3
   • ANDROID_HOME = /Applications/Android/sdk
   • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
   • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)
   • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
   • Xcode at /Applications/Xcode.app/Contents/Developer
   • Xcode 11.4.1, Build version 11E503a
   • CocoaPods version 1.9.1

[✓] Chrome - develop for the web
   • Chrome at /Applications/Google 
     Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 3.6)
   • Android Studio at /Applications/Android Studio.app/Contents
   • Flutter plugin version 46.0.1-dev.5
   • Dart plugin version 192.7761
   • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b4-5784211)

[✓] VS Code (version 1.42.0)
   • VS Code at /Applications/Visual Studio Code.app/Contents
   • Flutter extension version 3.8.0

[✓] Connected device (3 available)
   • iPho • acd5efecf25da9ac75d28 • ios            • iOS 13.4.1
   • Web Server • web-server                               • web-javascript • Flutter Tools
   • Chrome     • chrome                                   • web-javascript • Google Chrome 81.0.4044.138

 • No issues found!

追查问题后发现RoundSliderThumbShape的paint方法中的[sizeWithOverflow]为null。但我不知道如何使它不为空,因为这是颤振自己的代码。

此外,仅作为旁注,如果我删除 SliderTheme 一切正常。

标签: flutterslider

解决方案


最后我找到了解决方案。这可能不漂亮,但这是我到目前为止能找到的。我愿意接受更好的解决方案。

  1. 我创建了一个继承自 SliderComponentShape 的新类。
  2. 在它的绘画方法中,我注释掉了assert(!sizeWithOverflow.isEmpty);
  3. 我添加了sizeWithOverflow = parentBox.size;

这行得通。

所以代码看起来像这样:

class SpecialSliderThumbShape extends 
     SliderComponentShape {
    // .... All the same codes as the original RoundSliderThumbShape

 @override
 void paint(
   PaintingContext context,
   Offset center, {
   Animation<double> activationAnimation,
   @required Animation<double> enableAnimation,
   bool isDiscrete,
   TextPainter labelPainter,
   RenderBox parentBox,
   @required SliderThemeData sliderTheme,
   TextDirection textDirection,
   double value,
   double textScaleFactor,
   Size sizeWithOverflow,
 }) {
   assert(context != null);
   assert(center != null);
   assert(enableAnimation != null);
   assert(sliderTheme != null);
   assert(sliderTheme.disabledThumbColor != null);
   assert(sliderTheme.thumbColor != null);

   // This is the difference here:
   // assert(!sizeWithOverflow.isEmpty);

   sizeWithOverflow = parentBox.size;

   //... Continue same as the original

推荐阅读