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

Flutter中点击按钮基于列表数据动态生成新Container的实现方法

Solution for Dynamic Container Generation on Button Tap

Got it, let's walk through how to build this feature in Flutter step by step. We'll use a StatefulWidget to manage the dynamic UI updates since we need to track which items we've already displayed and add new ones on button taps.

Step-by-Step Implementation

1. Define a Data Model

First, let's create a simple class to pair each list item with its creation time (since each container needs to show the time it was generated):

class ItemEntry {
  final String content;
  final DateTime createdAt;

  ItemEntry(this.content, this.createdAt);
}

2. Full Widget Implementation

Here's the complete code with comments explaining key parts:

import 'package:flutter/material.dart';

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

  @override
  State<DynamicContainerScreen> createState() => _DynamicContainerScreenState();
}

class _DynamicContainerScreenState extends State<DynamicContainerScreen> {
  // Replace this with your actual list of text data
  final List<String> _sourceData = [
    "First list item content",
    "Second list item content",
    "Third list item content",
    "Fourth list item content",
  ];

  // Tracks all containers we've generated so far (with their creation time)
  final List<ItemEntry> _displayedItems = [];
  // Tracks the index of the next item to add from the source list
  int _nextItemIndex = 0;

  @override
  void initState() {
    super.initState();
    // Initialize with the first item (matches your requirement of having an initial container)
    if (_sourceData.isNotEmpty) {
      _displayedItems.add(ItemEntry(
        _sourceData[_nextItemIndex],
        DateTime.now(),
      ));
      _nextItemIndex++;
    }
  }

  // Triggered when the button is tapped
  void _addNextContainer() {
    if (_nextItemIndex < _sourceData.length) {
      setState(() {
        // Add the next item with the current timestamp
        _displayedItems.add(ItemEntry(
          _sourceData[_nextItemIndex],
          DateTime.now(),
        ));
        _nextItemIndex++;
      });
    } else {
      // Optional: Let the user know there are no more items left
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("No more items to add!")),
      );
    }
  }

  // Builds a single container for an ItemEntry
  Widget _buildItemContainer(ItemEntry entry) {
    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.grey[100],
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: Colors.grey[300]!),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            "Created at: ${_formatTime(entry.createdAt)}",
            style: TextStyle(color: Colors.grey[600], fontSize: 12),
          ),
          const SizedBox(height: 8),
          Text(
            entry.content,
            style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
          ),
        ],
      ),
    );
  }

  // Helper to format the timestamp into a readable string
  String _formatTime(DateTime dateTime) {
    return "${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')} ${dateTime.day}/${dateTime.month}/${dateTime.year}";
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Dynamic Containers")),
      body: Column(
        children: [
          // Button to trigger adding the next container
          Padding(
            padding: const EdgeInsets.all(16),
            child: ElevatedButton(
              onPressed: _addNextContainer,
              child: const Text("Add Next Container"),
            ),
          ),
          // Scrollable list of generated containers
          Expanded(
            child: ListView.builder(
              itemCount: _displayedItems.length,
              itemBuilder: (context, index) {
                return _buildItemContainer(_displayedItems[index]);
              },
            ),
          ),
        ],
      ),
    );
  }
}

Key Details to Note

  • State Management: We use _displayedItems to keep track of all containers we've generated, and _nextItemIndex to avoid going out of bounds of our source list.
  • Initialization: The initState method adds the first item to ensure there's an initial container when the screen loads.
  • Button Logic: _addNextContainer checks if there are remaining items, adds the next one with the current time, and calls setState to refresh the UI.
  • Scrollable UI: Using ListView.builder ensures the app stays performant even if you generate many containers, as it only renders items visible on screen.

How to Use

Just navigate to DynamicContainerScreen in your app. You'll see the initial container right away—tap the "Add Next Container" button to add each subsequent item from your source list below the existing ones.

内容的提问来源于stack exchange,提问作者Sai Sreekar Sesham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 16:32:50