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

Flutter实现选项列表选中按钮高亮及其他按钮复位的方案

解决Flutter单选按钮选中变色问题

你的代码核心问题是**selectedIndex定义在build方法内部**,每次调用setState触发页面重绘时,这个变量都会被重新初始化为0,导致选中状态无法被正确保留。同时按钮样式未根据选中状态动态调整,文本也没有对应不同天气选项。

以下是修正后的完整代码:

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:trailx_app/const/colors.dart';

class SignUpWeatherQ extends StatefulWidget {
  const SignUpWeatherQ({super.key});

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

class _SignUpWeatherQ extends State<SignUpWeatherQ> {
  // 将selectedIndex提升为类成员变量,初始值设为-1表示未选中任何选项
  int selectedIndex = -1;
  // 定义天气选项列表
  final List<String> weatherOptions = ['Sunny', 'Cloudy', 'Rainy', 'Windy', 'Snowy'];

  @override
  void initState() {
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: backgroundColor,
        body: Padding(
            padding: const EdgeInsets.all(16),
            child: GridView.builder(
              physics: const ClampingScrollPhysics(),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 1),
              itemCount: weatherOptions.length,
              itemBuilder: (context, index) {
                // 判断当前按钮是否被选中
                bool isSelected = selectedIndex == index;
                return ElevatedButton(
                  style: ButtonStyle(
                    // 设置按钮背景色:选中时用高亮色,未选中时用默认背景色
                    backgroundColor: MaterialStateProperty.all(
                      isSelected ? Colors.blueAccent : backgroundColor,
                    ),
                    // 设置按钮文本颜色:选中时用亮色,未选中时用默认文本色
                    foregroundColor: MaterialStateProperty.all(
                      isSelected ? Colors.white : loginTextColor,
                    ),
                    // 可选:添加边框区分选中状态
                    side: MaterialStateProperty.all(
                      BorderSide(
                        color: isSelected ? Colors.blueAccent : Colors.grey.shade300,
                        width: 2,
                      ),
                    ),
                  ),
                  onPressed: () => setState(() {
                    selectedIndex = index;
                  }),
                  child: Text(
                    weatherOptions[index],
                    style: GoogleFonts.getFont(
                      'Inter',
                      textStyle: const TextStyle(
                          fontWeight: FontWeight.w400,
                          letterSpacing: 0.6,
                          wordSpacing: 1,
                          fontSize: 20),
                    ),
                  ),
                );
              },
            )));
  }
}

关键修改说明:

  1. 状态持久化:将selectedIndex移到_SignUpWeatherQ类中作为成员变量,确保页面重绘时不会丢失选中状态。
  2. 动态样式:通过isSelected判断当前按钮是否被选中,分别设置背景色、文本色和边框样式,实现选中高亮效果。
  3. 多选项文本:定义weatherOptions列表,让每个按钮显示对应的天气文本,避免所有按钮都显示"Sunny"。
  4. 样式适配:调整文本颜色与背景色的对比度,保证选中状态下文本清晰可见。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:18:12