Flutter 当我的手势检测器';ListTile的尾部是什么?

Flutter 当我的手势检测器';ListTile的尾部是什么?,flutter,Flutter,我有一个带有ListTile的ListView和我的IconToggle,它在我的ListTile的尾部有一个手势检测器。但是当我试图点击图标时,我点击了列表?为什么会这样?我想能够点击我的切换,并让它切换到活动图标的图标 列表 return ListTile ( title: Text( arguments.groups[index], style: Theme.of(context).textTheme.body1, ), onTap: () => onGr

我有一个带有ListTile的ListView和我的IconToggle,它在我的ListTile的尾部有一个手势检测器。但是当我试图点击图标时,我点击了列表?为什么会这样?我想能够点击我的切换,并让它切换到活动图标的图标

列表

return ListTile
(
  title: Text(
    arguments.groups[index],
    style: Theme.of(context).textTheme.body1,
  ),
  onTap: () => onGroupTap(arguments.groups[index]),
  trailing: IconToggle(
    isActive: false,
    active: Icon
    (
      Icons.notifications,
      color: Theme.of(context).iconTheme.color,
    ),
    deactive: Icon
    (
      Icons.notifications_off,
      color: Theme.of(context).accentColor,
    ),
  ),
);
图标切换

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

class IconToggle extends StatefulWidget {

  bool isActive = true;
  final Icon active;
  final Icon deactive;
  final Function(bool) onChanged;

  IconToggle({this.isActive,  @required this.active,  @required this.deactive, this.onChanged}) 
  : assert(isActive != null), 
  assert(active != null), 
  assert(deactive != null);

  @override
  _IconToggleState createState() => _IconToggleState();
}

class _IconToggleState extends State<IconToggle> {

  _showIcon()
  {
    return widget.isActive ? widget.active : widget.deactive;
  }

