每次我在 InteractiveViewer Flutter 中释放屏幕时,缩放值都会重置

问题描述 投票:0回答:1

我想在缩放时显示红色方块并且该值大于二。使用我拥有的代码我可以做到这一点,问题是当我释放屏幕时,缩放重置并且正方形消失。 如何让方块在停止缩放后保持亮起状态,只要缩放值大于二,当然如果缩放值小于二则消失?

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => ZoomProvider(),
      child: const MaterialApp(
        title: 'Interactive Viewer Example',
        home: HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Zoom ${context.watch<ZoomProvider>().zoomLevel.toStringAsFixed(1)}'),
      ),
      body: Center(
        child: InteractiveViewer(
              onInteractionUpdate: (details) {
                context.read<ZoomProvider>().updateZoomLevel(details.scale);
              },
              boundaryMargin: const EdgeInsets.all(320),
              constrained: false,
              minScale: 0.5,
              maxScale: 5.0,
              child: Stack(
                children: [Image.network(
                  'https://picsum.photos/id/1/400/400',
                  fit: BoxFit.contain,
                ),
              
            
            
            Visibility(
              //visible: true,
              visible: context.watch<ZoomProvider>().zoomLevel >= 2,
              child: Container(
                width: 40,
                height: 40,
                color: Colors.red,
              ),
            ),
            ]
              )
        
        ),
      ),
    );
  }
}

class ZoomProvider extends ChangeNotifier {
  double _zoomLevel = 1.0;

  double get zoomLevel => _zoomLevel;

  void updateZoomLevel(double scale) {
    _zoomLevel = scale;
    notifyListeners();
  }
}
flutter
1个回答
0
投票

您需要将缩放级别持久存储在 ZoomProvider 中。

您可以通过将交互过程中的状态更新与交互完成后的最终状态更新分开来实现这一点。像这样:

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Zoom ${context.watch<ZoomProvider>().zoomLevel.toStringAsFixed(1)}'),
      ),
      body: Center(
        child: InteractiveViewer(
          onInteractionUpdate: (details) {
            context.read<ZoomProvider>().updateZoomLevel(details.scale);
          },
          onInteractionEnd: (details) {
            context.read<ZoomProvider>().finalizeZoomLevel();
          },
          boundaryMargin: const EdgeInsets.all(320),
          constrained: false,
          minScale: 0.5,
          maxScale: 5.0,
          child: Stack(
            children: [
              Image.network(
                'https://picsum.photos/id/1/400/400',
                fit: BoxFit.contain,
              ),
              Visibility(
                visible: context.watch<ZoomProvider>().isZoomedIn,
                child: Container(
                  width: 40,
                  height: 40,
                  color: Colors.red,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class ZoomProvider extends ChangeNotifier {
  double _zoomLevel = 1.0;
  double _finalZoomLevel = 1.0;

  double get zoomLevel => _zoomLevel;
  bool get isZoomedIn => _finalZoomLevel >= 2;

  void updateZoomLevel(double scale) {
    _zoomLevel = scale;
    notifyListeners();
  }

  void finalizeZoomLevel() {
    _finalZoomLevel = _zoomLevel;
    notifyListeners();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.