• Unity


    为了更贴近游戏实际ui的效果和使用环境, 从而讨论上一节遗留的问题, 列表显示是必不可少的
    参考
    修改之前的HomeRoute,

            private Widget CreateListTest()
            {
                ListView listView = ListView.builder(
                    scrollDirection: Axis.vertical,
                    itemExtent: 20,
                    itemCount: 100,
                    itemBuilder: (context, index) =>
                    {
                        return new Text(data: index.ToString());
                    }
                    );
    
                return listView;
            }
    
            private Widget GetWidget()
            {
                Scaffold scaffold = new Scaffold(
                    appBar: new AppBar(
                        title: new Text("首页")
                        ),
                    body: CreateListTest()
                    );
    
                return scaffold;
            }
    

    创建了一个列表, 显示从0到99的数字, 每个列表项高度为20(逻辑高度), 效果如下

    通过UIWidgets Inspector可以看到列表项是循环回收的(即看不到的列表项不作为一个UI节点存在), 但这个节点大概已经嵌套了四五十层... 对性能不太信任

    显示背包道具

    下面要做的是模拟一个显示背包道具的操作, 一个简单的列表显示玩家背包中的每种道具的名字和一句说明(为简化, 道具通通不可叠加)
    即提前准备好state, 暂时没有action

    首先我准备了几个道具

    // Item.cs
    
    using System.Collections.Generic;
    
    namespace Data
    {
        // 道具的数据类, 非常简单
        public class Item
        {
            public int id;
            public string name;
            public string description;
    
            // 临时模拟一个配置表
            public static Dictionary<int, Item> Table = new Dictionary<int, Item>()
            {
                { 1, new Item { id = 1, name = "木棍", description = "一根没什么用的木棍" } },
                { 2, new Item { id = 2, name = "石头", description = "一块没什么用的石头" } },
                { 3, new Item { id = 3, name = "干草", description = "一把没什么用的干草" } },
            };
        }
    }
    

    然后给主角的背包里塞了10个木棍, 10个石头, 5个干草

    // GlobalState.cs
    
    using System.Collections.Generic;
    
    namespace UI
    {
        public class GlobalState
        {
            public List<int> Items;
    
            public GlobalState()
            {
                Items = new List<int>
                {
                    1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                    2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
                    3, 3, 3, 3, 3,
                };
            }
        }
    }
    

    修改列表显示

    // HomeRoute.cs
    
            private Widget CreateListTest()
            {
                var widget = new StoreConnector<GlobalState, List<int>>(
                    converter: (state) => state.Items,
                    builder: (context, list, dispatcher) => ListView.builder(
                        itemExtent: 20,
                        itemCount: list.Count,
                        itemBuilder: (context2, index) =>
                        {
                            int itemId = list[index];
                            Data.Item data = Data.Item.Table[itemId];
                            return new Text(data: $"道具名称: {data.name}, 说明: {data.description}");
                        }
                        )
                    );
    
                return widget;
            }
    

    这么写从直觉上不太对, 但目前成功了

    修改背包道具

    参照前面的写法给增加两个功能: 点击道具列表项使用获取一个新道具

    为了更直观删除了大部分道具

    GlobalState.cs
    
    using System.Collections.Generic;
    
    namespace UI
    {
        public class GlobalState
        {
            public List<int> Items;
    
            public GlobalState()
            {
                UnityEngine.Debug.Log("创建了新的GlobalState");
                Items = new List<int>
                {
                    1, 2, 3,
                };
            }
    
            public GlobalState(List<int> items)
            {
                UnityEngine.Debug.Log("创建了新的GlobalState, 传递了items");
                Items = items;
            }
        }
    }
    
    // Actions.cs
    
    namespace UI
    {
        public class UseBagItemAction
        {
            public int positionIndex;
        }
    
        public class GetItemAction
        {
            public int itemId;
        }
    }
    
    // HomeRoute.cs
    
            public static GlobalState Reducer(GlobalState state, object action)
            {
                if (action is UseBagItemAction)
                {
                    int posId = ((UseBagItemAction)action).positionIndex;
                    // 这里参照了Redux规范, 复制一份新的再修改, 下同
                    List<int> items = new List<int>(state.Items);
                    items.RemoveAt(posId);
                    return new GlobalState(items);
                }
    
                if (action is GetItemAction)
                {
                    int itemId = ((GetItemAction)action).itemId;
                    List<int> items = new List<int>(state.Items);
                    items.Add(itemId);
                    return new GlobalState(items);
                }
    
                return state;
            }
    
            private Widget CreateListTest()
            {
                var showList = new StoreConnector<GlobalState, List<int>>(
                    converter: (state) => state.Items,
                    builder: (context, list, dispatcher) => ListView.builder(
                        //itemExtent: 20,
                        itemCount: list.Count,
                        itemBuilder: (context2, index) =>
                        {
                            int itemId = list[index];
                            Data.Item data = Data.Item.Table[itemId];
                            return new RaisedButton(
                                child: new Text(data: $"{index} - 道具名称: {data.name}, 说明: {data.description}"),
                                onPressed: () =>
                                {
                                    dispatcher.dispatch(new UseBagItemAction { positionIndex = index });
                                }
                                );
                        }
                        )
                    );
    
                var btn = new StoreConnector<GlobalState, object>(
                    converter: (state) => null,
                    builder: (context, _, dispathcer) => new RaisedButton(
                        child: new Text("获得一根木棍"),
                        onPressed: () =>
                        {
                            dispathcer.dispatch(new GetItemAction { itemId = 1 });
                        }
                        )
                    );
    
                var widget = new Column(
                    children: new List<Widget> {
                        // 画面溢出时直接报错, 限制一下高度
                        new Container(
                            child: showList,
                            height: 400
                            ),
                        btn,
                        }
                    );
    
                return widget;
            }
    

    使用三个道具, 获得三个木棍, 没什么问题

    之后就需要讨论ListItem更复杂化动效效率优化代码重构等等问题了, 和这次的主题没有关系

  • 相关阅读:
    Qbxt 模拟题 day2(am) T2 jian
    Codevs 1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提高组
    洛谷比赛 U5442 买(最长链)
    洛谷 P1800 software_NOI导刊2010提高(06)(二分答案+DP检验)
    Codevs 4373 窗口(线段树 单调队列 st表)
    P1453 城市环路
    P1841 [JSOI2007]重要的城市
    P1410 子序列
    H
    GSS4 D
  • 原文地址:https://www.cnblogs.com/lunoctis/p/12240455.html
Copyright © 2020-2023  润新知