如何在React Native中创建并使用9-patch图片?
如何在React Native中创建并使用9-patch图片?
嘿,我完全懂你想要的那种按钮或容器背景拉伸不变形的效果,React Native里直接丢.9.png到Image组件里不生效其实是有原因的——Android原生支持9-patch,但iOS根本不认这个格式,而且两边的处理方式不一样,咱不用第三方库,纯靠原生组件就能搞定,一步步来:
一、先做出符合规范的9-patch图片
首先得把你的普通PNG转成标准的.9.png,用Android Studio自带的Draw 9-patch工具最靠谱:
- 打开工具后导入你的原图,在图片的四个边缘画细黑线:顶部和左侧的线标记可拉伸区域,右侧和底部的线标记内容可以显示的区域
- 保存的时候文件名必须是
xxx.9.png(比如button_bg.9.png),这个后缀绝对不能错,不然Android不认 - 划重点:这张.9.png只给Android用,别放到iOS的资源目录里去
二、Android平台直接用原生支持
把做好的xxx.9.png放到Android项目的android/app/src/main/res/drawable目录(没有的话新建一个),然后在React Native里这么用:
import React from 'react'; import { Image, View } from 'react-native'; const StretchyButton = () => ( <View style={{ width: 200, height: 50 }}> <Image // 注意:引用的时候别带.9后缀!只写文件名 source={require('./android/app/src/main/res/drawable/button_bg')} style={{ width: '100%', height: '100%' }} /> </View> ); export default StretchyButton;
这样Android系统会自动识别这是9-patch图片,严格按照你标记的区域拉伸,边角绝对不会变形
三、iOS平台用capInsets模拟9-patch效果
iOS没有9-patch的概念,咱用React Native Image组件的capInsets属性来实现同样的效果——这个属性就是告诉iOS:图片的哪些区域不能拉伸,只能拉伸中间部分
- 先把你的普通PNG(不用转9-patch)放到iOS项目的
Images.xcassets或者项目目录里 - 先量好你要保留的边角尺寸,比如你的图片是100x100,左右上下各20px是不想变形的边角,那代码这么写:
import React from 'react'; import { Image, View, Platform } from 'react-native'; const StretchyButton = () => { // 分平台选图片资源 const bgSource = Platform.select({ android: require('./android/app/src/main/res/drawable/button_bg'), ios: require('./ios/YourProjectName/Images/button_bg.png') }); // 分平台设置样式 const bgStyle = Platform.select({ android: { width: '100%', height: '100%' }, ios: { width: '100%', height: '100%', // 四个值分别是:上、右、下、左的固定区域大小 capInsets: { top: 20, right: 20, bottom: 20, left: 20 }, // 必须设置resizeMode为stretch或者repeat,默认的cover不行 resizeMode: 'stretch' } }); return ( <View style={{ width: 200, height: 50 }}> <Image source={bgSource} style={bgStyle} /> </View> ); }; export default StretchyButton;
调capInsets的数值的时候多试几次,直到拉伸出来的效果和你想要的一致就行
四、避坑小提示
- Android端引用9-patch图片时,绝对不能带.9后缀,比如别写
require('./button_bg.9.png'),不然会当成普通图片渲染 - iOS端的capInsets数值要和你的图片实际尺寸匹配,比如图片边角是15px,就把四个值设为15
- 不管哪边,都要给Image或者它的父View设置明确的宽高,不然图片可能不会正确拉伸
内容来源于stack exchange




