0

基本上我有一个带有元素的滑动屏幕,用户可以在其中向左或向右滑动。当用户滑动时,我调用了一些函数。我GestureDetector用于手势识别和PageView.Custom我的物品。可能ListView.Custom也有效,但它不能解决我的问题。

我需要一个PageController,因为我必须以编程方式控制导航。而且我认为这PageController可能是我的函数被多次调用的问题背后的原因。如何解决?有人知道为什么setstate经常被调用以及如何防止它吗?

我为您提供了一个完整的工作示例(缩小版),其中包含向右滑动操作的打印,您可以在其中看到它的beeing 被多次调用。

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {


  int currentIndex = 0;
  @override
  Widget build(BuildContext context) {
    // Page selector for tab list
    void _selectPage(int index) {
      print('page index: $index');
      setState(() {
        currentIndex = index;
      });
    }


    // Routes list for tab navigation Android
    final List<Widget> _pages = [
      ScreenA(),
      ScreenB(func: _selectPage),
    ];

    return Scaffold(
      appBar: AppBar(),
      body: _pages[currentIndex],
      bottomNavigationBar: SafeArea(
        child: BottomNavigationBar(
          onTap: _selectPage,
          iconSize: 22,
          currentIndex: currentIndex,
          type: BottomNavigationBarType.fixed,
          items: [
            BottomNavigationBarItem(
              backgroundColor: Theme.of(context).primaryColor,
              icon: Icon(Icons.description),
              label: 'ScreenA',
            ),
            BottomNavigationBarItem(
                backgroundColor: Theme.of(context).primaryColor,
                icon: Icon(Icons.ac_unit_outlined),
                label: 'ScreenB'),
          ],
        ),
      ),
    );
  }
}

class ScreenA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('HOME'),
    );
  }
}

class ScreenB extends StatefulWidget {
  Function func;
  ScreenB({Key key, @required this.func})
      : super(key: key);
  @override
  _ScreenBState createState() => _ScreenBState();
}

class _ScreenBState extends State<ScreenB> {
  _ScreenBState();

  var _controller = PageController();


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          IconButton(
            icon: Icon(Icons.access_alarm_sharp),
            onPressed: () async {
              widget.func(0);
            },
          ),
        ],
      ),
      body: PageView.custom(
          dragStartBehavior: DragStartBehavior.start,
          controller: _controller,
          physics: NeverScrollableScrollPhysics(),
          scrollDirection: Axis.horizontal,
          childrenDelegate: SliverChildBuilderDelegate((ctx, pageIndex) =>
              GestureDetector(
                  onPanUpdate: (details) async {
                    if (details.delta.dx < 0) {
                      _controller.nextPage(
                          duration: Duration(milliseconds: 200),
                          curve: Curves.easeInOut);

                      print('function called');
                    }
                  },
                  child: Center(
                      child: Container(
                          width: 200,
                          height: 200,
                          color: Colors.red,
                          child: Text('hi')))))),
    );
  }
}

提前致谢!

4

1 回答 1

0

请将此功能写出小部件构建功能

// Page selector for tab list
void _selectPage(int index) {
  print('page index: $index');
  setState(() {
    currentIndex = index;
  });
}

像这样

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {


  int currentIndex = 0;


    // Page selector for tab list
    void _selectPage(int index) {
      print('page index: $index');
      setState(() {
        currentIndex = index;
      });
    }


    // Routes list for tab navigation Android
    final List<Widget> _pages = [
      ScreenA(),
      ScreenB(func: _selectPage),
    ];

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(),
      body: _pages[currentIndex],
      bottomNavigationBar: SafeArea(
        child: BottomNavigationBar(
          onTap: _selectPage,
          iconSize: 22,
          currentIndex: currentIndex,
          type: BottomNavigationBarType.fixed,
          items: [
            BottomNavigationBarItem(
              backgroundColor: Theme.of(context).primaryColor,
              icon: Icon(Icons.description),
              label: 'ScreenA',
            ),
            BottomNavigationBarItem(
                backgroundColor: Theme.of(context).primaryColor,
                icon: Icon(Icons.ac_unit_outlined),
                label: 'ScreenB'),
          ],
        ),
      ),
    );
  }
}

class ScreenA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('HOME'),
    );
  }
}

class ScreenB extends StatefulWidget {
  Function func;
  ScreenB({Key key, @required this.func})
      : super(key: key);
  @override
  _ScreenBState createState() => _ScreenBState();
}

class _ScreenBState extends State<ScreenB> {
  _ScreenBState();

  var _controller = PageController();


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          IconButton(
            icon: Icon(Icons.access_alarm_sharp),
            onPressed: () async {
              widget.func(0);
            },
          ),
        ],
      ),
      body: PageView.custom(
          dragStartBehavior: DragStartBehavior.start,
          controller: _controller,
          physics: NeverScrollableScrollPhysics(),
          scrollDirection: Axis.horizontal,
          childrenDelegate: SliverChildBuilderDelegate((ctx, pageIndex) =>
              GestureDetector(
                  onPanUpdate: (details) async {
                    if (details.delta.dx < 0) {
                      _controller.nextPage(
                          duration: Duration(milliseconds: 200),
                          curve: Curves.easeInOut);

                      print('function called');
                    }
                  },
                  child: Center(
                      child: Container(
                          width: 200,
                          height: 200,
                          color: Colors.red,
                          child: Text('hi')))))),
    );
  }
}
于 2020-11-05T06:59:46.520 回答