Действительно ли React Native действительно поддерживает Android-фрагменты?

Этот вопрос сложнее ответить, чем кажется.

  • ReactFragmentActivity существует в основной ветке React Native, НО

  • Существует открытая проблема для создания фрагмента React, см. https://github.com/facebook/react-native/pull/12199/commits/e5b68717f57c41f5f1e77c289bdb4f673bb242f1 // Это еще не одобрено, но необходимость была подтверждена.

  • Я просмотрел десятки примеров React Native на github и т.д., и фрагменты никогда не показываются. Докажи, пожалуйста, неправильно!

  • По-видимому, невозможно увидеть: React-native внутри фрагмента, но это решение, похоже, не полностью касается событий касания.

Мое впечатление, что React Native в первую очередь сосредоточен на управлении корневым представлением всей активности для макетов. Я думаю, что есть некоторая осторожность в использовании фрагментов. Как побочная заметка "Реагировать" (а не "Реагировать нативный" ), похоже, имеет свою собственную концепцию фрагмента. Я предполагаю, что даже менеджер макетов йоги внутри React Native гибкий, поскольку он не хочет иметь дело с Android Fragments. Это не проблема для новых приложений, а для интеграции React Native в существующие приложения, это настоящая проблема!

И ДА, ребята, если вы НЕ знаете, но ХОТИТЕ знать ПОЖАЛУЙСТА голосуйте за вопрос!

Ответ 1

Я не знаю, возможно, вы уже нашли решение, но оно может быть полезно для кого-то другого. Решение, которое вы предоставили, действительно имеет некоторые проблемы с событиями касания, когда вы используете собственный андроид FragmentActivity или AppCompatActivity. Но native-native имеет собственный ReactFragmentActivity, и если ваша активность расширяет эту активность, события касания работают хорошо, но только в отдельном фрагменте. Он не работает с ViewPager и другими. Только если фрагмент используется в отдельной операции, например:

Fragment reactFragment = new MainReactFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment, reactFragment, "reactFragment").commit();

EDIT:

После некоторых проб и ошибок, я получил его, чтобы исправить работу с 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
        );
    }
}

Затем реализуем наш фрагмент:

public class MainReactFragment extends ReactFragment {

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

Нам нужно расширить нашу активность из ReactFragmentActivity и инициализировать 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;
    }
}

РЕЗУЛЬТАТ:

введите описание изображения здесь,

введите описание изображения здесь,

введите описание изображения здесь,

введите описание изображения здесь

Надеюсь, это поможет кому-то.