【问题标题】:Enable to swipe only in certain widget in Flutter启用仅在 Flutter 中的某些小部件中滑动
【发布时间】:2020-10-03 16:01:32
【问题描述】:

我在 Flutter 中看到了一个 PageView,它可以正确地在不同页面之间滑动。但是我们可以在当前页面的任意位置滑动以向左或向右移动。但我的问题是只在特定区域左右滑动。如何实现?

在上图中,我只想在蓝色容器中向左或向右滑动。

【问题讨论】:

标签: flutter flutter-layout


【解决方案1】:

我能够通过以下代码得到上述问题的解决方案:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AccountScreen(),
    );
  }
}

class AccountScreen extends StatefulWidget {
  @override
  _AccountScreenState createState() => _AccountScreenState();
}

class _AccountScreenState extends State<AccountScreen> {
  PageController _bannerController = PageController(
    initialPage: 0,
  );

  PageController _contentController = PageController(
    initialPage: 0,
  );

  @override
  void dispose() {
    _bannerController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          Expanded(
            flex: 1,
            child: PageView(
              controller: _bannerController,
              onPageChanged: (int value) {
                _contentController.animateToPage(value,
                    duration: Duration(milliseconds: 400),
                    curve: Curves.easeInOut);
              },
              children: [
                MyPage1Widget(),
                MyPage2Widget(),
              ],
            ),
          ),
          Expanded(
            flex: 2,
            child: PageView(
              physics: NeverScrollableScrollPhysics(),
              controller: _contentController,
              children: [
                MyPage1Widget(),
                MyPage2Widget(),
              ],
            ),
          )
        ],
      ),
    );
  }
}

class MyPage1Widget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("Page 1"),
    );
  }
}

class MyPage2Widget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text("Page 2"),
    );
  }
}

如果有比这更好的解决方案,请告诉我。

【讨论】:

    【解决方案2】:
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: AccountScreen(),
        );
      }
    }
    
    class AccountScreen extends StatefulWidget {
      @override
      _AccountScreenState createState() => _AccountScreenState();
    }
    
    class _AccountScreenState extends State<AccountScreen> {
      PageController _contentController = PageController(
        initialPage: 0,
      );
    
      @override
      void dispose() {
        _contentController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return PageView(
          controller: _contentController,
          physics: AlwaysScrollableScrollPhysics(),
          children: [
            //They are different just to see different approaches
            MyPage3Widget(),
            MyPage4Widget(),
          ],
        );
      }
    }
    
    class MyPage3Widget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Material(
          child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Container(color: Colors.blue, height: 200),
            Expanded(
              child: GestureDetector(
                  onHorizontalDragUpdate: (_) {}, //This does the trick
                  child: Container(
                      color: Colors.transparent,
                      child: Center(child: Text("Page 2")))),
            )
          ],
        )
        );
      }
    }
    
    class MyPage4Widget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(), //it will scroll only when dragging the AppBar as if it were your banner
          body: GestureDetector(
            onHorizontalDragUpdate: (_) {}, //This does the trick
            child: Container(
              color: Colors.transparent,
              child: Center(child: Text("Page 2"))
            )
          ),
        );
      }
    }
    

    将 GestureDetector 添加到您不希望用户使用空手势滚动的身体部位(onHorizo​​ntalDragUpdate 因为您不想水平拖动)欺骗 Gesture Arena 认为手势检测器是想要的做某事。使用透明颜色的 Container 来填充所有可用空间(如果我只使用 Center 或 Text,它只会包装该文本,请检查颤振检查器以查看整个区域)。

    比较您的示例的优势:

    • 只有一个PageController
    • 动画移动流畅,当移动横幅时,pageView 随之移动

    【讨论】:

      猜你喜欢
      • 2020-07-30
      • 1970-01-01
      • 2012-12-07
      • 2020-12-07
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 2020-11-14
      • 1970-01-01
      相关资源
      最近更新 更多