启用仅在Flutter中的某些小部件中滑动

时间:2020-06-14 03:12:14

标签: flutter flutter-layout

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

enter image description here

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

2 个答案:

答案 0 :(得分:0)

我可以使用以下代码来解决上述问题:

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"),
    );
  }
}

让我知道是否有比这更好的解决方案。

答案 1 :(得分:0)

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认为手势检测器是您想要的手势检测器做某事。使用透明颜色的容器填充所有可用空间(如果我仅使用居中或文本,它将仅包裹该文本,请检查颤动检查器以查看整个区域)。

比较您的示例的优势:

  • 只有一个PageController
  • 动画平滑移动,移动横幅时,pageView随之移动