# ListCard - 列表组控件

## 概述
基于 `ListGroupProps` 接口定义，集成自 `ListCard.tsx` 中的类型定义。

`ListCard` 是一个列表组控件，用于将多个 ListItem 或 ListItemWithWidget 组合成一个分组显示。支持自定义标题、标题尺寸、分组类型、底部提示信息等功能，是构建设置页面和功能列表的核心组件。

## 预览

![](http://cdn.cnbj0.fds.api.mi-img.com/miio.files/commonfile_png_ba2d1f8d5c0c9f5f62ea32a0f5f8c9c0.png)

## 基本信息

| 信息项 | 内容 |
|--------|------|
| 中文名称 | 列表组控件 |
| 描述 | 用于将多个列表项组合成一个分组显示的容器组件 |
| 位置 | `miot/ui/ListCard` |
| 引入版本 | `10116` |
| 更新时间 | 2026-04-03 |

## 入参（Props）

| 属性名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| **title** | `string` | 是 | - | 分组标题文本 |
| **titleSize** | `'small' \| 'medium' \| 'large'` | 否 | `'small'` | 标题尺寸：<br>`'small'` - 14px medium，蓝灰色<br>`'medium'` - 16px medium，深色<br>`'large'` - 20px regular，深色 |
| **dataSource** | `ListItemProps[] \| ListItemWithWidgetProps[]` | 是 | - | 列表项数据数组 |
| **type** | `'normal' \| 'widget'` | 否 | `'normal'` | 分组类型：<br>`'normal'` - 使用 ListItem 组件<br>`'widget'` - 使用 ListItemWithWidget 组件 |
| **footer** | `string` | 否 | - | 底部提示文本，显示在卡片容器外部 |
| **disabled** | `boolean` | 否 | - | 是否禁用分组内的所有列表项 |

## 出参（输出/行为）

### 组件渲染输出
- **视觉输出**：根据入参渲染完整的分组 UI
  - 标题：分组标题文本，样式随 `titleSize` 变化
  - 内容区域：包含所有列表项的圆角容器
  - 底部提示：显示在卡片容器外部的提示文本
- **布局输出**：自适应宽度，占满屏幕

### 事件输出
| 事件名 | 触发条件 | 输出值 | 说明 |
|--------|----------|--------|------|
| **子组件事件** | 通过子组件触发 | - | ListCard 本身不直接触发事件，事件由内部的 ListItem 或 ListItemWithWidget 触发 |

### 状态变化
- **禁用状态**：当 `disabled=true` 时，所有子列表项被禁用
- **类型状态**：根据 `type` 选择渲染不同的子组件
- **标题尺寸**：根据 `titleSize` 选择不同的字体、颜色和间距

## 基础用法

```jsx
import React from 'react';
import { ListCard } from '@components/listCard';
import type { ListItemProps } from '@components/listItem/interface';

const MyComponent = () => {
  const listData: ListItemProps[] = [
    {
      title: 'Wi-Fi 设置',
      subtitle: '连接到无线网络',
      onPress: () => console.log('跳转到 Wi-Fi 设置')
    },
    {
      title: '蓝牙',
      subtitle: '管理蓝牙设备',
      onPress: () => console.log('跳转到蓝牙设置')
    },
    {
      title: '个人热点',
      subtitle: '共享网络连接',
      onPress: () => console.log('跳转到热点设置')
    }
  ];

  return (
    <ListCard
      title="网络设置"
      dataSource={listData}
    />
  );
};
```

## 完整示例

### 1. 不同标题尺寸

```jsx
import React from 'react';
import { View } from 'react-native';
import { ListCard } from '@components/listCard';
import type { ListItemProps } from '@components/listItem/interface';

const TitleSizeExample = () => {
  const data: ListItemProps[] = [
    { title: '选项一', onPress: () => {} },
    { title: '选项二', onPress: () => {} },
  ];

  return (
    <View>
      {/* small: 14px medium, 蓝灰色 */}
      <ListCard
        title="小标题"
        titleSize="small"
        dataSource={data}
      />

      {/* medium: 16px medium, 深色 */}
      <ListCard
        title="中标题"
        titleSize="medium"
        dataSource={data}
      />

      {/* large: 20px regular, 深色 */}
      <ListCard
        title="大标题"
        titleSize="large"
        dataSource={data}
      />
    </View>
  );
};
```

### 2. 带开关的分组

```jsx
import React, { useState } from 'react';
import { ListCard } from '@components/listCard';
import { ButtonType } from '@components/listItem';
import type { ListItemWithWidgetProps } from '@components/listItem/interface';

const SwitchGroup = () => {
  const [settings, setSettings] = useState({
    wifi: true,
    bluetooth: false,
    autoPlay: true
  });

  const switchData: ListItemWithWidgetProps[] = [
    {
      type: ButtonType.SWITCH,
      title: 'Wi-Fi',
      subtitle: '连接到无线网络',
      checked: settings.wifi,
      onChange: (val) => setSettings(prev => ({...prev, wifi: val}))
    },
    {
      type: ButtonType.SWITCH,
      title: '蓝牙',
      subtitle: '管理蓝牙设备',
      checked: settings.bluetooth,
      onChange: (val) => setSettings(prev => ({...prev, bluetooth: val}))
    },
    {
      type: ButtonType.SWITCH,
      title: '自动播放',
      subtitle: '网络环境良好时自动播放',
      checked: settings.autoPlay,
      onChange: (val) => setSettings(prev => ({...prev, autoPlay: val}))
    }
  ];

  return (
    <ListCard
      title="开关设置"
      type="widget"
      dataSource={switchData}
    />
  );
};
```

### 3. 带底部提示

```jsx
import React from 'react';
import { ListCard } from '@components/listCard';
import type { ListItemProps } from '@components/listItem/interface';

const TipsGroup = () => {
  const data: ListItemProps[] = [
    {
      title: '个性化推荐',
      subtitle: '根据您的使用习惯推荐内容',
      onPress: () => console.log('推荐设置')
    },
    {
      title: '通知管理',
      subtitle: '管理应用通知权限',
      onPress: () => console.log('通知设置')
    }
  ];

  return (
    <ListCard
      title="推荐设置"
      titleSize="medium"
      dataSource={data}
      footer="底部提示信息会显示在卡片容器外部"
    />
  );
};
```

### 4. 综合设置页面示例

```jsx
import React, { useState } from 'react';
import { ScrollView, StyleSheet } from 'react-native';
import { ListCard } from '@components/listCard';
import { ButtonType } from '@components/listItem';
import type { ListItemProps, ListItemWithWidgetProps } from '@components/listItem/interface';

const SettingsScreen = () => {
  const [settings, setSettings] = useState({
    wifi: true,
    bluetooth: false,
    location: true,
  });

  const networkData: ListItemProps[] = [
    {
      title: 'Wi-Fi',
      subtitle: '连接到无线网络',
      value: '已连接',
      onPress: () => console.log('Wi-Fi 设置')
    },
    {
      title: '蓝牙',
      subtitle: '管理蓝牙设备',
      onPress: () => console.log('蓝牙设置')
    },
  ];

  const switchData: ListItemWithWidgetProps[] = [
    {
      type: ButtonType.SWITCH,
      title: 'Wi-Fi',
      checked: settings.wifi,
      onChange: (val) => setSettings(prev => ({...prev, wifi: val}))
    },
    {
      type: ButtonType.SWITCH,
      title: '位置服务',
      checked: settings.location,
      onChange: (val) => setSettings(prev => ({...prev, location: val}))
    }
  ];

  return (
    <ScrollView style={styles.container}>
      <ListCard
        title="网络设置"
        titleSize="large"
        dataSource={networkData}
        footer="注意：断开网络连接可能会导致部分功能不可用"
      />

      <ListCard
        title="开关设置"
        titleSize="medium"
        type="widget"
        dataSource={switchData}
      />
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
  },
});
```

### 5. 禁用状态示例

```jsx
import React from 'react';
import { ListCard } from '@components/listCard';
import type { ListItemProps } from '@components/listItem/interface';

const DisabledGroup = () => {
  const data: ListItemProps[] = [
    {
      title: '仅读功能',
      subtitle: '此功能不可修改',
      onPress: () => console.log('不会触发')
    },
    {
      title: '受限功能',
      subtitle: '需要管理员权限',
      onPress: () => console.log('不会触发')
    }
  ];

  return (
    <ListCard
      title="受限功能"
      dataSource={data}
      disabled={true}
      footer="当前用户权限不足，无法修改这些设置"
    />
  );
};
```

## 使用技巧

### 1. 数据结构组织

```jsx
// 推荐将分组数据定义在常量中，便于维护
const NETWORK_SETTINGS: ListItemProps[] = [
  { /* ... */ }
];

const SWITCH_SETTINGS: ListItemWithWidgetProps[] = [
  { /* ... */ }
];

<ListCard title="网络设置" dataSource={NETWORK_SETTINGS} />
<ListCard title="开关设置" type="widget" dataSource={SWITCH_SETTINGS} />
```

### 2. 动态数据处理

```jsx
import React, { useState } from 'react';
import { ListCard } from '@components/listCard';
import { ButtonType } from '@components/listItem';
import type { ListItemWithWidgetProps } from '@components/listItem/interface';

const DynamicGroup = () => {
  const [features, setFeatures] = useState([
    { id: 1, title: '功能 A', enabled: true },
    { id: 2, title: '功能 B', enabled: false },
    { id: 3, title: '功能 C', enabled: true },
  ]);

  const switchData: ListItemWithWidgetProps[] = features.map((feature) => ({
    type: ButtonType.SWITCH,
    title: feature.title,
    checked: feature.enabled,
    onChange: (val) => {
      setFeatures(prev =>
        prev.map(item =>
          item.id === feature.id
            ? {...item, enabled: value}
            : item
        )
      );
    }
  }));

  return (
    <ListCard
      title="功能设置"
      type="widget"
      dataSource={switchData}
    />
  );
};
```
