【问题标题】:InteractiveViewer does not hide other Widgets when pannedInteractiveViewer 在平移时不会隐藏其他小部件
【发布时间】:2021-02-18 22:14:08
【问题描述】:

我在 ProductDetail 页面上使用了 InteractiveViewer。

但是当我平移和缩放图像时,按钮和文本等其他小部件会覆盖它。

这是我的代码:

class ProductDetail extends StatelessWidget {
  final Product product;
  ProductDetail({this.product});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 10.0),
        child: Column(
          children: [
            SizedBox(
              height: 20
            ),
            SizedBox(
              height: 300,
              width: MediaQuery.of(context).size.width -20,
              child: InteractiveViewer(
                child: Hero(
                    tag: product.id,
                    child: Carousel(
                        autoplay: false,
                        boxFit: BoxFit.cover,
                        dotBgColor: Colors.transparent,
                        dotColor: Colors.black.withOpacity(0.5),
                        images: [
                          AssetImage(product.imageUrl),
                          AssetImage(product.imageUrl),
                          AssetImage(product.imageUrl),
                      ],
                    ),
                ),
              ),
            ),
            SizedBox(
                width: MediaQuery.of(context).size.width -20,
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Row(
                    children: [
                      Text(
                        '₹ ${product.price}',
                        style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
                      ),
                      Text(
                        '₹ ${product.price}',
                        style: TextStyle(
                            fontSize: 14,
                            fontWeight: FontWeight.bold,
                            decoration: TextDecoration.lineThrough,
                            color: Colors.grey
                        ),
                      ),
                    ],
                  ),
                ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  SizedBox(
                      child: ElevatedButton(
                        onPressed: () {},
                        style: ButtonStyle(
                          backgroundColor: MaterialStateProperty.all<Color>(getColorFromHex('#d1d1d1')),
                        ),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Icon(Icons.add_shopping_cart),
                            Text("Add to Cart", style: TextStyle(fontSize: 18)),
                          ],
                        ),
                      )
                  ),
                  SizedBox(
                    child: ElevatedButton(
                      onPressed: () {},
                      style: ButtonStyle(
                          backgroundColor: MaterialStateProperty.all<Color>(getColorFromHex('#56a8e2')),
                      ),
                      child: Row(
                        children: [
                          Icon(Icons.shopping_bag),
                          Text("Buy Now", style: TextStyle(fontSize: 18)),
                        ],
                      ),
                    )
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

当我使用 InteractiveViewer 平移或缩放图像时,如何隐藏文本和按钮等其他小部件?

【问题讨论】:

    标签: flutter


    【解决方案1】:
    1. InteractiveViewer 有两个属性 onInteractionStart 和 onInteractionEnd。

    onInteractionStart → void Function(ScaleStartDetails details) : 调用 当用户在小部件上开始平移或缩放手势时。

    onInteractionEnd → void Function(ScaleEndDetails details) : 调用 当用户在小部件上结束平移或缩放手势时。

    1. 您需要使用 Visibility 小部件包装您希望隐藏的小部件。
    2. 当用户启动 (onInteractionStart) 并停止平移或缩放 (onInteractionEnd) 时,您可以设置 - 重置包装在 Visibility 小部件下的小部件的可见性。

    请查看下面的代码,我必须进行一些更改才能使其正常工作:

    import 'package:carousel_pro/carousel_pro.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MaterialApp(
        debugShowCheckedModeBanner: false,
        home: MyApp(),
      ));
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: ProductDetail(),
          ),
        );
      }
    }
    
    class ProductDetail extends StatefulWidget {
      ProductDetail({products});
    
      @override
      _ProductDetailState createState() => _ProductDetailState();
    }
    
    class _ProductDetailState extends State<ProductDetail> {
      bool _visible = true;
      TransformationController controller = TransformationController();
    
      final Products products = Products(
          id: 10,
          imageUrl:
              "https://cdn.pixabay.com/photo/2020/10/01/17/11/temple-5619197_960_720.jpg",
          price: 20.00);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0),
            child: Column(
              children: [
                SizedBox(height: 20),
                SizedBox(
                  height: 300,
                  width: MediaQuery.of(context).size.width - 20,
                  child: InteractiveViewer(
                    transformationController: controller,
                    onInteractionStart: (scale) {
                      setState(() => _visible = false);
                    },
                    onInteractionEnd: (scale) {
                      setState(() {
                         controller.value = Matrix4.identity();
                         _visible = true;
                      });
                    },
                    child: Hero(
                      tag: products.id,
                      child: Carousel(
                        autoplay: false,
                        boxFit: BoxFit.cover,
                        dotBgColor: Colors.transparent,
                        dotColor: Colors.black.withOpacity(0.5),
                        images: [
                          NetworkImage(products.imageUrl),
                          NetworkImage(products.imageUrl),
                          NetworkImage(products.imageUrl),
                        ],
                      ),
                    ),
                  ),
                ),
                Visibility(
                  visible: _visible,
                  child: SizedBox(
                    width: MediaQuery.of(context).size.width - 20,
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Row(
                        children: [
                          Text(
                            '₹ ${products.price.toString()}',
                            style: TextStyle(
                                fontSize: 25, fontWeight: FontWeight.bold),
                          ),
                          Text(
                            '₹ ${products.price.toString()}',
                            style: TextStyle(
                                fontSize: 14,
                                fontWeight: FontWeight.bold,
                                decoration: TextDecoration.lineThrough,
                                color: Colors.grey),
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
                Visibility(
                  visible: _visible,
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: [
                        SizedBox(
                            child: ElevatedButton(
                          onPressed: () {},
                          style: ButtonStyle(
                            backgroundColor:
                                MaterialStateProperty.all<Color>(Colors.cyanAccent),
                          ),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Icon(Icons.add_shopping_cart),
                              Text("Add to Cart", style: TextStyle(fontSize: 18)),
                            ],
                          ),
                        )),
                        SizedBox(
                            child: ElevatedButton(
                          onPressed: () {},
                          style: ButtonStyle(
                            backgroundColor:
                                MaterialStateProperty.all<Color>(Colors.limeAccent),
                          ),
                          child: Row(
                            children: [
                              Icon(Icons.shopping_bag),
                              Text("Buy Now", style: TextStyle(fontSize: 18)),
                            ],
                          ),
                        )),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class Products {
      final int id;
      final String imageUrl;
      final double price;
      Products({
        this.id,
        this.imageUrl,
        this.price,
      });
    
      Products copyWith({
        int id,
        String imageUrl,
        double price,
      }) {
        return Products(
          id: id ?? this.id,
          imageUrl: imageUrl ?? this.imageUrl,
          price: price ?? this.price,
        );
      }
    }
    

    【讨论】:

    • 感谢您的努力,非常感谢!这确实解决了我的问题,但只是在一定程度上。缩放后,当我离开屏幕触摸时,按钮和其他小部件再次出现。你有解决办法吗?
    • 可见性在用户交互开始时设置为 false,在用户交互结束时重置为 true。如果您不希望按钮和小部件再次可见,请不要添加以下代码: onInteractionEnd: (scale) { setState(() { setState(() => _visible = true); }); },
    • 当图像被放大然后用户离开屏幕触摸并且图像没有被缩小时,小部件重新出现在(缩放的)图像上......
    • 我已经更新了代码。现在,当用户离开屏幕时,图像将重置为原始大小,并且按钮再次可见。通过设置controller.value = Matrix4.identity(); 来重置图像大小
    猜你喜欢
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    相关资源
    最近更新 更多