React Native显示点9图片

1.背景

本文使用的RN(使用RN表示React Native)的版本为0.44版本。在应用的开发过程,可能会遇到这么一种场景,就是在图片的拉伸过程中,需要保持部分区域不被拉伸,而部分区域需要进行拉伸。比如IM中聊天的背景气泡等。那么这个时候我们就可能需要使用到点9图片。那么在RN中,该如何使用点9图片呢?

2.RN上显示点9图片的思路

首先既然是图片,那么在RN中肯定是需要在组件Image中进行显示,那么RN的Image可以同时支持Android和ios平台的点9图片的制作和显示吗?我们去官方的Api文档上找找看。在RN的文档上我们看到了这样的介绍

ios
capInsets {top: number, left: number, bottom: number, right: number}
当图片被缩放的时候,capInsets指定的角上的尺寸会被固定而不进行缩放,而中间和边上其他的部分则会被拉伸。这在制作一些可变大小的圆角按钮、阴影、以及其它资源的时候非常有用(译注:这就是常说的九宫格或者.9图。了解更多信息,可以参见[苹果官方文档]

可以看到RN的Image组件是可以直接支持capInsets属性,对我们需要的图片进行对应的拉伸操作,这与ios原生的使用是一样的,那么在Android平台上该如何使用呢?很遗憾,在RN上并没有这方面的介绍。
  做过Android原生开发的可能知道,在Android平台上是可以通过工具制作点9图片,然后作为背景图片直接使用,那么按照这个思路,我们可以在Android封装对应的组件,然后在Android平台上要使用的时候就直接使用制作好的点9图片,而在ios平台上我们使用capInsets属性。

3.React Native 9patch image

在这里,我们找到了一个封装好的开源组件,Github地址:https://github.com/rusfearuth/react-native-9patch-image 我们来看下它在Android平台下的封装思路

public class RCTImageCapInsetManager extends SimpleViewManager<RCTImageCapInsetView> {
    @Override
    public String getName() {
        return "RCTImageCapInset";
    }

    @Override
    protected RCTImageCapInsetView createViewInstance(ThemedReactContext reactContext) {
        return new RCTImageCapInsetView(reactContext);
    }

    @ReactProp(name = "source")
    public void setSource(final RCTImageCapInsetView view, ReadableMap source) {
        String uri = source.getString("uri");
        view.setSource(uri);
    }
}

首先从source中获取uri的地址,然后将其赋值给这里的RCTImageCapInsetView,而对于RCTImageCapInsetView

public class RCTImageCapInsetView extends ImageView {
    private String mUri;

    public RCTImageCapInsetView(Context context) {
        super(context);
    }

    public void setSource(String uri) {
        mUri = uri;
        reload();
    }

    public void reload() {
        Integer resId = null;
        if (getImageCache().has(mUri)) {
            resId = getImageCache().get(mUri);
            if (resId == null) {
                getImageCache().remove(mUri);
            }
        }

        if (resId == null) {
            resId = getResourceDrawableId(mUri);
            getImageCache().put(mUri, resId);
        }

        setBackgroundResource(resId);
    }

    private @NonNull Integer getResourceDrawableId(@NonNull final String aName) {
        if (aName == null || aName.isEmpty()) {
                return 0;
        }

        final String name = aName.toLowerCase().replace("-", "_");

        return getResources().getIdentifier(
                name,
                "drawable",
                getContext().getPackageName()
        );
    }

    private RCTImageCache getImageCache()
    {
        return RCTImageCache.getInstance();
    }
}

RCTImageCapInsetView的本质是一个ImageView,获取到uri的名称,然后在drawable之中查找到对应的id名称,最后得到图片资源作为ImageView背景,跟我们在Android原生上使用点9图片的方式是一样的。

4.制作点9图片

4.1 Android平台下制作

在这里我们用到的是Android上默认的logo图片

ic_launcher.png

  将其赋值到res/drawable目录下,并将其改名为image.9.png,在android studio中双击打开它,选择9-patch模式

image.png

  这个时候我们就可以直接在android studio直接进行点9图片的制作,当然我们也可以打开android sdk中提供的点9图片制作工具进行制作,工具路径为:/Users/hzl/Library/Android/sdk/tools/draw9patch 至于如何点9图片的上下左右边界代表的意思,这里不作过多的阐述,可以通过百度,Google等去搜索相关的介绍。这样Android平台上的点9图片就制作完成了。

4.2 ios平台下制作

在上面我们制作了Android平台下的点9图片,那么在ios平台上,对应的capInsets属性是多少呢?我们把鼠标悬停在边界上

image.png
image.png

可以看到Horizontal Patch:29-66px,那么对应的capInsets属性中的left和right就是29和29(95-66=29,其中95是原始图片的宽),同理根据Vertical Patch:40-86px,可以知道capInsets属性中的top和bottom就是40和9

5.RN上显示点9图片

在上面中我们制作好了对应的点9图片,那么我们分别在Android和ios平台上看下效果如果。

import React, {Component} from 'react';
import {View, Platform} from 'react-native';
import NinePatchView from 'react-native-9patch-image';

export default class Main extends Component {

    render() {
        return (
            <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
                <NinePatchView
                    style={{width: 200, height: 200}}
                    source={Platform.OS === 'android' ? {uri: 'image'} : require('./image.png')}
                    capInsets={{top: 40, left: 29, bottom: 9, right: 29}}/>
            </View>)
    }
}

这里要特别注意的是Android平台要使用Release版本的apk才可以看到效果,至于如何打包Android Release版本apk,可以去看下RN官方文档上的介绍,http://reactnative.cn/docs/0.43/signed-apk-android.html#content

ios.png
android.png

  可以看到,两个平台上的显示效果是一致的。

6.最后

文章中使用的例子已经上传了Github:https://github.com/hzl123456/NinePatchView

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,361评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,010评论 4 62
  • 放缓自己的前行脚步,欣赏路边的风景,平凡的过一辈子,一切安好,也是一道美好人生风景线。 这几天有个新闻,刺痛了我的...
    太湖晨风阅读 392评论 0 2
  • 寻一朵月季, 追一米阳光, 凝一瞬格局, 换一个微笑, 藏一脸喜悦。 细之微处, 话那款款情深, 返璞归真。
    佛笑来人阅读 142评论 6 20
  • 回校已快一个星期,又回到了放假前的状态,从以前上个厕所吃个饭都要人陪的我,慢慢独来独往,一个人去吃饭、健身馆、图书...
    小小海棠阅读 122评论 0 0