Как получить значение текущего масштаба InteractiveViewer во flutter?

#flutter

#flutter

Вопрос:

Итак, что я хочу сделать здесь, это изменить размер SingleChildScrollView пропорционально всякий раз, когда масштаб InteractiveViewer. Например: масштаб 1.0 = ширина scrollview равна 1000, масштаб 2.0 = ширина scrollview равна 2000 и так далее. Кажется, я не могу выяснить, как сделать это непосредственно из документации. Итак, я рассмотрел это, получив значение самого свойства (scale) и повторно отобразив виджет SingleChildScrollView, но, похоже, я не могу найти никакого способа сделать это. Если есть необходимость в дополнительных разъяснениях, не стесняйтесь спрашивать. Спасибо!

Ответ №1:

Вы можете получить фактическое и постоянное значение масштаба следующим образом:

 class InteractiveViewerTest extends StatefulWidget {
  @override
  _InteractiveViewerTestState createState() => _InteractiveViewerTestState();
}

class _InteractiveViewerTestState extends State<InteractiveViewerTest> {
  TransformationController _transformationController =
      TransformationController();

  @override
  Widget build(BuildContext context) {
    return InteractiveViewer(
      minScale: 0.5,
      maxScale: 2.0,
      transformationController: _transformationController,
      onInteractionEnd: (details) {
        // Details.scale can give values below 0.5 or above 2.0 and resets to 1
        // Use the Controller Matrix4 to get the correct scale.
        double correctScaleValue = _transformationController.value.getMaxScaleOnAxis();
      },
      child: Container(
        width: 100,
        height: 100,
        color: Colors.blue,
      ),
    );
  }
}
  

Комментарии:

1. Это правильный ответ, подробности.масштаб зависит от текущего взаимодействия, поэтому, например, если вы сжимаете внутрь, он всегда будет возвращать значение меньше 1, а если вы сжимаете наружу, он вернет значение больше нуля, и это независимо от фактического масштаба дочернего виджета, с которым взаимодействуют.

2. Это здорово! Забудьте утвержденный ответ, это тот самый!

3. масштаб возвращается к 1.0 после завершения масштабирования, когда я добавляю контроллер в интерактивный просмотрщик, как его остановить

4. Это именно то, что исправляет приведенное выше решение. Вы уверены, что используете _transformationController.value.getMaxScaleOnAxis(); для получения значения scalue?

5. Невероятный ответ. Использование details.scale (или .verticalScale /.horizontalScale) сбросит значение до 1.0, когда завершится жест панорамирования.

Ответ №2:

onInteractionUpdate Вызывается, когда пользователь обновляет жест панорамирования или масштабирования в виджете. Таким образом, вы можете получить текущее значение scale из callback .

Я добавил демонстрационный код ниже:

        InteractiveViewer(
        transformationController: transformationController,
        onInteractionUpdate: (ScaleUpdateDetails details){  // get the scale from the ScaleUpdateDetails callback
          var myScale = details.scale;
          print(myScale); // print the scale here
        },
        boundaryMargin: EdgeInsets.all(20.0),
        minScale: 0.1,
        maxScale: 4.6,
        scaleEnabled: true,
        panEnabled: true,
        child: ClipRRect(
          borderRadius: BorderRadius.circular(18.0),
          child: Image.asset('images/user_picture.png'),
        ),
      );
  

Комментарии:

1. Спасибо, ваш ответ решил мой вопрос, могу ли я задать дополнительный вопрос, есть ли способ выполнить функцию только при увеличении / уменьшении масштаба, а не при панорамировании?

2. interaction Обратные вызовы вызываются независимо от того, происходит ли взаимодействие с виджетом (панорамирование или масштабирование). Если вы не хотите, чтобы виджет был panned , вы можете установить panEnabled значение false .

3. Я все еще хочу, чтобы виджет можно было перемещать, но я не хочу, чтобы взаимодействие запускалось при панорамировании, есть ли способ ограничить это?

4. Как я уже сказал, pan и scale являются взаимодействиями, и эти обратные вызовы будут вызываться в любое время, когда в виджете происходит взаимодействие. Смотрите Прилагаемые документы: The onInteractionUpdate is alled when the user updates a pan or scale gesture on the widget. @anonymous, я не думаю, что есть способ сделать то, о чем вы просите.

5. На самом деле есть. Люди, ищущие это, могут сравнить matrix4 до и после взаимодействия и оценить, было ли просто масштабирование или также панорамирование, или просто панорамирование и т.д.

Ответ №3:

Используйте onInteractionUpdate свойство и получите значение из ScaleUpdateDetails подобного:

 double scale;

InteractiveViewer(
  onInteractionUpdate: (details) {
    scale = details.scale; // This is your scale. 
  },
  child: FlutterLogo(),
);
  

Комментарии:

1. любопытный вопрос, всегда ли слово «детали» используется для всех виджетов? например, если мне нужна высота контейнера, я могу сделать то же самое, но изменить его на детали. высота?