Skip to content

SOUI 模板系统指南

Warning

The current page still doesn't have a translation for this language.

You can read it through google translate.

模板系统是 SOUI 框架提供的强大功能,用于实现可复用的界面组件。通过模板机制,您可以定义参数化的布局结构,避免重复代码,提高开发效率,并确保界面的一致性。

模板基础概念

模板定义结构

模板系统基于以下核心概念:

  • 模板定义:在资源文件中定义可复用的布局结构
  • 参数化:使用 {{parameter}} 语法定义可替换的参数
  • 命名空间:使用 g. 前缀创建模板命名空间
  • 实例化:通过 t: 前缀引用并实例化模板

模板定义与配置

创建模板资源文件

在项目的 values 目录下创建模板定义文件(推荐命名为 templates.xml):

<?xml version="1.0" encoding="utf-8"?>
<template>
    <!-- 基础组件模板 -->
    <g.card>
        <window name="{{name}}" width="{{cardWidth}}" height="{{cardHeight}}" 
                colorBkgnd="{{backgroundColor}}" roundCorner="8"
                padding="16" margin="8">
            <text name="title" text="{{title}}" size="18" 
                  colorText="{{titleColor}}" gravity="center"/>
            <text name="subtitle" text="{{subtitle}}" size="14" 
                  colorText="{{subtitleColor}}" gravity="center" margin="0,8,0,0"/>
        </window>
    </g.card>

    <!-- 列表项模板 -->
    <g.list_item>
        <window name="{{name}}" height="56" layout="hbox" gravity="center"
                padding="16" margin="8">
            <img name="icon" skin="{{iconSkin}}" size="24" marginRight="16"/>
            <window size="-1,-1" layout="vbox" gravity="left|center">
                <text name="primary" text="{{primaryText}}" size="14" 
                      colorText="{{primaryColor}}" gravity="left"/>
                <text name="secondary" text="{{secondaryText}}" size="12" 
                      colorText="{{secondaryColor}}" gravity="left" marginTop="4"/>
            </window>
            <img name="arrow" skin="skin_arrow_right" size="16" gravity="right"/>
        </window>
    </g.list_item>

    <!-- 按钮模板 -->
    <g.button>
        <button name="{{name}}" text="{{text}}" width="{{buttonWidth}}" height="36"
                colorText="{{textColor}}" colorBkgnd="{{backgroundColor}}" 
                colorTextHover="{{hoverColor}}" colorBkgndHover="{{hoverBackground}}"
                roundCorner="4" font="{{font}}"/>
    </g.button>

    <!-- 输入框模板 -->
    <g.input_field>
        <edit name="{{name}}" text="{{hintText}}" width="{{inputWidth}}" height="40"
              colorText="{{textColor}}" colorBkgnd="{{backgroundColor}}" 
              colorBorder="{{borderColor}}" colorFocus="{{focusColor}}"
              padding="16" roundCorner="2"/>
    </g.input_field>
</template>

注册模板资源

  1. 在资源索引文件注册uires.idx):
<values>
    <!-- 其他资源引用 -->
    <file name="templates" path="values\templates.xml"/>
</values>
  1. 在界面定义文件引用init.xml):
<UIDEF>
    <template src="values:templates"/>
    <!-- 其他配置 -->
</UIDEF>

💡 提示:如果是通过 SOUI 项目向导创建的项目,上述配置通常已自动完成。默认模板资源文件为 values\templates.xml

模板使用方式

基础实例化

通过 t: 前缀引用模板并传入参数:

<!-- 实例化卡片模板 -->
<t:g.card name="userCard" cardWidth="300dp" cardHeight="120dp" 
          backgroundColor="@color/card_background" titleColor="@color/text_primary"
          title="用户信息" subtitle="高级会员" subtitleColor="@color/text_secondary"/>

<!-- 实例化列表项模板 -->
<t:g.list_item name="item1" iconSkin="skin_user" primaryText="张三" 
                secondaryText="zhangsan@example.com" primaryColor="@color/text_primary"
                secondaryColor="@color/text_secondary"/>

<!-- 实例化按钮模板 -->
<t:g.button name="submitBtn" text="提交" buttonWidth="120dp" textColor="@color/white"
            backgroundColor="@color/primary" hoverColor="@color/white" 
            hoverBackground="@color/primary_dark"/>

高级用法示例

动态列表模板

<!-- 模板定义:动态列表项 -->
<g.dynamic_list_item>
    <window name="{{name}}" height="{{itemHeight}}" layout="hbox" gravity="center"
            padding="@dim/spacing_md" margin="@dim/spacing_sm" 
            colorBkgnd="{{backgroundColor}}" roundCorner="@dim/corner_radius_normal">
        <img name="icon" skin="{{icon}}" size="{{iconSize}}" marginRight="@dim/spacing_md"/>
        <window size="-1,-1" layout="vbox" gravity="left|center">
            <text name="title" text="{{title}}" size="{{titleSize}}" colorText="{{titleColor}}"/>
            <text name="desc" text="{{description}}" size="{{descSize}}" colorText="{{descColor}}" 
                  marginTop="@dim/spacing_xs"/>
        </window>
        <text name="badge" text="{{badgeText}}" size="@dim/text_size_small" 
              colorText="{{badgeColor}}" colorBkgnd="{{badgeBg}}" 
              padding="@dim/spacing_xs,@dim/spacing_xxs" roundCorner="@dim/corner_radius_small"
              gravity="right" visible="{{showBadge}}"/>
    </window>
</g.dynamic_list_item>

条件渲染模板

<!-- 模板定义:条件显示组件 -->
<g.status_item>
    <window name="{{name}}" layout="hbox" gravity="center" padding="@dim/spacing_md">
        <img name="statusIcon" skin="{{statusIcon}}" size="@dim/icon_size"/>
        <text name="statusText" text="{{statusText}}" size="@dim/text_size_normal" 
              colorText="{{statusColor}}" marginLeft="@dim/spacing_md"/>
        <img name="actionIcon" skin="{{actionIcon}}" size="@dim/icon_size_small" 
              gravity="right" visible="{{showAction}}"/>
    </window>
</g.status_item>

模板实例化示例

<!-- 完整布局示例:使用模板的用户列表 -->
<window name="userList" layout="vbox" padding="@dim/spacing_md">
    <!-- 标题 -->
    <text name="listTitle" text="用户列表" size="@dim/text_size_title" 
          colorText="@color/text_primary" gravity="center" marginBottom="@dim/spacing_md"/>

    <!-- 用户卡片列表 -->
    <scrollview name="scroll" size="-1,-1">
        <window name="content" layout="vbox">
            <t:g.dynamic_list_item name="user1" itemHeight="72dp" 
                icon="skin_user_male" title="张三" desc="产品经理" titleColor="@color/text_primary"
                descColor="@color/text_secondary" backgroundColor="@color/white"
                iconSize="@dim/icon_size_large" titleSize="@dim/text_size_normal" 
                descSize="@dim/text_size_small" badgeText="VIP" badgeColor="@color/white"
                badgeBg="@color/accent" showBadge="true"/>

            <t:g.dynamic_list_item name="user2" itemHeight="72dp"
                icon="skin_user_female" title="李四" desc="UI设计师" titleColor="@color/text_primary"
                descColor="@color/text_secondary" backgroundColor="@color/white"
                iconSize="@dim/icon_size_large" titleSize="@dim/text_size_normal"
                descSize="@dim/text_size_small" showBadge="false"/>
        </window>
    </scrollview>
</window>

模板最佳实践

设计原则

  1. 单一职责:每个模板只负责一种界面组件
  2. 参数完整:为所有可变属性提供参数
  3. 语义命名:使用描述性参数名而非技术性名称
  4. 默认值:为非关键参数提供合理的默认值

命名规范

  • 模板命名:使用 g.[component_type] 格式,如 g.button, g.card
  • 参数命名:使用驼峰命名法,如 backgroundColor, titleText
  • 布尔参数:使用 isshow 前缀,如 isVisible, showIcon

模板组织建议

  1. 分层管理
  2. 基础组件模板(按钮、输入框、卡片)
  3. 复合组件模板(列表项、表单、对话框)
  4. 业务组件模板(用户卡片、商品卡片)

  5. 文件组织

    values/
    ├── templates.xml          # 通用模板
    ├── templates_forms.xml   # 表单模板
    ├── templates_cards.xml   # 卡片模板
    └── templates_list.xml    # 列表模板
    

  6. 版本控制:将模板文件纳入版本管理,便于团队协作

常见问题解答

Q: 模板参数支持哪些数据类型? A: 支持字符串、颜色值、尺寸值、布尔值、数字值等基本类型,通过字符串形式传递。

Q: 模板可以嵌套使用吗? A: 可以,模板可以引用其他模板,但需要注意避免循环引用。

Q: 模板支持条件渲染吗? A: 支持,通过布尔参数控制组件的可见性来实现条件渲染。