首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何修复SingleChildScrollView和InteractiveViewer手势冲突

如何修复SingleChildScrollView和InteractiveViewer手势冲突
EN

Stack Overflow用户
提问于 2022-10-20 09:14:07
回答 2查看 60关注 0票数 0

我在InteractiveViewer中使用SingleChildScrollView,这是我的完整代码:

代码语言:javascript
运行
复制
import 'package:flutter/material.dart';
import '../constants/images.dart';

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

class MyApp extends StatelessWidget {
  final List<String> images = [Images.IMG1, Images.IMG2, Images.IMG3];

  MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SingleChildScrollView(
          child: Column(
            children: [
              for (var image in images) ...[
                SizedBox(width:double.infinity,child: Divider(thickness: 5,)),
                Row(
                  children: [
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: ClipOval(
                        child: CircleAvatar(
                          radius: 24,
                          child: Image.asset(Images.PROFILE_IMAGE),
                        ),
                      ),
                    ),
                    Text('User1'),
                  ],
                ),
                InteractiveViewer(
                    child: Image.asset(
                  image,
                  fit: BoxFit.fitWidth,
                )),
                Row(
                  children: [
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Icon(Icons.favorite),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Icon(Icons.comment),
                    ),
                  ],
                )
              ]
            ],
          ),
        ),
      ),
    );
  }
}

问题是,当我试图放大或放大我的InteractiveViewer时,它通常不会在第一次尝试中工作,而且我需要在不同的触摸位置上尝试5-6次才能工作,在SingleChildScrollView中使用InteractiveViewer是非常困难的,但是它在没有SingleChildScrollView的情况下工作非常完美,请参见下面的剪辑:

有什么解决办法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-22 12:52:43

SingleChildScrollViewInteractiveViewer之间似乎有一场斗争,想要采取触控行动。

以Instagram的滚动机制为例,如果我们将两个手指放在柱子上并尝试滚动,滚动操作将不会完成,并且滚动将被暂时禁用。所以,如果我们能检测到这种两指触摸动作:

感谢:https://stackoverflow.com/a/72421013/14083299

我们可以禁用滚动,然后放大/关闭。

下面是一个示例代码:

代码语言:javascript
运行
复制
import 'package:flutter/material.dart';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final List<String> images = [
    'assets/prof2.jpg',
    'assets/prof2.jpg',
    'assets/prof2.jpg'
  ];

  final events = [];
  bool canScroll = true;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: SingleChildScrollView(
          physics: canScroll
              ? const ScrollPhysics()
              : const NeverScrollableScrollPhysics(),
          child: Listener(
            onPointerDown: (event) {
              events.add(event.pointer);
              print("new event");
            },
            onPointerUp: (event) {
              events.clear();
              print("events cleared");
              setState(() {
                canScroll = true;
              });
            },
            onPointerMove: (event) {
              if (events.length == 2) {
                setState(() {
                  canScroll = false;
                });
                //   int sensitivity = 8;
                //   if (event.delta.dy > sensitivity) {
                //     // code for two finger swipe up event

                //   } else if (event.delta.dy < -sensitivity) {
                //     // code for two finger swipe down event

                //   }
              }
            },
            child: Container(
              child: Column(
                children: [
                  for (var image in images) ...[
                    const SizedBox(
                        width: double.infinity,
                        child: Divider(
                          thickness: 5,
                        )),
                    Row(
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: ClipOval(
                            child: CircleAvatar(
                              radius: 24,
                              child: Image.asset('assets/prof2.jpg'),
                            ),
                          ),
                        ),
                        const Text('User1'),
                      ],
                    ),
                    InteractiveViewer(
                        child: Image.asset(
                      image,
                      fit: BoxFit.fitWidth,
                    )),
                    Row(
                      children: const [
                        Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Icon(Icons.favorite),
                        ),
                        Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Icon(Icons.comment),
                        ),
                      ],
                    )
                  ]
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
票数 1
EN

Stack Overflow用户

发布于 2022-10-23 10:28:58

多亏了@samad的回答,我终于用Listener修复了这个问题。

示例代码:

代码语言:javascript
运行
复制
        //First define _pointersCount=0 in your state class.
        Listener(
          onPointerDown: (_) => setState(() => _pointersCount++),
          onPointerUp: (_) => setState(() => _pointersCount--),
          child: ListView(
            physics: _pointersCount == 2 ? const NeverScrollableScrollPhysics() : null,
            children: [], //InteractiveViewer widgets here
        )),

这是@samad代码中的优化代码:

代码语言:javascript
运行
复制
class MyApp2 extends StatefulWidget {
  MyApp2({Key? key}) : super(key: key);

  @override
  State<MyApp2> createState() => _MyApp2State();
}

class _MyApp2State extends State<MyApp2> {
  final List<String> images = [Images.IMG1, Images.IMG2, Images.IMG3];
  int _pointersCount = 0;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Listener(
          onPointerDown: (_) => setState(() => _pointersCount++),
          onPointerUp: (_) => setState(() => _pointersCount--),
          child: ListView(
            physics: _pointersCount == 2 ? const NeverScrollableScrollPhysics() : null,
            children: [
              for (var image in images) ...[
                const SizedBox(width: double.infinity, child: Divider(thickness: 5)),
                Row(
                  children: [
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: ClipOval(
                        child: CircleAvatar(
                          radius: 24,
                          child: Image.asset(Images.PROFILE_IMAGE),
                        ),
                      ),
                    ),
                    const Text('User1'),
                  ],
                ),
                InteractiveViewer(child: Image.asset(image, fit: BoxFit.fitWidth)),
                Row(
                  children: const [
                    Padding(padding: EdgeInsets.all(8.0), child: Icon(Icons.favorite)),
                    Padding(padding: EdgeInsets.all(8.0), child: Icon(Icons.comment)),
                  ],
                )
              ]
            ],
          ),
        ),
      ),
    );
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74137284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档