这个问题比看起来更难回答。
ReactFragmentActivity 确实存在于 React Native 的 master 分支中,但是
创建 React Fragment 存在一个 Unresolved 问题,请参阅 https://github.com/facebook/react-native/pull/12199/commits/e5b68717f57c41f5f1e77c289bdb4f673bb242f1 //这还没有被批准,但是需要被确认。
我在 github 等上查看了数十个 React Native 示例,但从未显示 fragment 。请证明我错了!
这显然不是不可能看到:React-native inside a Fragment但是这个解决方案似乎不能完全处理触摸事件。
我的印象是 React Native 主要专注于控制布局的整个 Activity 的 Root View 。我认为在处理 fragment 时要小心谨慎。作为旁注,React 本身(不是 React Native)似乎有自己的 fragment 概念。我猜测 React Native 中的 Yoga 布局管理器也很灵活,因为它不想处理 Android fragment 。对于新应用来说不是问题,但对于将 React Native 集成到现有应用中,这是真正的问题!
最佳答案
我不知道,也许您已经找到了解决方案,但它可能对其他人有所帮助。您提供的解决方案是,当您使用原生 android FragmentActivity
或 AppCompatActivity
时,触摸事件确实存在一些问题。但是 react-native 有自己的 ReactFragmentActivity
并且如果您的 Activity 扩展了此 Activity ,则触摸事件可以正常工作,但只能在单独的 fragment 中。它不适用于 ViewPager 和其他人。只有fragment在单独的Activity中使用,像这样:
Fragment reactFragment = new MainReactFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment, reactFragment, "reactFragment").commit();
编辑:
经过一些试验和错误,我得到它来纠正 ViewPager 和 TabLayout 的工作(但我认为在其他情况下它也可以工作)。所以,这就是我所做的。 ReactFragment 看起来像这样:
public abstract class ReactFragment extends Fragment {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
// This method returns the name of our top-level component to show
public abstract String getMainComponentName();
@Override
public void onAttach(Context context) {
super.onAttach(context);
mReactRootView = new ReactRootView(context);
}
public void setmReactInstanceManager(ReactInstanceManager mReactInstanceManager){
this.mReactInstanceManager = mReactInstanceManager;
}
@Override
public ReactRootView onCreateView(LayoutInflater inflater, ViewGroup group, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return mReactRootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mReactRootView.startReactApplication(
mReactInstanceManager,
getMainComponentName(),
null
);
}
}
然后实现我们的 fragment :
public class MainReactFragment extends ReactFragment {
@Override
public String getMainComponentName() {
return "reactProject";
}
}
我们需要从 ReactFragmentActivity 扩展我们的 Activity 并初始化 ReactInstanceManager:
public class MainActivity extends ReactFragmentActivity {
TabLayout tabs;
ViewPager viewPager;
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
tabs = (TabLayout) findViewById(R.id.menuItemTabs);
viewPager = (ViewPager) findViewById(R.id.tabMainMenu);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
TabsAdapter adapter = new TabsAdapter(getSupportFragmentManager(), mReactInstanceManager);
viewPager.setAdapter(adapter);
tabs.setupWithViewPager(viewPager);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
public void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(this);
}
}
@Override
public void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
}
else {
super.onBackPressed();
}
}
}
当然还有 TabAdapter:
public class TabsAdapter extends FragmentStatePagerAdapter {
ReactInstanceManager mReactInstanceManager;
public TabsAdapter(FragmentManager fragmentManager, `enter code here`ReactInstanceManager reactInstanceManager){
super(fragmentManager);
mReactInstanceManager = reactInstanceManager;
}
@Override
public Fragment getItem(int position) {
MainReactFragment reactFragment = new MainReactFragment();
reactFragment.setmReactInstanceManager(mReactInstanceManager);
return reactFragment;
}
@Override
public int getCount() {
return 2;
}
@Override
public int getItemPosition(Object item) {
return POSITION_NONE;
}
@Override
public CharSequence getPageTitle(int position) {
return "react tab " + position;
}
@Override
public Parcelable saveState() {
return null;
}
}
结果:
关于android - React Native 真的支持 Android Fragment 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43796433/