找回密码
马上加入

QQ登录

只需一步,快速开始

搜索
发新帖

0

收听

1

听众

134

主题
发表于 昨天 20:54 | 查看: 5| 回复: 0

Lua开发:实现自定义选择列表UI组件

在游戏开发中,创建灵活、可复用的UI组件是提高开发效率的关键。今天我将分享一个Lua实现的通用选择列表组件 CommonSelectList,它可以在游戏中动态创建选项菜单。

组件概述

CommonSelectList是一个功能强大的自定义选择列表组件,主要特点包括:

  • 动态位置调整(自动适应屏幕边缘)
  • 可自定义的单元格大小
  • 支持文本和图标显示
  • 最大显示数量限制
  • 点击回调处理

核心代码分析

1. 组件初始化

CommonSelectList = {}
CommonSelectList._maxShowNum = 8  -- 最大显示cell个数

function CommonSelectList.main(data)
    local parent = GUI:Attach_Parent()
    GUI:LoadExport(parent, "common_tips/common_select_list")

    -- 获取屏幕尺寸
    local screenW = SL:GetMetaValue("SCREEN_WIDTH")
    local screenH = SL:GetMetaValue("SCREEN_HEIGHT")

    CommonSelectList._ui = GUI:ui_delegate(parent)
    -- 设置取消面板为全屏大小
    GUI:setContentSize(CommonSelectList._ui.Panel_cancel, screenW, screenH)

    CommonSelectList.InitUI(data)
end

2. UI初始化与布局

function CommonSelectList.InitUI(data)
    if not data then return end

    local position = data.position
    local values = data.values
    local cellSize = {width = 260, height = 28}  -- 默认cell尺寸
    local cellW = data.cellwidth or cellSize.width
    local cellH = data.cellheight or cellSize.height
    local MoveCount = data.MoveItemCount or 0

    -- 设置回调函数和图标路径
    CommonSelectList._func = data.func 
    CommonSelectList._iconPaths = data.iconPaths

    -- 处理单选项情况
    if type(values) == "string" then 
        values = {values}
    end 

    -- 计算实际显示数量
    local count = math.min(#values, CommonSelectList._maxShowNum)

    -- 自动调整位置(避免超出屏幕底部)
    if position.y < cellH * count then
        GUI:setAnchorPoint(CommonSelectList._ui.Image_bg, 0, 0) 
        if MoveCount > 0 then 
            position.y = position.y + MoveCount * cellH
        end
    end

    -- 计算背景高度
    local pSizeH = cellH * count + 8
    GUI:setContentSize(CommonSelectList._ui.Image_bg, cellW + 8, pSizeH)
    GUI:setContentSize(CommonSelectList._ui.ListView_1, cellW, cellH * count)
    GUI:setPositionY(CommonSelectList._ui.ListView_1, pSizeH - 4)

    -- 保存单元格尺寸
    CommonSelectList._cellSize = {width = cellW, height = cellH}

    -- 创建所有选项
    for i, v in ipairs(values) do
        local cell = CommonSelectList.CreateItemCell(i, v)
        GUI:ListView_pushBackCustomItem(CommonSelectList._ui.ListView_1, cell)
    end

    -- 设置背景位置
    GUI:setPosition(CommonSelectList._ui.Image_bg, position.x, position.y)

    -- 取消按钮点击事件
    GUI:addOnClickEvent(CommonSelectList._ui.Panel_cancel, function()
        if CommonSelectList._func then
            CommonSelectList._func(0)  -- 0表示取消选择
        end
        SL:CloseSelectListUI()
    end)
end

3. 创建单个选项单元格

function CommonSelectList.CreateItemCell(index, str)
    local parent = GUI:Widget_Create(CommonSelectList._ui.ListView_1, "widget", 0, 0)
    GUI:LoadExport(parent, "common_tips/common_select_list_cell")

    local size = CommonSelectList._cellSize
    local cell = GUI:getChildByName(parent, "Image_cell")
    GUI:setContentSize(cell, size)

    local ui = GUI:ui_delegate(cell)
    GUI:Text_setString(ui.Text_desc, str)
    GUI:setPosition(ui.Text_desc, size.width / 2, size.height / 2)

    -- 图标处理
    GUI:setVisible(ui.Image_icon, false)
    local iconPath = CommonSelectList._iconPaths and CommonSelectList._iconPaths[index]
    if iconPath and iconPath ~= "" and SL:IsFileExist(iconPath) then
        GUI:Image_loadTexture(ui.Image_icon, iconPath)
        GUI:setVisible(ui.Image_icon, true)
    end

    -- 单元格点击事件
    GUI:addOnClickEvent(cell, function()
        if CommonSelectList._func then
            CommonSelectList._func(index)  -- 传递选择的索引
        end
        SL:CloseSelectListUI()
    end)

    -- 清理临时节点
    GUI:removeFromParent(cell)
    GUI:removeFromParent(parent)

    return cell
end

使用示例

-- 创建选择列表
local data = {
    position = {x = 100, y = 200},  -- 显示位置
    values = {"攻击", "防御", "治疗", "逃跑"},  -- 选项列表
    iconPaths = {  -- 图标路径(可选)
        "icons/attack.png",
        "icons/defense.png",
        "icons/heal.png",
        "icons/escape.png"
    },
    cellwidth = 300,  -- 自定义宽度
    func = function(index)  -- 选择回调
        if index == 0 then
            print("取消选择")
        else
            print("选择了选项:", index)
        end
    end
}

CommonSelectList.main(data)

关键特性实现

  1. 智能位置调整

    • 检查列表是否会超出屏幕底部
    • 自动调整锚点和位置
    • 支持额外的位置偏移(MoveItemCount)
  2. 动态尺寸计算

    local pSizeH = cellH * count + 8
    GUI:setContentSize(CommonSelectList._ui.Image_bg, cellW + 8, pSizeH)
  3. 图标显示处理

    if iconPath and iconPath ~= "" and SL:IsFileExist(iconPath) then
        GUI:Image_loadTexture(ui.Image_icon, iconPath)
        GUI:setVisible(ui.Image_icon, true)
    end
  4. 回调机制

    • 选项选择回调传递索引
    • 取消选择传递0

实际应用场景

这个通用选择列表组件可以用于:

  1. 游戏中的上下文菜单
  2. 角色技能选择
  3. 物品使用选项
  4. 系统设置菜单
  5. 任何需要弹出选择的场景

优化建议

  1. 添加滚动支持,当选项超过最大显示数量时
  2. 实现动画效果,使弹出更流畅
  3. 添加键盘/手柄导航支持
  4. 支持自定义样式和主题

总结

通过这个 CommonSelectList组件,我们可以看到如何创建一个灵活、可复用的UI组件。关键点包括:

  • 动态适应屏幕边界
  • 支持自定义尺寸和内容
  • 简洁的回调接口
  • 图标和文本的组合显示

这种组件的实现思路可以扩展到其他UI元素,帮助构建更健壮的游戏UI系统。

希望这篇分析对你在游戏开发中实现自定义UI组件有所帮助!

您需要登录后才可以回帖 登录 | 马上加入

QQ|Archiver|手机版|小黑屋|alg阿灵戈社区 ( 苏ICP备2023026137号-1|苏ICP备2023026137号-1 )

GMT+8, 2025-7-27 15:25 , Processed in 0.474932 second(s), 24 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表