使用ListView时,ListTile OnTap正常工作。但当我使用ListWheelScrollView时,它不起作用。

6

当我使用ListView时,ListTile OnTap功能是正常的。但是当我使用ListWheelScrollView时,它就不起作用了。我的意思是无法触发点击。虽然视图会改变,但我似乎无法点击它。我在很多地方和链接中寻找解决方案,但仍然找不到解决方案。

这是我编写的代码:

@override
  Widget build(BuildContext context) {
    return new ListWheelScrollView(
      physics:FixedExtentScrollPhysics(),
      children: getPostList(),
      itemExtent: 100.0,
    );
  }

  List<PostListItem> getPostList() {
    return _postModal
        .map((contact) => new PostListItem(contact))
        .toList();
  }

这就是我创建ListTile的位置

@override
  Widget build(BuildContext context) {
    return new ListTile(
      onTap:  () {
          var route = new MaterialPageRoute(
            builder: (BuildContext context) =>
                new OnTapPost(value: _postModal.fullName),
          );
          Navigator.of(context).push(route);
        },
        leading: new Image.asset('assets/images/logo.png'),
        title: new Text(_postModal.fullName),
        subtitle: new Text(_postModal.email)
    );

  }

在上面的代码中,列表项无法被点击。但是,如果我将ListWheelScrollView替换为ListView,如下所示,它就可以完美地工作了。
@override
  Widget build(BuildContext context) {
    return new ListView(
      children: getPostList(),
    );
  }

  List<PostListItem> getPostList() {
    return _postModal
        .map((contact) => new PostListItem(contact))
        .toList();
  }

1
这可能是一个问题,你现在只能使用另一种类型的列表。请参见 https://github.com/flutter/flutter/issues/38803 - TWL
最终解决方案已经发布了,我想是在这个链接 https://pub.dev/packages/clickable_list_wheel_view。 - Althaf1467
3个回答

1

更新:Flutter团队尚未发布更新,但有另一种hack解决方案。通过使用GestureDetector将整个ListScrollWheel小部件包装起来。每次滚动都使用listscrollview的“onSelectedItemChanged”设置状态。但是手势检测器小部件仅在轻击时才执行操作。

  import 'package:flutter/cupertino.dart';
  import 'package:flutter/material.dart';
   
    
    class ServicesList extends StatefulWidget {
    
      final type;
    
      ServicesList({this.type});
    
      @override
      _ServicesListState createState() => _ServicesListState();
    }
    
    class _ServicesListState extends State<ServicesList> {
    
      double _height ,_width;
      int serviceIndex;
      final FixedExtentScrollController _controller = FixedExtentScrollController();

 

List<Service> serviceList = [
    Service(name: 'service 1'),
    Service(name: 'service 4'),
    Service(name: 'service 3'),

];
    
      @override
      void initState() {
    
        serviceIndex = 0;
        // TODO: implement initState
        super.initState();
      }
    
      detectService(index) {
        print('clicked container : $index'); //do whatever you want with the clicked index
      }
    
    
      @override
      Widget build(BuildContext context) {
    
        _height = MediaQuery.of(context).size.height;
        _width = MediaQuery.of(context).size.width;
               
        return scrollWheel();
      }
    
    
    
      Widget scrollWheel() {
        return GestureDetector(
          onTap: (){
            detectService(serviceIndex);
            },
          child: ListWheelScrollView(
            controller: _controller,
            diameterRatio: 1.5,
            itemExtent: 80,
            onSelectedItemChanged: (e)=>{
    
              setState(() {
                serviceIndex = e;
              })
            },
            magnification: 0.2,
            physics: FixedExtentScrollPhysics(),
            children: serviceList.map((e) {
    
    
                return Container(
                  padding:  const EdgeInsets.all(6.0),
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(10.0),
                    color: Colors.blue,
                  ),
                  child:Text('item $e.name');
                );
          }).toList(), //List of widgets
          ),
        );
      }
    }
  
   class Service {
      String name;
 
     Service( {this.name} );
  }

0

-1

我曾经遇到过同样的问题。如果你仍然想在你的情况下使用ListWheelScrollView而不是ListView,你可以将ListWheelScrollView包装在GestureDetector中,并创建一个_PostModals列表。使用onSelectedItemChanged来确定当前选择的列表项索引,然后创建一个全局索引变量。以下是我的一个示例:

import 'package:flutter/material.dart';

class ListScrollWheelExample extends StatelessWidget {
@override
Widget build(BuildContext context) {

List<PostModal> _postModals = [
  //Add your postModals here
];
int Index;

return GestureDetector(
  onTap: (){
    var route = new MaterialPageRoute(
      builder: (BuildContext context) =>
      new OnTapPost(value: _postModals[Index].fullName),
    );
    Navigator.of(context).push(route);
  },
  child: ListWheelScrollView(
    onSelectedItemChanged: (int index){
      Index = index;
    },
    offAxisFraction: -0.85,
    diameterRatio: 0.75,
    physics: FixedExtentScrollPhysics(),
    itemExtent: 100,
    children: <Widget>[

      getPostList(),

    ],
  ),
);
}
}

在你的ListTile中:

leading: new Image.asset('assets/images/logo.png'),
title: new Text(_postModals[Index].fullName),
subtitle: new Text(_postModals[Index].email)

我使用这种方式是因为我仍然喜欢轮子的外观,而且我不想转换为ListView,但尽量不要使ListWheelScrollView的直径太大,以保持点击功能正常工作。

编辑: 如果您想让多个项目可点击(3或4个可见项目),可以将ListWheelScrollView包装在一个带有3或4个GestureDetector的堆栈中。然后使用Index-1和Index+1等。


这并没有解决问题。问题是关于在列表中点击任何项目,而不仅仅是在ListWheelScrollView中心选择的项目。 - Bryson Thill
我的回答解决了这个问题,因为在我们的情况下,我们使用FixedExtentScrollPhysics(),它的使用主要是为了点击ScrolWheel中的当前项目,并且它不是ListView,不是所有项目都出现在前面。 - Ismaeel Sherif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接