ListTile OnTap is working when I use ListView. But when i use ListWheelScrollView it doesnt work

我怕爱的太早我们不能终老 提交于 2021-02-09 11:07:08

问题


ListTile OnTap is working when I use ListView. But when i use ListWheelScrollView it doesn't work. I mean it doesn't get tapped. The view changes. But i can't seem to tap it. I looked for the solution in a lot of places and links but still couldn't find the solutions.

These are the code I did.

@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();
  }

And this is where I have built the 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)
    );

  }

In the above code the list items doesn't get tapped. But if i replace the ListWheelScrollView with ListView as shown below, it works perfectly.

@override
  Widget build(BuildContext context) {
    return new ListView(
      children: getPostList(),
    );
  }

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

回答1:


Update: Another look no update yet from the flutter team but another hack solution. By wrapping the whole listscrollwheel widget with a Gesturedetector. Every scroll sets the state using the "onSelectedItemChanged" for listscrollview. But the gesture detector widget does something with it only on tap.

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



回答2:


I had the same issue If you still want to use a ListWheelScrollView and not a ListView in your case,

You can wrap the ListWheelScrollView inside a GestureDetector, and make a List of your _postModals. use the onSelectedItemChanged to determine which list item index that is currently selected , then create a global Index variable. Here is an example of what I mean :

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(),

    ],
  ),
);
}
}

and in your ListTile :

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

I used this way because I still like the wheel appearance and I don't want to convert to a ListView, but try not to make the diameter of the ListWheelScrollView so large to keep the tapping functionality work as expected.

Edit : If you want multiple items to be clickable (the 3 or 4 visible items), you can wrap the ListWheelScrollView in a stack with 3 or 4 Gesture detectors. Then use Index-1 and Index+1 , ...etc



来源:https://stackoverflow.com/questions/56255739/listtile-ontap-is-working-when-i-use-listview-but-when-i-use-listwheelscrollvie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!