【问题标题】:Implementing icon-text mapping without a lot of "if-then" logic在没有大量“if-then”逻辑的情况下实现图标-文本映射
【发布时间】:2021-12-20 19:09:52
【问题描述】:

更新:这个问题中提到的功能列表根据给定的餐厅在组成长度上有所不同。并非每家餐厅都具有相同或相同数量的功能。

我正在我的flutter 应用程序中创建一个餐厅功能列表,每个功能都有一个独特的图标。这些不一定是唯一的,因为根据功能会有一些重复(例如,任何带有“菜单”的东西都会返回 food 图标)。

我目前将此设置为基于feature 的一系列 if-then 查找(见下文)。当前系统有一个后备图标,用于给定功能没有映射到它的功能的情况。 我们在应用商店更新应用之前在后端添加功能,因此需要一种方法来处理还没有图标的新功能。

我相信一定有更好的方法使用map 或新的class。感谢您的帮助!

loadedRestaurant.restFeatureList![index].toString().toLowerCase().contains('family')
        ? Icons.family_restroom_rounded

: loadedRestaurant.restFeatureList![index].toString().toLowerCase().contains('game day') 
        ? Icons.sports
...

生成的小部件如下所示: Screenshot of restFeatureList

【问题讨论】:

    标签: flutter dart mobile


    【解决方案1】:

    您可以使用 Map 将功能和图标存储在一起,并使用 gridView.Builder 来创建列表(需要对结果进行一些调整):

    
         List restFeatureList = [
              {'feature': "family", "icon": Icons.family_restroom_rounded},
              {'feature': "game_day", "icon": Icons.sports},
              {'feature': "veggie", "icon": Icons.park},
              {'feature': "outdoor", "icon": Icons.outdoor_grill}
            ];
        
            return Scaffold(
              backgroundColor: Colors.blue,
              body: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Center(
                  child: Container(
                    width: 200,
                    height: 200,
                    color: Colors.white,
                    child: GridView.builder(
                      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 2,
                      ),
                      itemCount: restFeatureList.length,
                      itemBuilder: (BuildContext context, int index) {
                        return Row(
                          children: <Widget>[
                            Text('${restFeatureList[index]['feature']}'),
                            Icon(restFeatureList[index]['icon']),
                          ],
                        );
                      },
                    ),
                  ),
                ),
              ),
            );
    
    

    【讨论】:

    • 谢谢!我不确定这会起作用,因为我们需要一种处理没有图标映射到它们的功能的方法(请参阅上面的更新)。当前的查找只是检查一个特征 contains 是否是一个单词或短语,它不会寻找完整的特征 string
    • 您仍然可以在没有图标的功能上使用地图,只需传递一个 NULL 并让代码处理它。我一直在尝试使用 builder 来使代码更灵活,以应对未来的变化,例如功能来自 API 的情况。希望你找到合适的解决方案:-)
    • 我阅读了更新。您可以创建一个 json 结构来存储功能并创建一个类来处理它到应用程序,在应用程序中您可以检查功能是否存在并返回适当的响应,甚至返回该功能的相应小部件:(返回Icon(feature['icon'] ) 到您的小部件树。从视图中隐藏功能处理,您可以更轻松地添加或删除功能。
    • 谢谢,@fabio!我也使用了这个解决方案的一部分,只是使用了不同的mapgetter。此外,使用gridview.builder 真的很聪明。我实现了这个,它把我的代码减半(以前像个白痴一样使用两个listview.builders)。再次感谢您的指导!
    • 我非常感谢您的客气话!我的意思更像是一个玩笑,真的。我喜欢嘲笑自己和自己的错误,以便在我学习和发展的过程中保持积极的态度。
    【解决方案2】:

    类似这样的:

    //mapping in some utils for example
    final featureIcons = <String, IconData>{
          "family": Icons.family_restroom_rounded,
        }.entries;
    
        IconData getFeatureIcon(String feature) {
          return featureIcons
              .firstWhereOrNull((key) => key.key.toLowerCase().contains(feature))
              ?.value;
        }
    
    // in your UI
        getFeatureIcon(loadedRestaurant.restFeatureList![index].toString());
    

    【讨论】:

    • 感谢您的帮助!这非常有用。我最终只是使用带有orElse 子句的firstWhere 来设置default - 我们不能为此在应用程序中使用任何nulls
    • 当然,这只是一个例子。我同意默认图标是个好主意:)
    猜你喜欢
    • 1970-01-01
    • 2012-02-10
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 2023-02-02
    • 1970-01-01
    相关资源
    最近更新 更多