Skip to content

Commit

Permalink
feat(messaging/android): pass events to Flutter
Browse files Browse the repository at this point in the history
  • Loading branch information
p-mazhnik committed Sep 28, 2022
1 parent d553183 commit 828253c
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 12 deletions.
35 changes: 29 additions & 6 deletions ReactNativeApp/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import {
ScrollView,
StatusBar,
Text,
TextInput,
View,
} from 'react-native';
import { NavigationContainer, ParamListBase } from '@react-navigation/native';
import { NavigationContainer } from '@react-navigation/native';
import {
createNativeStackNavigator,
NativeStackScreenProps,
Expand All @@ -38,13 +39,14 @@ const Stack = createNativeStackNavigator();

type RootStackParamList = {
Home: { counter: number };
Flutter: undefined;
Flutter: { initialCounterValue: number };
};

function HomeScreen({
navigation,
route,
}: NativeStackScreenProps<RootStackParamList, 'Home'>) {
const [initialCounterValue, setCounter] = useState<number>(0);
const backgroundStyle = {
backgroundColor: Colors.lighter,
flex: 1,
Expand All @@ -57,13 +59,28 @@ function HomeScreen({
style={backgroundStyle}>
<Button
title={'Start Flutter Screen'}
onPress={() => navigation.navigate('Flutter')}
onPress={() =>
navigation.navigate({
name: 'Flutter',
params: { initialCounterValue },
merge: true,
})
}
/>
<View>
<Text>Enter initial counter value</Text>
<TextInput
keyboardType="numeric"
onChangeText={text => setCounter(Number(text))}
value={initialCounterValue.toString()}
maxLength={10}
/>
</View>
<View style={{ alignSelf: 'center' }}>
<Text>
You have pushed the button on the Flutter screen this many times:
</Text>
<Text style={{ textAlign: 'center' }}>{route.params?.counter}</Text>
<Text style={{ textAlign: 'center' }}>{route.params.counter}</Text>
</View>
</ScrollView>
</SafeAreaView>
Expand All @@ -72,7 +89,8 @@ function HomeScreen({

function FlutterScreenWrapper({
navigation,
}: NativeStackScreenProps<ParamListBase>) {
route,
}: NativeStackScreenProps<RootStackParamList, 'Flutter'>) {
const [counter, setCounter] = useState<number>(0);
const onCounterIncrement = (value: number) => {
console.log(`onCounterIncrement: ${value}`);
Expand All @@ -84,6 +102,7 @@ function FlutterScreenWrapper({
}, [counter, navigation]);
return (
<FlutterScreen
initialCounterValue={route.params.initialCounterValue}
onCounterIncrement={onCounterIncrement}
onScreenClose={onScreenClose}
/>
Expand All @@ -99,7 +118,11 @@ const App: React.FC = () => {
component={HomeScreen}
initialParams={{ counter: 0 }}
/>
<Stack.Screen name="Flutter" component={FlutterScreenWrapper} />
<Stack.Screen
name="Flutter"
component={FlutterScreenWrapper}
initialParams={{ initialCounterValue: 0 }}
/>
</Stack.Navigator>
</NavigationContainer>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.reactlibrary;

import android.os.Bundle;

import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
Expand All @@ -11,6 +13,9 @@
public class FlutterModuleActivity extends FlutterActivity {
private static final String CHANNEL = "pavel/flutter";

public static final String INITIAL_EVENT = "INITIAL_EVENT";
public static final String INITIAL_ARGS = "INITIAL_ARGS";

// React Native event emitter. Uset to send events to the host React Native app
private DeviceEventManagerModule.RCTDeviceEventEmitter reactNativeEventEmitter = null;

Expand Down Expand Up @@ -39,4 +44,16 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
}
);
}

@Override
public void onFlutterUiDisplayed() {
Bundle extras = this.getIntent().getExtras();
String eventName = extras.getString(INITIAL_EVENT);
String args = extras.getString(INITIAL_ARGS);
sendEventToFlutter(eventName, args);
}

public void sendEventToFlutter(String eventName, String args) {
channel.invokeMethod(eventName, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,34 @@ public String getName() {
}

@ReactMethod
public void startFlutterActivity(String stringArgument, int numberArgument, Callback callback) {
public void startFlutterActivity(String eventName, String args, Callback callback) {
Activity currentActivity = reactContext.getCurrentActivity();
// we can pass arguments to the Intent
currentActivity.startActivity(
new FlutterActivity
.NewEngineIntentBuilder(FlutterModuleActivity.class)
.build(currentActivity)
.putExtra(FlutterModuleActivity.INITIAL_EVENT, eventName)
.putExtra(FlutterModuleActivity.INITIAL_ARGS, args)
);
callback.invoke("Received numberArgument: " + numberArgument + " stringArgument: " + stringArgument);
callback.invoke("Received eventName: " + eventName + ", args: " + args);
}

@ReactMethod
public void sendEvent(String eventName, String args) {
Activity currentActivity = reactContext.getCurrentActivity();
if (currentActivity instanceof FlutterModuleActivity) {
((FlutterModuleActivity) currentActivity).sendEventToFlutter(eventName, args);
}
}

@ReactMethod
public void addListener(String eventName) {
// Keep: Required for RN built in Event Emitter Calls.
}

@ReactMethod
public void removeListeners(Integer count) {
// Keep: Required for RN built in Event Emitter Calls.
}
}
15 changes: 15 additions & 0 deletions flutter_module_rn/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ class _MyHomePageState extends State<MyHomePage> {
static const platform = MethodChannel('pavel/flutter');

int _counter = 0;
bool _received = false;

@override
void initState() {
platform.setMethodCallHandler((call) async {
if (call.method == 'setCounterValue') {
setState(() {
_received = true;
_counter = int.parse(call.arguments as String);
});
}
});
super.initState();
}

void _incrementCounter() {
setState(() {
Expand Down Expand Up @@ -107,6 +121,7 @@ class _MyHomePageState extends State<MyHomePage> {
const Text(
'You have pushed the button this many times:',
),
if (_received) const Text('(counter set from initial value)'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
Expand Down
4 changes: 3 additions & 1 deletion flutter_module_rn/src/FlutterScreen/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import * as React from 'react'

interface FlutterModuleRn {
startFlutterActivity: (arg1: string, arg2: number, callback: (text: string) => void) => void;
startFlutterActivity: (initialEvent: string, args: string, callback: (text: string) => void) => void;
sendEvent: (event: string, args?: string) => void;
}

interface FlutterScreenProps {
onCounterIncrement: (value: number) => void;
onScreenClose: () => void;
initialCounterValue: number;
}

declare const FlutterScreen: React.FC<FlutterScreenProps>
Expand Down
6 changes: 3 additions & 3 deletions flutter_module_rn/src/FlutterScreen/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { ActivityIndicator, NativeEventEmitter, NativeModules, Platform, Text, V
import React, { useEffect } from 'react'

const { FlutterModuleRn } = NativeModules;
const eventEmitter = new NativeEventEmitter(FlutterModuleRn);

const FlutterScreen = ({ onCounterIncrement, onScreenClose }) => {
const FlutterScreen = ({ initialCounterValue, onCounterIncrement, onScreenClose }) => {
useEffect(() => {
FlutterModuleRn.startFlutterActivity('', 0, (text) => {
FlutterModuleRn.startFlutterActivity('setCounterValue', initialCounterValue.toString(), (text) => {
console.log(text);
});
}, [])
useEffect(() => {
const eventEmitter = new NativeEventEmitter(FlutterModuleRn);
const listener1 = eventEmitter.addListener('incrementCounter', (event) => {
onCounterIncrement(event);
});
Expand Down

0 comments on commit 828253c

Please sign in to comment.