How to create a custom native ImageView/View in Android or iOS for ReactNative?

By | August 10, 2018

Many times we need custom components from native.

Here is a simple example on how to create a custom imageview in Android for react native.

First we will start with the Android Version

Android

  • Create a class that extends SimpleViewManager.
  • Write a setSrc method which accepts the source url from React Native.
  • Implement ‘createViewInstance’ method in which you can create the ImageView instance.
  • Listen for the setter to set the url and then start downloading the image.
  • Require the Native Component and set the import the ImageView just created from Native to React Native.
  • Pass the properties

and you are done.

Lets Start…

Java Class

Here is the complete class that creates the imageview and downloads the image.

[java]

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.Log;

import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.image.ReactImageView;

import java.net.URL;

public class ReactImageManager extends SimpleViewManager<ReactImageView> {

public static final String REACT_CLASS = "RCTImageView1";
private final @Nullable
Object mCallerContext = null;
private ImgStartListener imgStartListener;

/* Interface Listener to start loading the image if the source is set */
private interface ImgStartListener {
void startLoading(String imgUrl);
}

@Override
public String getName() {
return REACT_CLASS;
}

/* Method which sets the source from React Native */
@ReactProp(name = "src")
public void setSrc(ReactImageView view, String uri) {
imgStartListener.startLoading(uri);
}

@Override
protected ReactImageView createViewInstance(ThemedReactContext reactContext) {

final ReactImageView reactImageView = new ReactImageView(reactContext, Fresco.newDraweeControllerBuilder(), null, mCallerContext);

final Handler handler = new Handler();
imgStartListener = new ImgStartListener() {
@Override
public void startLoading(final String imgUrl) {
startDownloading(imgUrl, handler, reactImageView);

}
};

return reactImageView;
}

private void startDownloading(final String imgUrl, final Handler handler, final ReactImageView reactImageView) {
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(imgUrl);
final Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
setImage(bmp, handler, reactImageView);
} catch (Exception e) {
Log.e("ReactImageManager", "Error : " + e.getMessage());
}
}
}).start();
}

private void setImage(final Bitmap bmp, Handler handler, final ReactImageView reactImageView) {
handler.post(new Runnable() {
@Override
public void run() {
reactImageView.setImageBitmap(bmp);
}
});
}
}
[/java]

You can improve this view the way you want. This is only a simple implementation of an image.

Add to ViewManagers

Next step is to add this to a viewmanagers list.
Create a class named say “AnExampleReactPackage” and implement ReactPackage.
Add the above class to the ‘createViewManagers’ method.

[java]

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.helloworld.ToastModule;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class AnExampleReactPackage implements ReactPackage {

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new ReactImageManager()
);
}

}
[/java]

Add to MainApplication List

This is final step where you add the package so that React Native can detect your view.

[java]
public class MainApplication extends Application implements ReactApplication {

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new VectorIconsPackage(),
// add here
new AnExampleReactPackage()
);
}

@Override
protected String getJSMainModuleName() {
return "index";
}
};

@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}

@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
[/java]

In React Native

Create a file named ‘ImageView.js’ and copy the below code into it.

[html]
import PropTypes from ‘prop-types’;
import {requireNativeComponent, ViewPropTypes} from ‘react-native’;

var iface = {
name: ‘ImageView’,
propTypes: {
src: PropTypes.string,
borderRadius: PropTypes.number,
resizeMode: PropTypes.oneOf([‘cover’, ‘contain’, ‘stretch’]),
…ViewPropTypes, // include the default view properties
},
};

module.exports = requireNativeComponent(‘RCTImageView1’, iface);
[/html]

Usage

[html]
<ImageView
src={ ‘your_img_url’ }
style={{width: 100, height: 100}}
/>
[/html]

Now we will look at ios. Here instead of creating an ImageView, I am creating just a view in iOS.

iOS

Create new Files inside your application say”NativeView”.

Create Cocoa Files NativeView.m and .h

Now open NativeView.h and copy this code

[java]
#import <Foundation/Foundation.h>

#import <React/RCTViewManager.h>

@interface NativeView : RCTViewManager

@end
[/java]

RCTViewManager is the base class for view in React Native for iOS.

Now in NativeView.m

[java]
#import "NativeView.h"

@implementation NativeView

RCT_EXPORT_MODULE()
– (UIView *)view
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.backgroundColor = [UIColor blueColor];
return view;
}

@end
[/java]

Use it same like android

[java]
import { requireNativeComponent } from ‘react-native’;

// requireNativeComponent automatically resolves ‘RNTMap’ to ‘RNTMapManager’

module.exports = requireNativeComponent(‘NativeView’, null);
[/java]

One thought on “How to create a custom native ImageView/View in Android or iOS for ReactNative?

  1. Pingback: How to listen to events from react native? – CODERZHEAVEN

Leave a Reply

Your email address will not be published. Required fields are marked *