【问题标题】:Exposing Fragment in React Native Android ViewManager在 React Native Android ViewManager 中暴露 Fragment
【发布时间】:2016-03-25 19:32:56
【问题描述】:

我正在尝试将 YouTube Android API 包装为 React Native 的 UI 组件。我在 Android 配置方面取得了成功(获得 onInitializationSuccess),但是我无法弄清楚如何让 YouTubePlayerView 回到我的 React Native 应用程序。

根据文档,如果您无法扩展 YouTubeBaseActivity,他们建议使用 YouTubePlayerFragment。由于 Android 上的 React Native 不使用基于 XML 的布局,因此我尝试以编程方式创建视图。但是,当我返回包装视图(我尝试作为 FrameLayout,但不确定这是否是正确的选择)时,我创建它不会在应用程序上呈现任何内容。

我现在希望让它变得非常简单,这里是一些必要的代码:

YouTubeManager.java

public class YouTubeManager extends SimpleViewManager<FrameLayout>  implements YouTubePlayer.OnInitializedListener {
// ...
@Override
    protected FrameLayout createViewInstance(ThemedReactContext reactContext) {
        this.reactContext = reactContext;

        FrameLayout view = new FrameLayout(reactContext);
        view.setId(View.generateViewId());


        FragmentManager fragmentManager = activity.getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        YouTubePlayerFragment fragment = new YouTubePlayerFragment();
        fragmentTransaction.add(view.getId(), fragment);

        fragmentTransaction.commit();

        fragment.initialize("SECRET_KEY", this);

        return view;
    }
// ... 
}

YouTube.js

class YouTube extends Component {
    render () {
        return <YouTubeAndroid {...this.props}/>;
    }
};

var iface = {
    name : 'YouTube',
    propTypes : {
        ...View.propTypes
    },
};


var YouTubeAndroid = requireNativeComponent('YouTube', iface);

module.exports = YouTube;

index.android.js

var YouTube = require('./YouTube');

class YouTubePlayer extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>hello</Text>
        <YouTube />
      </View>
    );
  }
}

任何帮助将不胜感激,谢谢!

【问题讨论】:

  • 在 youtube 组件上设置显式高度和宽度有帮助吗?
  • @agent_hunt 是的,我尝试给它一个固定的高度/宽度和背景颜色。它只是渲染一个空视图dropbox.com/s/3obfjs6agcux3z2/…
  • 问题解决了吗?你成功渲染了 Fragment 了吗?
  • @ischmierer 是的,使用 Deminoth 的建议。不过,这需要扩展 ReactActivity,而且有点麻烦。这个方法最近坏了(在 0.32-rc 中修复,虽然 getCurrentActivity() 可以被 SimpleViewManager 使用)。

标签: android react-native android-youtube-api


【解决方案1】:

我没有针对 YouTube 片段的实际解决方案,但我使用了一些解决方法来在 RN 中显示 YouTube 视图。

(也许您可以先在片段上尝试3. 中的hack。)

  1. 创建自己的 ReactActivity 扩展 YouTubeBaseActivity 并让 MainActivity 扩展它。

    public abstract class ReactActivity extends YouTubeBaseActivity implements DefaultHardwareBackBtnHandler {
      // copy & paste RN's ReactActivity.java source
    
  2. YouTubePlayerView 制作YoutubeManager 类。

    当您实现ReactPackage 时,它应该从createViewManagers 获取一个Activity 实例。

    public class YoutubeManager extends SimpleViewManager<YouTubePlayerView> implements YouTubePlayer.OnInitializedListener, YouTubePlayer.PlayerStateChangeListener,  YouTubePlayer.PlaybackEventListener {
    
      public static final String REACT_CLASS = "RCTYoutube";
      private static final String YOUTUBE_API_KEY = "<YOUR_OWN_KEY>";
    
      private YouTubeBaseActivity mActivity = null;
      private YouTubePlayerView mYouTubePlayerView = null;
    
      public YoutubeManager(Activity activity) {
        super();
        mActivity = (YouTubeBaseActivity) activity;
      }
    
      @Override
      public String getName() {
        return REACT_CLASS;
      }
    
      @Override
      public YouTubePlayerView createViewInstance(ThemedReactContext context) {
        mContext = context;
    
        mYouTubePlayerView = new YouTubePlayerView(mActivity);
        mYouTubePlayerView.initialize(YOUTUBE_API_KEY, this);
    
        return mYouTubePlayerView;
      }
    

    并为它制作一个js模块。

    module.exports = requireNativeComponent('RCTYoutube', iface);
    
  3. 现在您可以显示 YouTube 视图,但它似乎是空视图。你需要一些技巧。

    componentDidMount() {
      this.setState({
        width: this.props.style.width,
        height: this.props.style.height - 1
      })
      this.timer = setInterval(()=>{
        this.setState({
          width: this.props.style.width,
          height: this.props.style.height + Math.floor(Math.random() * 2)
        })
      }, 500)
    }
    
    render() {
      return (<YoutubeView style={[style, { width: this.state.width, height: this.state.height }]} />)
    }
    
    componentWillUnmount() {
      if(this.timer) clearTimeout(this.timer);
    }
    

您可以从我的应用程序中看到它的实际工作原理。

https://play.google.com/store/apps/details?id=kr.dobbit.sharehows

【讨论】:

  • 知道为什么您需要延迟(或与此相关的时间间隔)才能显示出来吗?
猜你喜欢
  • 2021-12-14
  • 2018-09-17
  • 2015-07-26
  • 1970-01-01
  • 2016-11-11
  • 2017-10-03
  • 1970-01-01
  • 1970-01-01
  • 2018-06-19
相关资源
最近更新 更多