  _toggle()
  {
    setState(() {
      widget.isActive = !widget.isActive;
      if(widget.onChanged != null)
        widget.onChanged(widget.isActive);
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector
    ( 
      child: _showIcon(),
      onTap: _toggle(),
    );
  }
}
导入“包装:颤振/材料.省道”;
进口“包装:颤振/基础.dart”;
类IContogle扩展StatefulWidget{
bool isActive=true;
最终图标激活;
最终图标无效;
最终功能(bool)一旦更改;
IconToggle({this.isActive,@required this.active,@required this.deactive,this.onChanged})
:assert(isActive!=null),
断言(活动!=null),
断言(deactive!=null);
@凌驾
_IContogolgEstate createState()=>\u IContogolgEstate();
}
类_ICONTOGGESTATE扩展状态{
_showIcon()
{
return widget.isActive?widget.active:widget.deactive;
}
_切换()
{
设置状态(){
widget.isActive=!widget.isActive;
if(widget.onChanged!=null)
widget.onChanged(widget.isActive);
});
}
@凌驾
小部件构建(构建上下文){
返回手势检测器
( 
子项:_showIcon(),
onTap:_toggle(),
);
}
}

您可以复制粘贴运行下面的完整代码
步骤1:将
手势检测器移动到
尾随

步骤2:将
toggle()
逻辑置于
didUpdateWidget

步骤3:使用本地bool
isActive
not
widget.isActive

trailing: GestureDetector(
                    onTap: () {
                      print("trailing ontap");
                      setState(() {

                      });
                    },
                    child: IconToggle(

...
@override
  void didUpdateWidget(IconToggle oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("didUpdateWidget ${isActive}");
    isActive = !isActive;
    if (widget.onChanged != null) widget.onChanged(isActive);
  }
工作演示

完整代码

import 'package:flutter/material.dart';

class IconToggle extends StatefulWidget {
  bool isActive = true;
  final Icon active;
  final Icon deactive;
  final Function(bool) onChanged;

  IconToggle(
      {this.isActive,
      @required this.active,
      @required this.deactive,
      this.onChanged})
      : assert(isActive != null),
        assert(active != null),
        assert(deactive != null);

  @override
  _IconToggleState createState() => _IconToggleState();
}

class _IconToggleState extends State<IconToggle> {
  bool isActive = false;

  _showIcon() {
    print("showIcon");
    return isActive ? widget.active : widget.deactive;
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    isActive = widget.isActive;
  }
  /*_toggle() {
    print("toggle");
    setState(() {
      widget.isActive = !widget.isActive;
      if (widget.onChanged != null) widget.onChanged(widget.isActive);
    });
  }*/

  @override
  void didUpdateWidget(IconToggle oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("didUpdateWidget ${isActive}");
    isActive = !isActive;
    if (widget.onChanged != null) widget.onChanged(isActive);
  }

  @override
  Widget build(BuildContext context) {
    return _showIcon();
  }
}

void main() => runApp(MyApp());

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ListTile(
              title: Text(
                "arguments.groups[index]",
                style: Theme.of(context).textTheme.body1,
              ),
              onTap: () => print("onGroupTap(arguments.groups[index])"),
              trailing: GestureDetector(
                onTap: () {
                  print("trailing ontap");
                  setState(() {

                  });
                },
                child: IconToggle(
                  isActive: false,
                  onChanged: (isActive) {
                    print("execute onChange $isActive");
                  },
                  active: Icon(
                    Icons.notifications,
                    color: Theme.of(context).iconTheme.color,
                  ),
                  deactive: Icon(
                    Icons.notifications_off,
                    color: Theme.of(context).accentColor,
                  ),
                ),
              ),
            ),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
类IContogle扩展StatefulWidget{
bool isActive=true;
最终图标激活;
最终图标无效;
最终功能(bool)一旦更改;
易变(
{this.isActive,
@需要这个。激活,
@需要这个,
此参数(已更改})
:assert(isActive!=null),
断言(活动!=null),
断言(deactive!=null);
@凌驾
_IContogolgEstate createState()=>\u IContogolgEstate();
}
类_ICONTOGGESTATE扩展状态{
bool isActive=false;
_showIcon(){
打印(“showIcon”);
return isActive?widget.active:widget.deactive;
}
@凌驾
void initState(){
//TODO:实现initState
super.initState();
isActive=widget.isActive;
}
/*_切换(){
打印(“切换”);
设置状态(){
widget.isActive=!widget.isActive;
如果(widget.onChanged!=null)widget.onChanged(widget.isActive);
});
}*/
@凌驾
void didUpdateWidget(IContogle oldWidget){
super.didUpdateWidget(oldWidget);
打印(“didUpdateWidget${isActive}”);
isActive=!isActive;
如果(widget.onChanged!=null)widget.onChanged(isActive);
}
@凌驾
小部件构建(构建上下文){
返回_showIcon();
}
}
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
int _计数器=0;
void _incrementCounter(){
设置状态(){
_计数器++;
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
列表砖(
标题:正文(
“arguments.groups[索引]”,
样式:Theme.of(context).textTheme.body1,
),
onTap:()=>print(“onGroupTap(arguments.groups[index])”,
跟踪:手势检测器(
onTap:(){
打印(“跟踪ontap”);
设置状态(){
});
},
孩子:我要跳(
I:错,
一旦更改:(i活动){
打印(“执行onChange$isActive”);
},
活动:图标(
图标、通知、,
颜色:Theme.of(context).iconTheme.color,
),
停用:图标(
Icons.u关闭,
颜色:主题。背景。强调颜色,
),
),
),
),
正文(
“您已经按了这么多次按钮:”,
),
正文(
“$”计数器“,
风格:Theme.of(context).textTheme.headline4,
),
],
),
),
浮动操作按钮:浮动操作按钮(
按下时:\ u递增计数器,
工具提示:“增量”,
子:图标(Icons.add),
),
);
}
}