在flutter中如何让平移手势的内部widget不会与PageView冲突

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

我在 PageView 中有一个带有平移手势的小部件,并且 PageView 可以水平滚动,当我水平平移小部件时,PageView 会移动。

我期望的是平移手势可以移动页面视图中的小部件,而不是移动页面视图

这是图片。

enter image description here

这是演示代码”

import 'package:flutter/material.dart';


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

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView.builder(
        itemBuilder: (ctx, index) {
          return ChildPage(
            index: index,
          );
        },
        itemCount: 2,
      ),
    );
  }
}

class ChildPage extends StatefulWidget {
  final int index;

  const ChildPage({Key? key, required this.index}) : super(key: key);

  @override
  _ChildPageState createState() => _ChildPageState();
}

class _ChildPageState extends State<ChildPage> {
  Offset offset = Offset.zero;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        alignment: Alignment.center,
        children: [
          Positioned(
              top: offset.dy,
              left: offset.dx,
              child: GestureDetector(
                onPanUpdate: (details) {
                  print("hh");
                  offset = offset.translate(details.delta.dx, details.delta.dy);
                  setState(() {});
                },
                child: Container(
                  color: Colors.yellow,
                  width: 100,
                  height: 100,
                ),
              ))
        ],
      ),
    );
  }
}

android ios flutter flutter-layout flutter-pageview
2个回答
0
投票

使用RawGestureDetector,并使用水平和垂直手势来避免此解决方案


0
投票

我最近遇到了同样的问题,可能回答有点晚了,但希望对其他人有帮助。

你可以使用Listener来监听手势来控制PageView的物理。

代码:


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

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _isWidgetDragging = false;

  void _setWidgetDragging(bool isDragging) {
    setState(() {
      _isWidgetDragging = isDragging;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView.builder(
        physics:
            _isWidgetDragging ? const NeverScrollableScrollPhysics() : null,
        itemBuilder: (ctx, index) {
          return ChildPage(
            index: index,
            setWidgetDragging: _setWidgetDragging,
          );
        },
        itemCount: 2,
      ),
    );
  }
}

class ChildPage extends StatefulWidget {
  final int index;
  final Function(bool) setWidgetDragging;

  const ChildPage(
      {super.key, required this.index, required this.setWidgetDragging});

  @override
  _ChildPageState createState() => _ChildPageState();
}

class _ChildPageState extends State<ChildPage> {
  Offset offset = Offset.zero;
  bool isDragging = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Center(child: Text('Page ${widget.index}')),
          Positioned(
            left: offset.dx,
            top: offset.dy,
            child: Listener(
              onPointerDown: (event) {
                isDragging = true;
                widget.setWidgetDragging(true);
              },
              onPointerUp: (event) {
                isDragging = false;
                widget.setWidgetDragging(false);
              },
              onPointerCancel: (event) {
                isDragging = false;
                widget.setWidgetDragging(false);
              },
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onPanUpdate: (details) {
                  if (isDragging) {
                    setState(() {
                      offset += details.delta;
                    });
                  }
                },
                child: Container(
                  width: 100,
                  height: 100,
                  color: Colors.yellow,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.