React Native Elements Tile 组件完全指南:从三种基础用法到源码级原理解析
【免费下载链接】react-native-elementsCross-Platform React Native UI Toolkit项目地址: https://gitcode.com/gh_mirrors/re/react-native-elements
本指南基于
react-native-elements仓库中的 Tile 官方文档 及其 Props 参考 props/tile.md 编写。Tile 是 React Native Elements 中用于展示"单一主题相关内容"的图块组件:它以图片为视觉主体,可叠加标题、说明文字、图标,或嵌入任意自定义内容。读完本文,你将掌握 Featured Tile、带图标 Tile 与内容型 Tile 三种用法,理解全部 20 个 Props 的取值与默认行为,并从packages/base/src/Tile/的源码出发,弄清featured分支、默认尺寸计算、按压反馈与主题化机制等底层实现。
Tile 是什么
Tiles(图块)与 Cards 类似,都是"围绕单一主题展示一组相关内容"的便捷容器,但二者侧重不同:Tile 以全幅图片作为视觉主体,文字与图标直接叠加在图片之上(featured 模式)或位于图片下方的内容区;它常被用来构建瀑布流式的图片列表、媒体卡片、商品展示块等场景。
在 v3.4.2 文档中明确说明:该组件的设计灵感来自 Shoutem UI(Shoutem 团队)。自该版本以来,Tile 一直是 React Native Elements 的基础组件之一,当前仓库中它的实现位于:
- 基础(无主题绑定)实现:packages/base/src/Tile/Tile.tsx
- featured 分支实现:packages/base/src/Tile/components/FeaturedTile.tsx
- 主题化(绑定 Theme)实现:packages/themed/src/Tile/index.tsx
- 导出入口:packages/base/src/index.ts(
export * from './Tile')
安装与引入
Tile 属于 React Native Elements 核心包。安装 react-native-elements 后,即可从主包或子包引入:
// 经典方式(v3.4.2 文档示例) import { Tile } from 'react-native-elements'; // 当前仓库的模块化方式 import { Tile } from '@rneui/base'; import Tile from '@rneui/themed'; // 主题化版本,默认导出其中@rneui/base的 Tile 为纯基础组件(packages/base/src/Tile/index.tsx 仅导出Tile与TileProps类型);@rneui/themed的 Tile 通过withTheme包装,可读取全局主题中的组件级默认配置(见下文"主题化"一节)。
三种基础用法
原文档给出了三个可直接复制的经典示例,分别覆盖 featured 叠加、图标叠加与自定义内容三种场景。图片资源通过require('./img/path')或{ uri: '...' }对象传入imageSrc。
1. Featured Tile(标题叠加图块)
featured模式会把标题与说明文字直接覆盖渲染在图片之上,是文档中的第一种用法:
import { Tile } from 'react-native-elements'; <Tile imageSrc={require('./img/path')} title="Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolores dolore exercitationem" featured caption="Some Caption Text" />;要点:
featured为true时,组件内部会改走 FeaturedTile.tsx 分支,图片采用全幅背景图方式铺满整个 Tile。title与caption渲染在绝对定位的 overlay 容器内,默认文字颜色为白色(#ffffff)、居中对齐、四周带留白(左右 25、上下 45/40),见 FeaturedTile.tsx。- 标题默认使用
h4字号,仅当你同时传入titleStyle且其中包含fontSize时才改用自定义字号(源码判断:h4={!titleStyle || !('fontSize' in titleStyle)},见 Tile.tsx 与 FeaturedTile.tsx)。
2. Featured Tile with Icon(带图标的图块)
在 featured 基础上增加一个居中图标(例如播放按钮),适合做视频/媒体入口:
import { Tile } from 'react-native-elements'; <Tile imageSrc={require('./img/path')} icon={{ name: 'play-circle', type: 'font-awesome' }} featured />;图标通过icon对象配置,其结构为{ name, color, size, type, iconStyle }。其中type默认是material,也可换成 React Native Elements 支持的任意图标集(如font-awesome、ionicon、material-community等,可参考 icon.md 中的可用图标集列表)。图标最终由 Icon 组件 渲染,位于 overlay 容器内、标题上方并整体居中(FeaturedTile.tsx)。
3. Tile with Icon(内容型图块)
不开启featured时,Tile 由"图片区 + 底部内容区"组成,children会渲染在内容区内,适合放入自定义 Caption、按钮或其他元素:
import { Tile } from 'react-native-elements'; <Tile imageSrc={require('./img/path')} title="Lorem ipsum dolor sit amet, consectetur" icon={{ name: 'play-circle', type: 'font-awesome' }} // optional contentContainerStyle={{ height: 70 }} > <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }} > <Text>Caption</Text> <Text>Caption</Text> </View> </Tile>;要点:
- 非 featured 分支的渲染逻辑在 Tile.tsx:外层为
Pressable,内部依次为图片组件(默认resizeMode="cover"铺满)、居中的图标容器、底部内容容器。 - 底部内容容器默认内边距为
15/5/15/15(Tile.tsx),可通过contentContainerStyle覆盖,例如示例中把它固定为height: 70。 title渲染为Text(带testID="tileTitle"),children紧随其后,二者共同构成内容区。
Props 完整参考(含类型与默认值)
以下信息完整继承自 v3.4.2 的 props/tile.md,并与当前源码逐一核对。此外,Tile 还会接收所有 TouchableNativeFeedback(Android)或 TouchableOpacity(iOS)的触摸相关 Props——在当前仓库实现中,TileProps直接继承自PressableProps(Tile.tsx),因此onPress、disabled、delayPressIn等 Pressable 属性均可透传。
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
activeOpacity | number | 0.2 | 按压时的透明度/高亮系数 |
caption | string或React 元素/组件 | 无 | featured 模式下显示在 Tile 上的说明文字 |
captionStyle | object (style) | 无 | caption 的样式(仅当caption为字符串时生效) |
containerStyle | object (style) | 无 | 最外层 Tile 容器的样式 |
contentContainerStyle | object (style) | 无 | 非 featured 模式下底部内容区的样式 |
featured | boolean | false | 切换为图片叠加文字的 featured 外观 |
height | number | Device Width × 0.8 | Tile 高度 |
icon | object | 无 | 图标配置:{name: string, color: string, size: number, type: string(默认 material,或选择支持的图标集), iconStyle: object(style)} |
iconContainerStyle | object (style) | 无 | 图标外层容器的样式 |
ImageComponent | React 组件或元素 | BackgroundImage | 自定义图片渲染组件 |
imageContainerStyle | object (style) | 无 | 图片区域的样式 |
imageProps | object(Image Props 子集) | 无 | 传给图片的额外属性,例如resizeMode(完整属性见 image.md) |
imageSrc | object (image) | 必填 | 图片来源,require(...)或{ uri: '...' } |
onPress | function (event) | 无 | Tile 被按下时回调 |
overlayContainerStyle | object (View style) | 无 | featured 模式下 overlay 容器的样式 |
title | string | 无 | Tile 上的标题文本 |
titleNumberOfLines | number | 无 | 标题的最大行数 |
titleStyle | object (style) | 无 | 标题的样式 |
width | number | Device Width | Tile 宽度 |
说明:
height的默认值在文档中写作 "Device Width × 0.8",当前源码实现为height = width * 0.8(Tile.tsx);width默认取Dimensions.get('window').width,即屏幕窗口宽度。
源码级原理解析
featured分支与图片渲染差异
Tile组件的入口根据featured做分支(Tile.tsx):
featured === true:把title/icon/caption/children/imageSrc/onPress/activeOpacity/containerStyle/imageContainerStyle/overlayContainerStyle/titleStyle/captionStyle/width/height/imageProps/ImageComponent打包传给FeaturedTile。此时图片使用 BackgroundImage(见 FeaturedTile.tsx),并配合绝对定位、铺满整个 Tile 的 overlay 容器(position: absolute+top/left/right/bottom: 0,FeaturedTile.tsx)实现"文字浮于图片之上"。- 否则:走普通分支,图片使用 React Native Elements 自带的 Image 组件(
ImageComponent = Image,Tile.tsx),图片区域占flex: 2,底部内容区自适应。因此 Props 文档中ImageComponent的默认值标注为 BackgroundImage 是针对 featured 模式而言的。
默认尺寸与图片裁切
不传width/height时,Tile 默认占满整屏宽、高度为宽度的 80%(width * 0.8)。图片统一使用resizeMode="cover"填充(Tile.tsx、FeaturedTile.tsx),即等比放大并裁切超出部分,保证任意尺寸的图片都能铺满 Tile 且不变形。如果你需要不同的裁切策略,可通过imageProps={{ resizeMode: 'contain' }}覆盖。
按压反馈:从 Touchable 到 Pressable
v3.4.2 文档说明 Tile 会透传TouchableNativeFeedback(Android)/TouchableOpacity(iOS)的 Props;在当前仓库的基础实现中,组件已改用 React Native 的Pressable作为触摸根节点(Tile.tsx),TileProps extends PressableProps。一个值得注意的实现细节是:Android 水波纹颜色由主题主色与activeOpacity共同计算而来:
android_ripple: androidRipple( Color(theme?.colors?.primary).alpha(activeOpacity).rgb().toString() )(见 Tile.tsx。)也就是说activeOpacity在 Android 上会直接影响 ripple 高亮的透明度,文档标注的默认值 0.2 即对应默认按压高亮强度。
主题化:组件级默认配置
通过@rneui/themed引入的 Tile 由withTheme(Tile, 'Tile')包装(packages/themed/src/Tile/index.tsx),因而可以在全局主题中为 Tile 声明默认 Props,例如给所有 Tile 统一设置默认标题:
const theme = { Tile: { title: 'Mary is friendly', }, };这在 packages/themed/src/Tile/tests/Tile.test.tsx 中有对应测试:传入上述主题后,渲染出的Text子节点内容即为'Mary is friendly'。同理,FeaturedTile也有独立的主题键'FeaturedTile',两者可分别配置。
组件测试
仓库为 Tile 提供了完整的快照与行为测试,可作为自定义扩展时的参考:
- packages/themed/src/Tile/tests/Tile.test.tsx:验证基础渲染(仅传
imageSrc={{ uri: 'http://google.com' }})与主题默认 Props 应用; - packages/themed/src/Tile/tests/FeaturedTile.test.tsx:覆盖 featured 分支;
- 快照文件:packages/themed/src/Tile/tests/snapshots/Tile.test.tsx.snap。
实战建议与注意事项
imageSrc是唯一必填项:其余 Props 均有合理默认,最小可用的 Tile 只需一行<Tile imageSrc={require('./img')} />。- featured 模式与普通模式渲染结构完全不同:需要"文字压图"用
featured;需要"图片上方图标 + 下方文字/自定义内容"用普通模式,并通过contentContainerStyle控制内容区高度与间距。 - 图标集选择:
icon.type默认material,其它图标集(如font-awesome、ionicon)需要对应的图标字体已注册;具体可用集合见 icon.md。 - 按需覆盖图片行为:通过
imageProps传入resizeMode、borderRadius等 Image 属性,或通过ImageComponent换成自定义加载组件(如占位图/模糊加载实现)。 - 标题截断:长标题配合
titleNumberOfLines限制行数,避免撑破布局;标题默认h4字号,传入含fontSize的titleStyle后即完全由你控制。 - 交互:
onPress直接可用;如需禁用点击,可透传 Pressable 的disabled属性。若想快速试验各 Props 的效果,官方 playground 配置见 website/playground/Tile/tile.playground.tsx,它基于react-view对上述全部 Props 提供了可视化调参入口。
【免费下载链接】react-native-elementsCross-Platform React Native UI Toolkit项目地址: https://gitcode.com/gh_mirrors/re/react-native-elements
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考