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

如何实现3个FlatButton关联不同ListView,未选中按钮置灰且仅单个选中

How to Implement a Tab-like FlatButton Row with Corresponding ListViews in Flutter

Hey there! I’ve tackled a similar requirement before, so let me share a clean, straightforward solution that fits exactly what you need. The core idea is to track the selected button with a state variable, use that to update button styles (selected vs. grayed-out), and switch between ListViews accordingly.

Step 1: Set Up the Stateful Widget

First, we’ll use a StatefulWidget since we need to manage dynamic state (which button is selected). Declare a variable to track the selected button index—we’ll default it to 0 to have the first button selected initially.

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

  @override
  State<TabbedListView> createState() => _TabbedListViewState();
}

class _TabbedListViewState extends State<TabbedListView> {
  // Track which button is selected (0 = first button, default)
  int _selectedButtonIndex = 0;

  // Sample data for each ListView (replace with your actual data)
  final List<List<String>> _listContents = [
    ['First List Item 1', 'First List Item 2', 'First List Item 3'],
    ['Second List Item 1', 'Second List Item 2'],
    ['Third List Item 1', 'Third List Item 2', 'Third List Item 3', 'Third List Item 4'],
  ];

Step 2: Build the Button Row

We’ll create a reusable method to build each FlatButton. This method checks if the button is the selected one, and adjusts its color/text color to show the selected state (normal style) or grayed-out state. When a button is tapped, we update the _selectedButtonIndex to trigger a UI refresh.

// Reusable button builder
  FlatButton _buildTabButton(String buttonText, int buttonIndex) {
    return FlatButton(
      onPressed: () {
        setState(() {
          _selectedButtonIndex = buttonIndex;
        });
      },
      // Set background color: primary color if selected, light gray otherwise
      color: _selectedButtonIndex == buttonIndex 
          ? Theme.of(context).primaryColor 
          : Colors.grey[300],
      // Set text color: white if selected, dark gray otherwise
      textColor: _selectedButtonIndex == buttonIndex 
          ? Colors.white 
          : Colors.grey[600],
      child: Text(buttonText),
    );
  }

Then, add the button row to your main build method:

@override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // Button row with space between buttons
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            _buildTabButton('List 1', 0),
            _buildTabButton('List 2', 1),
            _buildTabButton('List 3', 2),
          ],
        ),
        const SizedBox(height: 16), // Spacing between buttons and list

Step 3: Show the Corresponding ListView

Finally, we’ll build the ListView based on the selected button index. We can use a ListView.builder for efficiency, pulling the correct data from our _listContents array.

// Selected ListView
        Expanded(
          child: ListView.builder(
            itemCount: _listContents[_selectedButtonIndex].length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(_listContents[_selectedButtonIndex][index]),
              );
            },
          ),
        ),
      ],
    );
  }
}

Key Notes

  • Visual Feedback: The button styles clearly show which one is active (colored) and which are inactive (grayed-out). If you want to make inactive buttons unclickable (though your requirement says to switch when selected, so clickable makes more sense), you can set onPressed: _selectedButtonIndex == buttonIndex ? () {...} : null—but this will disable the button entirely.
  • Customization: Feel free to tweak colors, padding, or button shapes to match your app’s design. For newer Flutter versions, you might want to use TextButton instead of FlatButton (since FlatButton is deprecated), but the logic remains the same.
  • Efficiency: Using ListView.builder ensures only visible list items are built, which is great for large datasets.

Give this implementation a shot—it should handle all your requirements: default selected first button, grayed-out inactive buttons, and switching ListViews when a button is tapped, with only one active button at a time.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:32:34