簡體   English   中英

如何在 Flutter 中為選定的 ListTile 添加樣式?

[英]How to add styling to selected ListTile in Flutter?

我有多個列表圖塊,我想為選定的一個添加一些樣式。 為了設置所選圖塊的顏色,我使用了ListTileTheme因此無論選擇哪個圖塊都將獲得ListTileTheme定義的顏色。

ListTileTheme(
  selectedTileColor: Colors.white,
  child: ...
),

我還想在ListTile左上角和左下角設置邊框半徑,為此我使用ClipRRect

ClipRRect(
  borderRadius: BorderRadius.only(
    topLeft: Radius.circular(32),
    bottomLeft: Radius.circular(32),
  ),
  child: ListTile(
    leading: Icon(Icons.people),
    title: Text('Teams'),
    onTap: () {},
    selected: true,
  ),
),

這很好用,如下圖所示:

在此處輸入圖像描述

但我必須手動將其添加到特定的列表磁貼中。 與定義一次的選定圖塊顏色不同,它會自動應用於選定屬性為真的任何圖塊,如何以類似的方式設置ClipRRect ,以便選擇的圖塊在左上角和左下角接收邊框半徑?

為了給選定的列表磁貼添加樣式,我使用了ListView.builder ,添加了所有菜單項以顯示在地圖的列表磁貼中。

final List<Map<String, dynamic>> _menuItem = [
    {
      "title": "Home",
      "icon": Icon(Icons.home),
      "selected": false,
    },
    {
      "title": "Teams",
      "icon": Icon(Icons.people),
      "selected": true,
    },
    {
      "title": "Ideas",
      "icon": Icon(Icons.lightbulb),
      "selected": false,
    }
];

然后使用ListView.builder循環遍歷它們。

ListView.builder(
  itemCount: _menuItem.length,
  itemBuilder: (context, index) {
    return ClipRRect(
      borderRadius: BorderRadius.only(
        topLeft: Radius.circular(32),
        bottomLeft: Radius.circular(32),
      ),
      child: ListTile(
        leading: _menuItem[index]['icon'],
        title: Text(_menuItem[index]['title']),
        selected: _menuItem[index]['selected'],
        onTap: () {
          if (!_menuItem[index]['selected'])
            changeSelectedMenu(index);
          },
      ),
    );
 },
)

changeSelectedMenu函數確保單擊的菜單項將selected屬性設置為 true。 正如所發布的那樣,選定的瓷磚顏色設置為 true,無論哪個瓷磚為白色,都從ClipRRect獲取圓角半徑。

您可以使用此代碼:

class MyListTile extends StatefulWidget {
  @override
_MyListTileState createState() => _MyListTileState();
}
class _MyListTileState extends State<MyListTile> {
 int index ;
 @override
 Widget build(BuildContext context) {
return Scaffold(
  backgroundColor: Colors.cyanAccent,
  body: ListView(
    children: [
      ClipRRect(
        borderRadius: index != null && index == 0?BorderRadius.only(
          topLeft: Radius.circular(32),
          bottomLeft: Radius.circular(32),
        ):BorderRadius.only(
          topLeft: Radius.circular(0),
          bottomLeft: Radius.circular(0),
        ),
        child:Container(
          color: index != null && index == 0?Colors.white:null,
          child: ListTile(
            focusColor: Colors.white,
            leading: Icon(Icons.people),
            title: Text('Teams'),
            onTap: () {
              setState(() {
                index = 0;
              });
            },
            selected: index != null && index == 0?true:false,
          ),
        ),
      ),
      ClipRRect(
          borderRadius: index != null && index == 1?BorderRadius.only(
            topLeft: Radius.circular(32),
            bottomLeft: Radius.circular(32),
          ):BorderRadius.only(
            topLeft: Radius.circular(0),
            bottomLeft: Radius.circular(0),
          ),
          child:Container(
            color: index != null && index == 1?Colors.white:null,
            child: ListTile(
              leading: Icon(Icons.people),
              title: Text('Teams'),
              onTap: () {
                setState(() {
                  index = 1;
                });
              },
              selected: index != null && index == 1,
            ),
          ),
      ),
      ClipRRect(
          borderRadius: index != null && index == 2?BorderRadius.only(
            topLeft: Radius.circular(32),
            bottomLeft: Radius.circular(32),
          ):BorderRadius.only(
            topLeft: Radius.circular(0),
            bottomLeft: Radius.circular(0),
          ),
          child:Container(
            color: index != null && index == 2?Colors.white:null,
            child: ListTile(
              leading: Icon(Icons.people),
              title: Text('Teams'),
              onTap: () {
                setState(() {
                  index = 2;
                });
              },
              selected: index != null && index == 2,
            ),
          ),
      ),
      ClipRRect(
          borderRadius: index != null && index == 3?BorderRadius.only(
            topLeft: Radius.circular(32),
            bottomLeft: Radius.circular(32),
          ):BorderRadius.only(
            topLeft: Radius.circular(0),
            bottomLeft: Radius.circular(0),
          ),
          child:Container(
            color: index != null && index == 3?Colors.white:null,
            child: ListTile(
              leading: Icon(Icons.people),
              title: Text('Teams'),
              onTap: () {
                setState(() {
                  index = 3;
                });
              },
                 selected: index != null && index == 3,
               ),
             ),
         ),
       ],
     ),
   );
 }

}

希望它的幫助! 但這不是一個好的解決方案。你應該使用構建器

你可能犯了和我一樣的錯誤,並且沒有研究 ListTile 的所有屬性。 ListTile 有幾個有用的屬性,例如shapeselectedTileColor可以解決您的問題。

import 'package:flutter/material.dart';

class SideMenuItem extends StatelessWidget {
  final String title;
  final IconData icon;
  final GestureTapCallback onTap;
  final bool active;

  const SideMenuItem({required this.title, required this.icon, required this.onTap, required this.active, Key? key})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    var borderRadius = const BorderRadius.only(topRight: Radius.circular(32), bottomRight: Radius.circular(32));
    return ListTile(
      shape: RoundedRectangleBorder(borderRadius: borderRadius),
      selectedTileColor: Colors.orange[100],
      selected: active,
      onTap: () {},
      leading: Icon(icon),
      title: Text(title),
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM