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.
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); } }); } }
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.
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() ); } }
Add to MainApplication List
This is final step where you add the package so that React Native can detect your view.
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); } }
In React Native
Create a file named ‘ImageView.js’ and copy the below code into it.
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);
Usage
<ImageView src={ 'your_img_url' } style={{width: 100, height: 100}} />
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
#import <Foundation/Foundation.h> #import <React/RCTViewManager.h> @interface NativeView : RCTViewManager @end
RCTViewManager is the base class for view in React Native for iOS.
Now in NativeView.m
#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
Use it same like android
import { requireNativeComponent } from 'react-native'; // requireNativeComponent automatically resolves 'RNTMap' to 'RNTMapManager' module.exports = requireNativeComponent('NativeView', null);
Pingback: How to listen to events from react native? – CODERZHEAVEN