Skip to content

Commit

Permalink
docs: add information how to add component in a React Native application
Browse files Browse the repository at this point in the history
Closes #84
  • Loading branch information
NatSatie authored and ricardodalarme committed Jul 11, 2023
1 parent 2f65e0a commit dee75c5
Show file tree
Hide file tree
Showing 2 changed files with 240 additions and 7 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -106,4 +106,5 @@ EnhancedVideoPlayer(mediaItem = mediaItem)
## Documentation

- [Contributing](docs/CONTRIBUTING.md)
- [Integrating with React Native](docs/react-native.md)
- [Releasing](docs/RELEASING.md)
232 changes: 232 additions & 0 deletions docs/react-native.md
Original file line number Diff line number Diff line change
@@ -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
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:id="@+id/player_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.compose.ui.platform.ComposeView
android:id="@+id/compose_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</merge>
```

### 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<NativeVideoView>() {
// 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<NativeVideoViewManager> {
return listOf(NativeVideoViewManager())
}

override fun createNativeModules(p0: ReactApplicationContext): MutableList<NativeModule> {
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<ReactPackage> getPackages() {
List<ReactPackage> 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<ViewStyle>;
uri?: string | null;
}

const NativeVideoView =
requireNativeComponent<NativeMediaPlayerProps>('VideoView');

const NativeMediaPlayer = ({
style,
uri,
}: NativeMediaPlayerProps): JSX.Element => {
return (
<NativeVideoView style={style} uri={uri} />
);
};

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)

0 comments on commit dee75c5

Please sign in to comment.