From dee75c515e5240bd71d9380e9ee6137083db3bf6 Mon Sep 17 00:00:00 2001 From: Natalia Satie Odashima Date: Wed, 5 Jul 2023 12:09:21 -0300 Subject: [PATCH] docs: add information how to add component in a React Native application Closes #84 --- README.md | 15 +-- docs/react-native.md | 232 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 7 deletions(-) create mode 100644 docs/react-native.md diff --git a/README.md b/README.md index f22fb251..2537cc85 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,13 @@ Enhanced Video Player for Android built on top of Exoplayer compliant with Andro ## Table of Contents - - [Table of Contents](#table-of-contents) - - [Installation](#installation) - - [Media Types](#media-types) - - [HLS](#hls) - - [DASH](#dash) - - [MSS/SmoothStreaming](#msssmoothstreaming) - - [Documentation](#documentation) +- [Table of Contents](#table-of-contents) +- [Installation](#installation) +- [Media Types](#media-types) + - [HLS](#hls) + - [DASH](#dash) + - [MSS/SmoothStreaming](#msssmoothstreaming) +- [Documentation](#documentation) ## Installation @@ -106,4 +106,5 @@ EnhancedVideoPlayer(mediaItem = mediaItem) ## Documentation - [Contributing](docs/CONTRIBUTING.md) +- [Integrating with React Native](docs/react-native.md) - [Releasing](docs/RELEASING.md) diff --git a/docs/react-native.md b/docs/react-native.md new file mode 100644 index 00000000..ce1b55f9 --- /dev/null +++ b/docs/react-native.md @@ -0,0 +1,232 @@ +# React Native Guide Use + +## Minimal Requirements + +- Kotlin: 1.8.22 +- Gradle: 7.6.1 + +**Warning: This guide uses the older architecture of React Native, Android UI Components.** + +## Setup + +### Setting `android/build.gradle` + +```groovy +buildscript { + ext { + buildToolsVersion = "33.0.0" + minSdkVersion = 26 + compileSdkVersion = 33 + targetSdkVersion = 33 + kotlinVersion = "1.8.22" + mediaVersion = "1.0.2" + } + repositories { + google() + mavenCentral() + maven { + url 'https://maven.google.com' + name 'Google' + } + maven { url 'https://plugins.gradle.org/m2/' } + maven { url 'https://jitpack.io' } + } + dependencies { + classpath('com.android.tools.build:gradle:7.4.2') + } +} +``` + +### Setting `android/app/build.gradle` + +In `android/app/build.gradle`, add the following lines in `android` and `dependencies`: + +```groovy +android { + compileOptions { + targetCompatibility JavaVersion.VERSION_1_8 + } + + composeOptions { + kotlinCompilerExtensionVersion = "1.4.8" + } + + buildFeatures { + compose true + } +} + +dependencies { + implementation "com.github.profusion:android-enhanced-video-player:0.2.0" + implementation "androidx.media3:media3-exoplayer:$mediaVersion" + implementation "androidx.media3:media3-exoplayer-dash:$mediaVersion" + implementation "androidx.media3:media3-ui:$mediaVersion" + + def composeBom = platform('androidx.compose:compose-bom:2023.05.01') + implementation composeBom + androidTestImplementation composeBom + implementation 'androidx.compose.ui:ui' + implementation 'androidx.compose.ui:ui-tooling-preview' + debugImplementation 'androidx.compose.ui:ui-tooling' +} +``` + +# How to setup the component in Android React Native + +1. Add the ComposeView in the xml file in `android/app/src/main/res/layout` +2. Create your component +3. Create the component's manager +4. Create the component's package +5. Import the component's package in `getPackages()` in `android/app/src/main/java/com/rngql/MainApplication.java` + +### 1. Add ComposeView in xml file at `android/app/src/main/res/layout` + +Consider the file is called `my-xml-file.xml` + +```xml + + + + + + +``` + +### 2. Create component's view + +```kotlin +class NativeVideoView(context: ThemedReactContext) : RelativeLayout(context) { + private val composeView: ComposeView + private val player: ExoPlayer + var uri: String? = null + set(value) { + field = value + updateUri() + } + + // Connects the view with the xml file + init { + inflate(context, R.layout.my-xml-file, this) + player = ExoPlayer.Builder(context).build() + composeView = findViewById(R.id.compose_view) + initContent() + } + + // Set the Exoplayer to play a certain uri with a mp4 file + private fun updateUri() { + player.setMediaItem(MediaItem.fromUri(Uri.parse(uri))) + player.prepare() + } + + // Responsible to stop media functions if the player is not visible + fun onDropViewInstance() { + player.release() + } + + // Create an instance of EnhancedVideoPlayer which is linked with Exoplayer + private fun initContent() { + composeView.setContent { + EnhancedVideoPlayer( + exoPlayer = player, + ) + } + } +} + +``` + +### 3. Create component's manager + +```kotlin +class NativeVideoViewManager : SimpleViewManager() { + // Defines the name of component used in React Native + override fun getName() = "VideoView" + + override fun createViewInstance(reactContext: ThemedReactContext): NativeVideoView { + return NativeVideoView(reactContext) + } + + // Defines the prop to be used in React Native + @ReactProp(name = "uri") + fun setUri(view: NativeVideoView, uri: String?) { + view.uri = uri + } + + // If the view is not available, it'll release the player + override fun onDropViewInstance(view: NativeVideoView) { + view.onDropViewInstance() + } +} + +``` + +### 4. Create component's package + +```kotlin +class NativeVideoViewPackage : ReactPackage { + override fun createViewManagers(reactContext: ReactApplicationContext): List { + return listOf(NativeVideoViewManager()) + } + + override fun createNativeModules(p0: ReactApplicationContext): MutableList { + return mutableListOf() + } +} +``` + +### 5. Import package in MainApplication + +```kotlin +public class MainApplication extends Application implements ReactApplication { + + private final ReactNativeHost mReactNativeHost = + new DefaultReactNativeHost(this) { + @Override + protected List getPackages() { + List packages = new PackageList(this).getPackages(); + packages.add(new NativeVideoViewPackage()); + return packages; + } +``` + +## Usage in React Native + +First of all, make sure to clean the cache and build the Android application. + +In order to import the components we need to use `requireNativeComponent`. + +```typescript +import { requireNativeComponent } from 'react-native'; + +interface NativeMediaPlayerProps { + style?: StyleProp; + uri?: string | null; +} + +const NativeVideoView = + requireNativeComponent('VideoView'); + +const NativeMediaPlayer = ({ + style, + uri, +}: NativeMediaPlayerProps): JSX.Element => { + return ( + + ); +}; + +export default NativeMediaPlayer; +``` + +## References + +- [Compose in Views](https://developer.android.com/jetpack/compose/migrate/interoperability-apis/compose-in-views) +- [Android Native UI Components](https://reactnative.dev/docs/native-components-android) +- [Stackoverflow: Android: Jetpack Compose and XML in Activity](https://stackoverflow.com/questions/65648904/android-jetpack-compose-and-xml-in-activity)