![](/img/trans.png)
[英]requireNativeComponent: "RNSScreenStackHeaderConfig" was not found in the UIManager
[英]requireNativeComponent was not found in UIManager
我知道這個問題已經被問過很多次了,但是所有的問題都是指在react-native
應用程序中集成第三方依賴項,但就我而言,這是因為我自己的本機代碼,我在如何修復它時遇到了問題。 我正在使用react-native
0.69
這是我的代碼片段
CealScanQrView.kt
class CealScanQrView(context: Context): FrameLayout(context) {
...
//Contains all the logic of integrating camerax, check below code repo to see the full source code
...
}
CealScanQrFragment.kt
class CealScanQrFragment: Fragment() {
private lateinit var cealScanQrView: CealScanQrView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
super.onCreateView(inflater, container, savedInstanceState)
cealScanQrView = CealScanQrView(requireNotNull(context))
return cealScanQrView // this CustomView could be any view that you want to render
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// do any logic that should happen in an `onCreate` method, e.g:
cealScanQrView.setUpCamera(requireActivity())
}
override fun onDestroy() {
super.onDestroy()
cealScanQrView.destroyCamera()
}
}
CealScanQrViewManager.kt
class CealScanQrViewManager(
private val reactContext: ReactApplicationContext
) : ViewGroupManager<FrameLayout>() {
private val cealScanQrView = "CealScanQrView"
private val topChange = "topChange"
private val phasedRegistrationNames = "phasedRegistrationNames"
private val bubbled = "bubbled"
private val onChange = "onChange"
private val create = "create"
companion object {
private const val COMMAND_CREATE = 1
}
private var propWidth: Int? = null
private var propHeight: Int? = null
override fun getName() = cealScanQrView
override fun createViewInstance(reactContext: ThemedReactContext) = FrameLayout(reactContext)
override fun getCommandsMap() = mapOf("create" to COMMAND_CREATE)
override fun receiveCommand(root: FrameLayout, commandId: String?, args: ReadableArray?) {
super.receiveCommand(root, commandId, args)
val reactNativeViewId = requireNotNull(args).getInt(0)
when (commandId?.toInt()) {
COMMAND_CREATE -> createFragment(root, reactNativeViewId)
}
}
private fun createFragment(root: FrameLayout, reactNativeViewId: Int) {
val parentView = root.findViewById<ViewGroup>(reactNativeViewId)
setupLayout(parentView)
val myFragment = CealScanQrFragment()
val activity = reactContext.currentActivity as FragmentActivity
activity.supportFragmentManager
.beginTransaction()
.replace(reactNativeViewId, myFragment, reactNativeViewId.toString())
.commit()
}
private fun setupLayout(view: View) {
Choreographer.getInstance().postFrameCallback(object: Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
manuallyLayoutChildren(view)
view.viewTreeObserver.dispatchOnGlobalLayout()
Choreographer.getInstance().postFrameCallback(this)
}
})
}
@ReactPropGroup(names = ["width", "height"], customType = "Style")
fun setStyle(view: FrameLayout, index: Int, value: Int) {
if (index == 0) propWidth = value
if (index == 1) propHeight = value
}
private fun manuallyLayoutChildren(view: View) {
// propWidth and propHeight coming from react-native props
val width = requireNotNull(propWidth)
val height = requireNotNull(propHeight)
view.measure(
View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY))
view.layout(0, 0, width, height)
}
override fun getExportedCustomBubblingEventTypeConstants(): Map<String, Any> {
return mapOf(
topChange to mapOf(
phasedRegistrationNames to mapOf(
bubbled to onChange
)
)
)
}
}
在JS
方面
我創建了一個CealScanQrViewManager.tsx
文件
import {requireNativeComponent} from 'react-native';
export const CealScanQrViewManager = requireNativeComponent(
'CealScanQrViewManager',
);
在 App.tsx 中
const createFragment = (viewId: number | null) =>
UIManager.dispatchViewManagerCommand(
viewId,
// we are calling the 'create' command
UIManager.CealScanQrViewManager.Commands.create.toString(),
[viewId],
);
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const [isCameraPermissionGranted, setIsCameraPermissionGranted] =
useState(false);
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const ref = useRef(null);
useEffect(() => {
requestCameraPermission();
}, []);
useEffect(() => {
if (isCameraPermissionGranted) {
const viewId = findNodeHandle(ref.current);
createFragment(viewId);
}
}, [isCameraPermissionGranted]);
const requestCameraPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Cool Photo App Camera Permission',
message:
'Cool Photo App needs access to your camera ' +
'so you can take awesome pictures.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
setIsCameraPermissionGranted(true);
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
};
const readQr = async (data: any) => {
console.log(data.nativeEvent.qrCode);
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
{isCameraPermissionGranted ? (
<CealScanQrViewManager
style={{
// converts dpi to px, provide desired height
height: PixelRatio.getPixelSizeForLayoutSize(200),
// converts dpi to px, provide desired width
width: PixelRatio.getPixelSizeForLayoutSize(200),
}}
ref={ref}
onChange={readQr}
/>
) : (
<View style={{flex: 1, backgroundColor: 'red'}} />
)}
</SafeAreaView>
);
};
一旦我授予相機權限,我就會收到錯誤消息
requireNativeComponent CealScanQrViewManager was not found in UIManager
有點刺眼的答案,但我認為一個正確的答案:本機組件的官方指南讓您注冊一個視圖管理器,這是一個 class 覆蓋getName
以返回固定字符串,然后傳遞相同的字符串到requireNativeComponent
。
在您鏈接的存儲庫中,這些名稱不匹配。 您requireNativeComponent('CealScanQrViewManager')
,但將其注冊為"CealScanQrView"
。 正如官方指南解釋的那樣,
getName
返回的名稱用於引用來自 JavaScript 的原生視圖類型。
如果名稱不匹配,難怪查找類型失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.