在Flutter 3.7中,CupertinoPicker跳过桌面(Windows)中的项目

vof42yt1  于 2023-01-31  发布在  Flutter
关注(0)|答案(1)|浏览(163)

自从更新到Flutter 3.7后,我无法在我的CupertienoPicker中选择某些项目。
要重现此问题,请在Windows桌面中运行以下代码:

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  int _index = 0;

  List<String> team = <String>["Olaf","Victor","Rita"] ;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: CupertinoPicker(
            itemExtent: 50,
            onSelectedItemChanged: (selectedIndex) {
              _index = selectedIndex;
            },
            children: List.generate(team.length, (index) {
              return Text(team[index]);
            }),
        ),
      ),
    );
  }
}

An issue已经在github中归档了。

flvlnr44

flvlnr441#

这个问题实际上似乎是最新的Flutter 3.7中的一个bug。
作为一种变通方法,我必须向CupertinoPickerscrollerController添加一个侦听器,并按如下所示编程执行跳转

var c = FixedExtentScrollController();
c.addListener(() {
  if (previousIndex != c.selectedItem) {
    isScrollDown = previousIndex<c.selectedItem;
    isScrollUp = previousIndex>c.selectedItem;

    var previousIndexTemp = previousIndex;
    previousIndex = c.selectedItem;

    if (isScrollUp) {
      c.jumpToItem(previousIndexTemp - 1);
    } else if (isScrollDown) {
      c.jumpToItem(previousIndexTemp + 1);
    }
  }
});

...

CupertinoPicker(
  scrollController: c,
...

下面是应用上述变通方法的上述代码的修改版本:

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  int _index = 0;
  int previousIndex = 0;
  bool isScrollUp = false;
  bool isScrollDown = true;

  List<String> team = <String>["Olaf","Victor","Rita"] ;

  FixedExtentScrollController c = FixedExtentScrollController();

  @override
  void initState() {
    c.addListener(_manageScroll);

    super.initState();
  }

  void _manageScroll () {
    if (previousIndex != c.selectedItem) {
      isScrollDown = previousIndex<c.selectedItem;
      isScrollUp = previousIndex>c.selectedItem;

      var previousIndexTemp = previousIndex;
      previousIndex = c.selectedItem;

      if (isScrollUp) {
        c.jumpToItem(previousIndexTemp - 1);
      } else if (isScrollDown) {
        c.jumpToItem(previousIndexTemp + 1);
      }
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: CupertinoPicker(
          scrollController: c,
            itemExtent: 50,
            onSelectedItemChanged: (selectedIndex) {
              _index = selectedIndex;
            },
            children: List.generate(team.length, (index) {
              return Text(team[index]);
            }),
        ),
      ),
    );
  }
}

相关问题