You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中IconButton点击无响应,如何解决该问题?

问题:IconButton点击无反应,无法切换励志名言

我制作了一个IconButton,在Chrome上显示正常,但点击后没有任何反应。正在开发一款励志应用,原本希望点击按钮切换屏幕中间展示的名言,却无法实现该功能,不清楚问题所在。以下是我的代码:

主文件代码

import 'dart:convert';

import 'package:app/count_page.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';


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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {


    return MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.blue,
          splashColor: Colors.transparent,
          highlightColor: Colors.transparent,
        ),
      home:ChangeNotifierProvider(
        create: (BuildContext context) =>  CountPage()
        ,child: Quote() ,)
      );
  }
}

class Quote extends StatelessWidget {
  Quote({Key? key}) : super(key: key);
  late CountPage _countPage;
  @override
  Widget build(BuildContext context) {
    _countPage = Provider.of<CountPage>(context,listen: false);
    String arrayText = '[{"author": "-공자-","message": "멈추지 않으면 얼마나 천천히 가는지는 문제가 되지 않느니라 " },'
        '{"author": "공자","message": "어디를 가든지 마음을 다해 가라" },'
        '{"author": "공자","message": "상처는 잊되, 은혜는 결코 잊지 말라" },'
        '{"author": "공자","message": "한 사람에게서 모든 덕을 구하지 말라" },'
        '{"author": "공자","message": "허물이 있다면, 버리기를 두려워 말라" },'
        '{"author": "공자","message": "절약하지 않는 자는 고통받게 될 것이니라" },'
        '{"author": "공자","message": "앞날을 결정짓고자 한다면 옛것을 공부하라" },'
        '{"author": "공자","message": "지나침은 모자람만 못하다" },'
        '{"author": "공자","message": "스스로 존경하면 다른 사람도 그대를 존경할 것이니라" },'
        '{"author": "공자","message": "흠 없는 조약돌보다는 흠 있는 금강석이 더 나으니라" },'
        '{"author": "나폴레옹","message": "내 사전에 불가능은 없다" },'
        '{"author": "바이런","message": "가장 뛰어난 예언자는 과거이다" },'
        '{"author": "나폴레옹","message": "내 비장의 무기는 아직 손안에 있다" },'
        '{"author": "소크라테스","message": "너 자신을 알라" },'
        '{"author": "아리스토텔레스","message": "많은 벗을 가진 사람은 한 사람의 진실한 벗을 가질 수 없다" },'
        '{"author": "솔론","message": "말은 행동의 거울이다." },'
        '{"author": "플랭클린","message": "백 년을 살 것처럼 일하고" },'
        '{"author": "아리스토텔레스","message": "불행은 진정한 친구가" },'
        '{"author": "생텍쥐베리","message": "사막이 아름다운 것은 어딘가에 샘을 숨기고 있기 때문이다" },'
        '{"author": "파스칼","message": "습관은 제2의 천성으로 제1의 천성을 파괴한다" }]'; 
    List list = jsonDecode(arrayText);


    return Scaffold(
      body:Container(
        color: Colors.white,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Center(child: IconButton(onPressed:(){_countPage.page_down();} , icon:Icon(Icons.chevron_left))),
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Center(
                  child: Container(
                    color: Colors.deepOrange,
                    height: 400,
                    width: 250,
                      child: Center(child: Text(list[_countPage.page]["message"],style: TextStyle(fontSize: 40,color: Colors.black),textAlign: TextAlign.center,))
                  ),
                ),
                Center(child: Text(list[_countPage.page]["author"],style: TextStyle(fontSize: 20,color: Colors.black),)),
              ],
            ),
            Center(child: IconButton(onPressed:(){_countPage.page_up();}, icon:Icon(Icons.chevron_right))),
          ],
        ),
      ) ,
      bottomNavigationBar: BottomAppBar(
        color: Colors.blue,
        child: Container(
          height: 100,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Center(child: IconButton(onPressed: copy, icon:Icon(Icons.settings))),
              Center(child: IconButton(onPressed: share, icon:Icon(Icons.content_copy))),
              Center(child: IconButton(onPressed: option, icon:Icon(Icons.share))),
            ],

          ),

        ),
      ),
    );
  }



  void copy() {
  }

  void share() {
  }

  void option() {
  }
}

CountPage文件代码

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

class CountPage extends ChangeNotifier{
  int _page = 0;
  int get page => _page;

   page_down() {
    _page --;
    notifyListeners();
  }

   page_up() {
    _page ++;
    notifyListeners();
  }
}

这是我第一次在Stack Overflow提问,作为经验不足的开发者,若我的提问方式或代码存在问题,恳请各位不吝指正。


问题分析与修复方案

1. UI未监听状态变化

你的Quote组件是StatelessWidget,且获取CountPage时使用了listen: false,这意味着即使CountPage调用notifyListeners(),组件也不会重新构建,自然看不到名言切换的效果。

修复方式:使用Consumer包裹需要更新的UI部分(性能更优),同时调整按钮的状态调用逻辑:

// 替换Quote组件中Row里的Column部分
Consumer<CountPage>(
  builder: (context, countPage, child) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Center(
          child: Container(
            color: Colors.deepOrange,
            height: 400,
            width: 250,
            child: Center(child: Text(list[countPage.page]["message"],style: TextStyle(fontSize: 40,color: Colors.black),textAlign: TextAlign.center,))
          ),
        ),
        Center(child: Text(list[countPage.page]["author"],style: TextStyle(fontSize: 20,color: Colors.black),)),
      ],
    );
  },
)

移除Quote类中的late CountPage _countPage;和_countPage = Provider.of<CountPage>(context,listen: false);,修改左右按钮的点击事件:

// 左按钮
IconButton(
  onPressed:(){
    Provider.of<CountPage>(context, listen: false).page_down();
  }, 
  icon:Icon(Icons.chevron_left)
),
// 右按钮
IconButton(
  onPressed:(){
    Provider.of<CountPage>(context, listen: false).page_up();
  }, 
  icon:Icon(Icons.chevron_right)
),

2. 数组越界风险

当前page_up和page_down方法没有边界判断,当page减到负数或者超过名言列表长度时,会触发数组越界错误。

修复方式:修改CountPage的方法,添加边界校验,同时在调用时传入列表长度:

// 修改CountPage类
class CountPage extends ChangeNotifier{
  int _page = 0;
  int get page => _page;

  void page_down(int maxIndex) {
    if (_page > 0) {
      _page --;
      notifyListeners();
    }
  }

  void page_up(int maxIndex) {
    if (_page < maxIndex - 1) {
      _page ++;
      notifyListeners();
    }
  }
}

更新按钮的调用逻辑:

// 左按钮
IconButton(
  onPressed:(){
    Provider.of<CountPage>(context, listen: false).page_down(list.length);
  }, 
  icon:Icon(Icons.chevron_left)
),
// 右按钮
IconButton(
  onPressed:(){
    Provider.of<CountPage>(context, listen: false).page_up(list.length);
  }, 
  icon:Icon(Icons.chevron_right)
),

最终效果

修改后,点击左右按钮时,CountPage的page值会在合法范围内更新,Consumer监听状态变化后自动刷新名言内容,实现切换功能,同时避免数组越界错误。


内容的提问来源于stack exchange,提问作者GodHanmin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 02:50:43