Exposing Fragment in React Native Android ViewManager

六月ゝ 毕业季﹏ 提交于 2019-12-03 12:36:45

问题


I am attempting to wrap the YouTube Android API as a UI Component for React Native. I have been successful in the Android configuration of things (getting onInitializationSuccess), however I am unable to figure out how get the YouTubePlayerView back to my React Native app.

According to the docs, they recommend using YouTubePlayerFragment if you can not extend YouTubeBaseActivity. Since React Native on Android does not use XML based layouts I attempted to create the views programmatically. However, when I return the wrapping View ( I tried as a FrameLayout, but not sure if that was the right choice) I created it does not render anything on the application.

I am looking to keep it extremely simple for now, here are the necessary bits of code:

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>
    );
  }
}

Any help would be really appreciated, thank you!


回答1:


I don't have actual solution for the YouTube fragment, but I used some workaround for displaying an YouTube view in RN.

(Maybe you can try the hack in 3. on your fragment first.)

  1. Make your own ReactActivity that extends YouTubeBaseActivity and let MainActivity extends it.

    public abstract class ReactActivity extends YouTubeBaseActivity implements DefaultHardwareBackBtnHandler {
      // copy & paste RN's ReactActivity.java source
    
  2. Make YoutubeManager class for the YouTubePlayerView.

    It should takes an Activity instance from createViewManagers when you implements ReactPackage.

    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;
      }
    

    and make a js module for it.

    module.exports = requireNativeComponent('RCTYoutube', iface);
    
  3. Now You can display an YouTube view, but it seems like empty view. You need some hack for it.

    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);
    }
    

You can see how it works actually from my app.

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



来源:https://stackoverflow.com/questions/36226702/exposing-fragment-in-react-native-android-viewmanager

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!