feat(navigation): 实现基础导航功能
- 新增 NavigationHelper、NavigationManager 和 AppManager 类 - 实现 navigate 和 pop 方法 - 添加 MainActivity 和 BuzActivity 作为导航示例 - 更新 App.tsx,添加导航按钮 - 新增互联网医院模块作为导航目标
这个提交包含在:
父节点
28646bf960
当前提交
da6c39d068
@ -4,23 +4,24 @@
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/AppTheme"
|
||||
android:supportsRtl="true">
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.trust.ywx.BuzActivity" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.trust.ywx
|
||||
|
||||
import android.app.Activity
|
||||
import java.util.Stack
|
||||
|
||||
object AppManager {
|
||||
private val activityStack: Stack<Activity> = Stack()
|
||||
fun addActivity(activity: Activity) {
|
||||
activityStack.add(activity)
|
||||
}
|
||||
|
||||
fun removeActivity(activity: Activity) {
|
||||
activityStack.remove(activity)
|
||||
}
|
||||
|
||||
fun finishActivity(activity: Activity?) {
|
||||
if (activity != null) {
|
||||
removeActivity(activity)
|
||||
activity.finish()
|
||||
} else {
|
||||
lastActivity()?.apply {
|
||||
removeActivity(this)
|
||||
this.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun lastActivity(): Activity? {
|
||||
return activityStack.lastElement()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.trust.ywx
|
||||
|
||||
import android.os.Bundle
|
||||
import com.facebook.react.ReactActivity
|
||||
import com.trust.ywx.specs.navigation.NavigationHelper
|
||||
import com.facebook.react.ReactActivityDelegate
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
|
||||
import com.facebook.react.defaults.DefaultReactActivityDelegate
|
||||
|
||||
class BuzActivity : ReactActivity() {
|
||||
|
||||
/**
|
||||
* Returns the name of the main component registered from JavaScript. This is used to schedule
|
||||
* rendering of the component.
|
||||
*/
|
||||
override fun getMainComponentName(): String = NavigationHelper.routerName
|
||||
|
||||
/**
|
||||
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
|
||||
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
|
||||
*/
|
||||
override fun createReactActivityDelegate(): ReactActivityDelegate =
|
||||
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
AppManager.addActivity(this)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
AppManager.removeActivity(this)
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
@ -1,22 +1,14 @@
|
||||
package com.trust.ywx
|
||||
|
||||
import com.facebook.react.ReactActivity
|
||||
import com.facebook.react.ReactActivityDelegate
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
|
||||
import com.facebook.react.defaults.DefaultReactActivityDelegate
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.trust.ywx.specs.navigation.NavigationHelper
|
||||
|
||||
class MainActivity : ReactActivity() {
|
||||
|
||||
/**
|
||||
* Returns the name of the main component registered from JavaScript. This is used to schedule
|
||||
* rendering of the component.
|
||||
*/
|
||||
override fun getMainComponentName(): String = "app"
|
||||
|
||||
/**
|
||||
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
|
||||
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
|
||||
*/
|
||||
override fun createReactActivityDelegate(): ReactActivityDelegate =
|
||||
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
|
||||
class MainActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
NavigationHelper.routerName = "app"
|
||||
startActivity(Intent(this, BuzActivity::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
package com.trust.ywx.specs
|
||||
|
||||
|
||||
import android.content.Intent
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.trust.ywx.AppManager
|
||||
import com.trust.ywx.BuzActivity
|
||||
import com.trust.ywx.specs.NativeNavigationManagerSpec
|
||||
import com.trust.ywx.specs.navigation.NavigationHelper
|
||||
|
||||
class NavigationManager(reactContext: ReactApplicationContext) :
|
||||
NativeNavigationManagerSpec(reactContext) {
|
||||
override fun navigate(name: String) {
|
||||
NavigationHelper.routerName = name
|
||||
AppManager.lastActivity()
|
||||
?.startActivity(Intent(AppManager.lastActivity(), BuzActivity::class.java))
|
||||
}
|
||||
|
||||
override fun pop(name: String?) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.trust.ywx.specs.navigation
|
||||
|
||||
object NavigationHelper {
|
||||
var routerName: String = "app"
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</LinearLayout>
|
||||
@ -14,14 +14,13 @@
|
||||
"build-android-hospital": "react-native bundle --platform android --dev false --entry-file src/hospital/hospital.ts --bundle-output ./bundle/hospital.android.bundle --assets-dest ./bundle --config metro.main.config.js --minify true --reset-cache"
|
||||
},
|
||||
"codegenConfig": {
|
||||
"name": "SpecsManager",
|
||||
"name": "SpecManager",
|
||||
"type": "modules",
|
||||
"jsSrcsDir": "./src/specs",
|
||||
"jsSrcsDir": "specs",
|
||||
"android": {
|
||||
"javaPackageName": "com.trust.ywx.specs"
|
||||
}
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"@react-native-async-storage/async-storage": "^2.2.0",
|
||||
"@react-native/new-app-screen": "0.80.1",
|
||||
|
||||
1
specs/README.md
普通文件
1
specs/README.md
普通文件
@ -0,0 +1 @@
|
||||
# 文件名必须`Native`开头
|
||||
@ -5,8 +5,14 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import { NewAppScreen } from '@react-native/new-app-screen';
|
||||
import { StatusBar, StyleSheet, useColorScheme, View } from 'react-native';
|
||||
import {
|
||||
Button,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
useColorScheme,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { pushByName } from '../common/NavigationHelper.ts';
|
||||
|
||||
function App() {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
@ -14,7 +20,13 @@ function App() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
|
||||
<NewAppScreen templateFileName="App.tsx" />
|
||||
<View style={{ height: 100 }} />
|
||||
<Button
|
||||
title={'进入互联网医院'}
|
||||
onPress={() => {
|
||||
pushByName('hospital', {});
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { storageApp } from './StorageHelper.ts';
|
||||
import NavigationManager from '../specs/SpecsManager.ts';
|
||||
import NavigationManager from '../../specs/NativeNavigationManager.ts';
|
||||
|
||||
export const pushByName = (name: string, params: any) => {
|
||||
storageApp
|
||||
.save({
|
||||
key: 'MessageActivity',
|
||||
key: `MessageActivity_${name}`,
|
||||
data: params,
|
||||
expires: 1000 * 3600,
|
||||
})
|
||||
@ -12,3 +12,8 @@ export const pushByName = (name: string, params: any) => {
|
||||
NavigationManager.navigate(name);
|
||||
});
|
||||
};
|
||||
export const pop = (name: string) => {
|
||||
storageApp.remove({ key: `MessageActivity_${name}` }).finally(() => {
|
||||
NavigationManager.pop(name);
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
import 'react';
|
||||
import 'react-native';
|
||||
import './NavigationHelper';
|
||||
|
||||
41
src/hospital/Hospital.tsx
普通文件
41
src/hospital/Hospital.tsx
普通文件
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Sample React Native App
|
||||
* https://github.com/facebook/react-native
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {
|
||||
Button,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
useColorScheme,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { pop } from '../common/NavigationHelper.ts';
|
||||
|
||||
function Hospital() {
|
||||
const isDarkMode = useColorScheme() === 'dark';
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
|
||||
<View style={{ height: 100 }} />
|
||||
<View>互联网医院</View>
|
||||
<Button
|
||||
title={'返回'}
|
||||
onPress={() => {
|
||||
pop('hospital');
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export default Hospital;
|
||||
@ -0,0 +1,4 @@
|
||||
import { AppRegistry } from 'react-native';
|
||||
import Hospital from './Hospital.tsx';
|
||||
|
||||
AppRegistry.registerComponent('hospital', () => Hospital);
|
||||
正在加载...
在新工单中引用
屏蔽一个用户