React Native是否真的支持Android片段?

时间:2017-05-05 04:17:31

标签: android react-native

这个问题比看上去难以回答。

我的印象是React Native主要专注于控制布局的整个活动的根视图。我认为在拍摄片段时会有一些谨慎使用。作为旁注,React本身(不是React Native)似乎有自己的片段概念。我甚至猜测React Native灵活的瑜伽布局管理器,因为它不想处理Android碎片。新应用程序不是一个问题,但是将React Native集成到现有应用程序中这是真正的问题!

如果你不知道但是很想知道但是想知道请投票给这个问题!

2 个答案:

答案 0 :(得分:1)

2021 年初: 我还创建了关于它的博客文章:https://stefanmajiros.medium.com/integration-of-native-android-fragments-and-views-into-react-native-a4156621543b

通常,您只需在 React Native 中渲染占位符(作为原生 UI 组件),然后您需要在 React Native 中找到该占位符的 id,将 id 发送到本机部分,然后执行将片段附加到的命令视图,类似于:

getSupportFragmentManager()
.beginTransaction()
.add(placeholderId, yourfragment, "sometag")
.commit();

答案 1 :(得分:0)

我不知道,也许你已经找到了解决方案,但它对其他人有帮助。当您使用原生android AppCompatActivityReactFragmentActivity时,您提供的解决方案确实存在触摸事件的一些问题。但react-native有自己的Fragment reactFragment = new MainReactFragment(); getSupportFragmentManager().beginTransaction().replace(R.id.fragment, reactFragment, "reactFragment").commit(); ,如果你的活动扩展了这个活动,那么触摸事件效果很好,但只能在分离的片段中。它不适用于ViewPager和其他人。仅当片段在分离的Activity中使用时,如下所示:

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

修改

经过一些试验和错误,我得到了正确的ViewPager和TabLayout工作(但我认为在其他情况下它也可以正常工作)。所以,这就是我所做的。 ReactFragment看起来像这样:

public class MainReactFragment extends ReactFragment {

    @Override
    public String getMainComponentName() {
        return "reactProject";
    }
}

然后实现我们的片段:

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

我们需要从ReactFragmentActivity扩展我们的活动并初始化ReactInstanceManager:

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

当然,TabAdapter:

{{1}}

<强>结果:

enter image description here

enter image description here

enter image description here

enter image description here

希望,这会对某人有所帮助。