如何在Flutter中显示嵌套的展开瓷砖列表(具有子类别)?

huangapple go评论52阅读模式
英文:

How to display a list of nested expansion tile in flutter (Category with sub category)?

问题

I understand your request. Here's the translated content without the code:

我正在尝试构建一个扩展瓷砖列表,每个扩展瓷砖都有一个子列表,但每个子项目都有一个子类别。

假设您不知道嵌套子类别的长度,如何在以下对象中不硬编码每个迭代...

第一个对象在sub_categories键下有一个空列表,但第二个对象具有嵌套的完全相同的对象!那么,如果子类别为空,我们可以显示普通的列表项,但如果对象具有未知长度的子类别,我们将在扩展瓷砖中显示它们。

基本上,硬编码每个迭代都不正确,因为我们不知道子类别的长度。

英文:

I'm trying to build a list of expansion tile, each expansion tile has a list of children but every child has a sub category.

Suppose that you don’t know the length of the nested sub category, How to NOT HARD CODE each iteration in the following objects...

        {
"id": 53,
"parent_id": null,
"slug": "bazar",
"name": "BAZAR",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 196,
"parent_id": null,
"slug": "cosmetics",
"name": "COSMETICS",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": [
{
"id": 170,
"parent_id": 196,
"slug": "make-up",
"name": "Make Up",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": [
{
"id": 171,
"parent_id": 170,
"slug": "make-up-eyes",
"name": "Eyes",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": [
{
"id": 214,
"parent_id": 171,
"slug": "mascara",
"name": "Mascara & Brows",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 215,
"parent_id": 171,
"slug": "eyeshadow",
"name": "Eyeshadow",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 216,
"parent_id": 171,
"slug": "eyeliner",
"name": "Eyeliner",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 217,
"parent_id": 171,
"slug": "falselashes",
"name": "Falselashes",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
}
]
},
{
"id": 172,
"parent_id": 170,
"slug": "make-up-face",
"name": "Face",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": [
{
"id": 219,
"parent_id": 172,
"slug": "foundation",
"name": "Foundation",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 220,
"parent_id": 172,
"slug": "concealer-corrector",
"name": "Concealer & Corrector",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 226,
"parent_id": 172,
"slug": "bronzer-blush",
"name": "Bronzer & Blush",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 227,
"parent_id": 172,
"slug": "compact-loose-powder",
"name": "Compact & Loose Powder",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
}
]
},
{
"id": 174,
"parent_id": 170,
"slug": "make-up-lips",
"name": "Lips",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": [
{
"id": 228,
"parent_id": 174,
"slug": "lipstick",
"name": "Lipstick",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 230,
"parent_id": 174,
"slug": "lip-gloss-lip-balm",
"name": "Lip Gloss & Lip Balm",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
}
]
},
{
"id": 175,
"parent_id": 170,
"slug": "make-up-nails",
"name": "Nails",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
}
]
},
{
"id": 177,
"parent_id": 196,
"slug": "skin-care",
"name": "Skin Care",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": [
{
"id": 178,
"parent_id": 177,
"slug": "cleansers-toners",
"name": "Cleansers & Toners",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 179,
"parent_id": 177,
"slug": "masks-scrubs",
"name": "Masks & Scrubs",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
},
{
"id": 181,
"parent_id": 177,
"slug": "serums-treatments",
"name": "Serums & Treatments",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
}
]
},
{
"id": 192,
"parent_id": 196,
"slug": "beauty-tools",
"name": "Tools & Accessories",
"is_searchable": true,
"shop_in_shop": false,
"logo": null,
"banner": null,
"shop_banner": null,
"sub_categories": []
}
]
},

As you can see, the first object at ** sub_categories** key has empty list, but the second object has a nested same exact object!, so how can we show this data in a list view of expansion tile, if the sub categories is empty we can show a normal list tile but if the object has a nested unknown length of sub categories we will show them in a expansion tile.

Basically, it's not right to hard code each iteration because we don’t know the length of sub categories.

答案1

得分: 0

以下是翻译好的代码部分:

简单地通过递归解决了这个问题。

这是一个小部件,它会检测它是否嵌套以及基于列表长度。

class RecursiveDrawerItem extends StatelessWidget {
 final List categories;

 const RecursiveDrawerItem({Key? key, required this.categories})
    : super(key: key);

 @override
 Widget build(BuildContext context) {
return ListView.separated(
  separatorBuilder: (context, index) =>
      Divider(color: DaraghmehColors().grey),
  physics: const NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  itemCount: categories.length,
  itemBuilder: (BuildContext context, int index) {
    final category = categories[index];

    return category['sub_categories'].isEmpty
        ? ListTile(
            title: MediumFont(
                text: category['name'],
                textAlign: TextAlign.start,
                fontWeight: FontWeight.w400),
          )
        : ExpansionTileCard(
            animateTrailing: true,
            elevation: 0.0,
            expandedColor: Colors.white,
            shadowColor: Colors.white,
            baseColor: Colors.white,
            title: MediumFont(
                text: category['name'],
                textAlign: TextAlign.start,
                fontWeight: FontWeight.w400),
            children: <Widget>[
              Padding(
                padding: EdgeInsets.symmetric(horizontal: 10.w),
                 /// 递归 
                child: RecursiveDrawerItem(
                    categories: category['sub_categories']),
              )
            ],
          );
     },
    );
 }
}

然后像这样使用这个类:

RecursiveDrawerItem(categories: drawerData.categories['categories']),
英文:

Simply i solved this by recursion.

This is the widget which detect if it nested or not and based on list length.

class RecursiveDrawerItem extends StatelessWidget {
final List categories;
const RecursiveDrawerItem({Key? key, required this.categories})
: super(key: key);
@override
Widget build(BuildContext context) {
return ListView.separated(
separatorBuilder: (context, index) =>
Divider(color: DaraghmehColors().grey),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: categories.length,
itemBuilder: (BuildContext context, int index) {
final category = categories[index];
return category['sub_categories'].isEmpty
? ListTile(
title: MediumFont(
text: category['name'],
textAlign: TextAlign.start,
fontWeight: FontWeight.w400),
)
: ExpansionTileCard(
animateTrailing: true,
elevation: 0.0,
expandedColor: Colors.white,
shadowColor: Colors.white,
baseColor: Colors.white,
title: MediumFont(
text: category['name'],
textAlign: TextAlign.start,
fontWeight: FontWeight.w400),
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.w),
/// recursive 
child: RecursiveDrawerItem(
categories: category['sub_categories']),
)
],
);
},
);
}
}

then use this class like this..

RecursiveDrawerItem(categories: drawerData.categories['categories']),

huangapple
  • 本文由 发表于 2023年5月10日 15:16:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76215828.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定