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

Flutter中API数据加载后实现Container点击单选变色的方法

Flutter实现单选变色的ListView Builder容器

要实现点击容器切换颜色且同一时间仅一个选中的需求,核心是通过状态管理记录选中项索引,结合ListView动态渲染样式。下面是完整实现方案:

核心思路

  • 用StatefulWidget维护选中状态,定义_selectedIndex变量存储当前选中项的索引,初始值设为-1(表示无选中项)
  • 通过FutureBuilder处理API异步数据请求(示例中模拟了API返回数据,实际项目替换为真实接口即可)
  • 在ListView.builder中,每个容器的颜色根据当前索引是否等于_selectedIndex来切换,点击时更新选中索引

完整代码示例

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '单选容器示例',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const SingleSelectContainerPage(),
    );
  }
}

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

  @override
  State<SingleSelectContainerPage> createState() => _SingleSelectContainerPageState();
}

class _SingleSelectContainerPageState extends State<SingleSelectContainerPage> {
  // 记录选中项的索引,-1表示未选中任何项
  int _selectedIndex = -1;

  // 模拟API接口返回数据,实际项目替换为真实的网络请求
  Future<List<String>> _fetchData() async {
    await Future.delayed(const Duration(seconds: 1)); // 模拟网络延迟
    return ['容器1', '容器2', '容器3'];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('单选容器示例')),
      body: FutureBuilder<List<String>>(
        future: _fetchData(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          } else if (snapshot.hasError) {
            return Center(child: Text('加载失败: ${snapshot.error}'));
          } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
            return const Center(child: Text('暂无数据'));
          }

          final dataList = snapshot.data!;
          return ListView.builder(
            itemCount: dataList.length,
            itemBuilder: (context, index) {
              // 判断当前项是否被选中,设置对应颜色
              final isSelected = _selectedIndex == index;
              final containerColor = isSelected ? Colors.blueAccent : Colors.grey[200];

              return Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                child: InkWell(
                  onTap: () {
                    setState(() {
                      // 点击时更新选中索引,实现单选效果
                      _selectedIndex = index;
                    });
                  },
                  borderRadius: BorderRadius.circular(8),
                  child: Container(
                    padding: const EdgeInsets.all(16),
                    decoration: BoxDecoration(
                      color: containerColor,
                      borderRadius: BorderRadius.circular(8),
                      border: isSelected ? Border.all(color: Colors.blue, width: 2) : null,
                    ),
                    child: Text(
                      dataList[index],
                      style: TextStyle(
                        fontSize: 16,
                        color: isSelected ? Colors.white : Colors.black87,
                      ),
                    ),
                  ),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

关键细节说明

  • 使用InkWell包裹Container,既实现点击事件,又能提供Material风格的水波纹反馈
  • 通过setState更新_selectedIndex,触发页面重绘,动态切换选中项的颜色和样式
  • FutureBuilder完美适配异步数据加载场景,覆盖了加载中、加载失败、无数据等各种状态

内容的提问来源于stack exchange,提问作者Mr.Robot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:05:21