android - React Native 真的支持 Android Fragment 吗?

标签 android react-native

这个问题比看起来更难回答。

我的印象是 React Native 主要专注于控制布局的整个 Activity 的 Root View 。我认为在处理 fragment 时要小心谨慎。作为旁注,React 本身(不是 React Native)似乎有自己的 fragment 概念。我猜测 React Native 中的 Yoga 布局管理器也很灵活,因为它不想处理 Android fragment 。对于新应用来说不是问题,但对于将 React Native 集成到现有应用中,这是真正的问题!

最佳答案

我不知道,也许您已经找到了解决方案,但它可能对其他人有所帮助。您提供的解决方案是,当您使用原生 android FragmentActivityAppCompatActivity 时,触摸事件确实存在一些问题。但是 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;
    }
}

结果:

enter image description here ,

enter image description here ,

enter image description here ,

enter image description here

关于android - React Native 真的支持 Android Fragment 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43796433/

相关文章:

android - 如果在 Play 商店取消应用购买,用户评分会被删除吗

android - 如何使用TextView数组

android - 为什么我的系统覆盖会捕获所有触摸(无法与底层 View 进行交互)

react-native - 使用 redux 的选项卡导航器性能问题

使用 Expo 和 Firebase 的 iOS 应用奖励推荐

c# - 将ByteArray转换为png图像并将其添加到Xamarin.Android中的ImageView

android - 显示 Facebook 的所有事件

java - 无法从 Maven 存储库中找到 play-services-maps.jar - React Native

ios - 通过 iPhone IOS 测试 React Native

javascript - 每次调用dataSuccess函数