我正在尝试创建一个 React Native Windows 应用程序,该应用程序使用当前未由 React Native Windows 库包装的本机 Windows 组件。特别是媒体播放器元素。
我是 Windows UWP 编程和 React Native 的新手。
我按照官方文档并使用 React Native DateTimePicker项目作为参考,为 MediaPlayerElement 创建了一个 ViewManager。
代码正在编译,我可以调试以查看它正在执行,但是当 RN Windows 应用程序打开时,我看不到我的媒体播放器元素,或者在 VS Live View Tree 或 React Native 树视图工具中。
我已经使用 .idl 文件包装了 MediaPlayerElement,它由我的 MediaPlayerViewManager 调用,它将视图暴露给 React Native。
我的代码片段如下:
MediaPlayerView.idl
namespace MediaPlayer {
[default_interface]
runtimeclass MediaPlayerView : Windows.UI.Xaml.Controls.MediaPlayerElement {
MediaPlayerView(Microsoft.ReactNative.IReactContext context);
void UpdateProperties(Microsoft.ReactNative.IJSValueReader reader);
};
}
媒体播放器视图.h
#include "NativeModules.h"
#include "Generated Files/MediaPlayer.MediaPlayerView.g.h"
namespace winrt::MediaPlayer::implementation {
namespace xaml = winrt::Windows::UI::Xaml;
class MediaPlayerView : public MediaPlayerViewT<MediaPlayerView> {
public:
MediaPlayerView(Microsoft::ReactNative::IReactContext const& reactContext);
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const& reader);
private:
Microsoft::ReactNative::IReactContext m_reactContext{ nullptr };
bool m_updating{ false };
void RegisterEvents();
};
}
namespace winrt::MediaPlayer::factory_implementation {
struct MediaPlayerView : MediaPlayerViewT<MediaPlayerView, implementation::MediaPlayerView> {};
}
媒体播放器视图.cpp
#include "pch.h"
#include "JSValueXaml.h"
#include "MediaPlayerView.h"
#include "Generated Files/MediaPlayer.MediaPlayerView.g.cpp"
namespace winrt {
using namespace Microsoft::ReactNative;
using namespace Windows::Foundation;
}
namespace winrt::MediaPlayer::implementation {
MediaPlayerView::MediaPlayerView(winrt::IReactContext const& reactContext) :
m_reactContext(reactContext) {
RegisterEvents();
}
void MediaPlayerView::RegisterEvents() {
// TODO:Register events.
}
void MediaPlayerView::UpdateProperties(winrt::IJSValueReader const& reader) {
m_updating = true;
// TODO:Update properties.
m_updating = false;
return;
}
}
MediaPlayerViewManager.h
#pragma once
#include "winrt/Microsoft.ReactNative.h"
#include "NativeModules.h"
namespace winrt::MediaPlayer::implementation {
class MediaPlayerViewManager : public winrt::implements<
MediaPlayerViewManager,
winrt::Microsoft::ReactNative::IViewManager,
winrt::Microsoft::ReactNative::IViewManagerWithReactContext,
winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties,
winrt::Microsoft::ReactNative::IViewManagerWithExportedEventTypeConstants> {
public:
MediaPlayerViewManager();
// IViewManager
winrt::hstring Name() noexcept;
winrt::Windows::UI::Xaml::FrameworkElement CreateView() noexcept;
// IViewManagerWithReactContext
winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept;
void ReactContext(winrt::Microsoft::ReactNative::IReactContext reactContext) noexcept;
// IViewManagerWithNativeProperties
winrt::Windows::Foundation::Collections::
IMapView<winrt::hstring, winrt::Microsoft::ReactNative::ViewManagerPropertyType>
NativeProps() noexcept;
void UpdateProperties(
winrt::Windows::UI::Xaml::FrameworkElement const& view,
winrt::Microsoft::ReactNative::IJSValueReader const& propertyMapReader) noexcept;
// IViewManagerWithExportedEventTypeConstants
winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomBubblingEventTypeConstants() noexcept;
winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomDirectEventTypeConstants() noexcept;
private:
winrt::Microsoft::ReactNative::IReactContext m_reactContext{ nullptr };
};
}
MediaPlayerViewManager.cpp
#include "pch.h"
#include "MediaPlayerViewManager.h"
#include "NativeModules.h"
#include "MediaPlayerView.h"
namespace winrt {
using namespace Microsoft::ReactNative;
using namespace Windows::Foundation::Collections;
namespace xaml = winrt::Windows::UI::Xaml;
}
namespace winrt::MediaPlayer::implementation {
MediaPlayerViewManager::MediaPlayerViewManager() {}
//IViewManager
winrt::hstring MediaPlayerViewManager::Name() noexcept {
return L"MediaPlayerView";
}
xaml::FrameworkElement MediaPlayerViewManager::CreateView() noexcept {
return winrt::MediaPlayer::MediaPlayerView(m_reactContext);
}
// IViewManagerWithReactContext
winrt::IReactContext MediaPlayerViewManager::ReactContext() noexcept {
return m_reactContext;
}
void MediaPlayerViewManager::ReactContext(IReactContext reactContext) noexcept {
m_reactContext = reactContext;
}
// IViewManagerWithNativeProperties
IMapView<hstring, ViewManagerPropertyType> MediaPlayerViewManager::NativeProps() noexcept {
auto nativeProps = winrt::single_threaded_map<hstring, ViewManagerPropertyType>();
// Insert native props here:
return nativeProps.GetView();
}
void MediaPlayerViewManager::UpdateProperties(xaml::FrameworkElement const& view,
IJSValueReader const& propertyMapReader) noexcept {
if (auto mediaPlayerView = view.try_as<MediaPlayerView>()) {
mediaPlayerView->UpdateProperties(propertyMapReader);
} else {
OutputDebugStringW(L"Type deduction for MediaPlayerView failed.");
}
}
// IViewManagerWithExportedEventTypeConstants
ConstantProviderDelegate MediaPlayerViewManager::ExportedCustomBubblingEventTypeConstants() noexcept {
return nullptr;
}
ConstantProviderDelegate MediaPlayerViewManager::ExportedCustomDirectEventTypeConstants() noexcept {
return nullptr;
}
}
ReactPackageProvider.cpp
#include "pch.h"
#include "ReactPackageProvider.h"
#include "NativeModules.h"
using namespace winrt::Microsoft::ReactNative;
// NOTE: You must include the headers of your native modules here in
// order for the AddAttributedModules call below to find them.
#include "MediaPlayerViewManager.h"
namespace winrt::MediaPlayerProject::implementation
{
void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept
{
AddAttributedModules(packageBuilder);
packageBuilder.AddViewManager(L"MediaPlayerViewManager", []() { return winrt::make<winrt::MediaPlayer::implementation::MediaPlayerViewManager>(); });
}
} // namespace winrt::MediaPlayerProject::implementation
MediaPlayerView.js
import React from 'react';
import { StyleSheet, View} from 'react-native';
import { requireNativeComponent } from 'react-native';
const MediaPlayerWindows = requireNativeComponent("MediaPlayerView")
const MediaPlayerView = () => {
return(
<View style={styles.container}>
<MediaPlayerWindows/>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex:1,
justifyContent:'center',
alignItems:'center',
}
})
export default MediaPlayerView
应用程序.tsx
import React from 'react';
import {
SafeAreaView,
StyleSheet,
} from 'react-native';
import MediaPlayerView from './components/MediaPlayerView';
const App = () => {
return (
<SafeAreaView style={styles.App}>
<MediaPlayerView/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
App: {
flexDirection:"column",
flex:1,
alignItems: 'center',
justifyContent:'center',
}
});
export default App;
看不到 React Native Windows 的任何输出,我做错了什么?
谢谢你读到这里。这是我的第一个 Stack Overflow 问题,我希望我没有给出太多的处理。