Подтвердить что ты не робот

Ядро Android Fragment State

В настоящее время я использую навигационный ящик для Android-приложения Android. В моем первом фрагменте у меня есть фрагмент, который загружает данные, используя API-интерфейс Facebook Graph. Таким образом, когда приложение впервые загружается, оно сначала переходит к первому фрагменту.

First

Затем я использую навигационный ящик, чтобы щелкнуть другой фрагмент и просмотреть его.

Second Fragment

И наконец, я снова использую навигационный ящик, чтобы вернуться к первому фрагменту и просмотреть его.

First Fragment

Моей проблемой, с которой я столкнулся, является то, как я могу использовать фрагмент, который был создан один раз, вместо повторного его создания всякий раз, когда выбран пункт "Ящик навигации". Мой код для переключения фрагментов приведен ниже.

private void displayView(int position) {
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
    case 0:
        fragment = new SelectionFragment();
        break;
    case 1:
        fragment = new HomeFragment();
        break;
    case 2:
        fragment = new PhotosFragment();
        break;
    case 3:
        fragment = new CommunityFragment();
        break;
    case 4:
        fragment = new PagesFragment();
        break;
    case 5:
        fragment = new SplashFragment();
        break;
    default:
        break;
    }

    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }
}

Я заметил, что действительно есть "новый" экземпляр фрагмента каждый раз, когда выбран параметр. Как я могу реализовать логику создания экземпляра фрагмента ONCE и повторно использовать его, так что мне не нужно постоянно загружать фрагмент снова и снова.

4b9b3361

Ответ 1

Для всех, кто сталкивается с той же проблемой со мной, мне удалось найти решение.

В кадре контейнера я должен определить конкретные виды фрагментов, которые я буду использовать, как показано ниже.

Specific fragments

В каждом представлении фрагмента я должен "связать" его с фактическим фрагментом, как показано ниже, с помощью атрибута "android: name. Обратите внимание на путь для фрагмента, например, в моем случае это com.example.confesssionsrp.SelectionFragment.

<fragment
    android:id="@+id/selectionFragment"
    android:name="com.example.confessionsrp.SelectionFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

В MainActivity (или Activity, где мы просматриваем фрагменты) создаем переменные для каждого из фрагментов, как показано ниже.

Variables

После этого в Oncreate главной операции (или вашего конкретного действия) инициализируйте различные фрагменты, как показано ниже.

OnCreate

Перейдите к созданию нового метода под названием " ShowFragment", как показано ниже.

private void showFragment(int fragmentIndex, boolean addToBackStack) {
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    for (int i = 0; i < fragments.length; i++) {
        if (i == fragmentIndex) {
            transaction.show(fragments[i]);
            if (Session.getActiveSession().isClosed()) {
                mDrawerLayout
                        .setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            }
        } else {
            transaction.hide(fragments[i]);
        }
    }
    if (addToBackStack) {
        transaction.addToBackStack(null);
    }
    transaction.commit();
}

С этого момента при переключении фрагментов вручную вызовите метод ShowFragment с выбранным фрагментом, как показано ниже.

Show Fragment

Выполняя все это в целом, не будет reset Фрагмент каждый раз, когда мы его рассматриваем, и, следовательно, является решением ответа. Спасибо всем, кто мне помог до сих пор:)!

Ответ 2

Я использую следующий код:

@Override
public void onNavigationDrawerItemSelected(int position) {

    // update the main content by replacing fragments
    FragmentManager fragmentManager = getFragmentManager();
    if(position==0){// selection of tabs content
        fragmentManager
        .beginTransaction()
        .replace(R.id.container,
                SimulatorFragment.newInstance(position + 1)).commit();
    }else if(position==1){
        fragmentManager
        .beginTransaction()
        .replace(R.id.container,
                HudFragment.newInstance(position + 1)).commit();
    }else if(position==2){
        // Display the fragment as the main content.
        fragmentManager
        .beginTransaction()
        .replace(R.id.container, 
                SettingsBasicFragment.newInstance(position +1)).commit();
    }else{

    }
}

Вы можете заменить новый экземпляр в первый раз и сохранить фрагмент, если он не является нулевым, а затем заменить на сохраненный фрагмент.

В этой операции необходимо реализовать NavigationDrawerFragment.NavigationDrawerCallbacks

Конструктор фрагмента и методы newInstance выглядят следующим образом:

public final class HudFragment extends Fragment {
/**
 * The fragment argument representing the section number for this
 * fragment.
 */
private static final String ARG_SECTION_NUMBER = "section_number";

/**
 * Returns a new instance of this fragment for the given section number.
 * @param simulation 
 */
public static HudFragment newInstance(int sectionNumber) {  
    HudFragment fragment = new HudFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}

public HudFragment() {
}

Для переключения фрагментов по коду я использую этот метод внутри параметра NavigationDrawerFragment:

/**
 * Select a different section
 * @param position
 */
public void select(int position){
    selectItem(position);
}

private void selectItem(int position) {
    mCurrentSelectedPosition = position;
    if (mDrawerListView != null) {
        mDrawerListView.setItemChecked(position, true);
    }            
    if (mDrawerLayout != null) {
        mDrawerLayout.closeDrawer(mFragmentContainerView);
    }
    if (mCallbacks != null) {
        mCallbacks.onNavigationDrawerItemSelected(position);
    }
}

Ответ 3

Второй вариант - начать с примера navigationDrawer, предлагаемого Android SDK. Я выбрал этот шаблон активности при создании проекта, и почти весь код моего предыдущего ответа создается автоматически.

Если вы хотите сохранить фрагменты после вращения устройства или подражания, это другое дело, вам нужно сохранить фрагменты. Если нет, вам просто нужно сохранить новый экземпляр фрагмента в переменной и проверить, является ли оно нулевым, чтобы создать новый или использовать старый.

Ответ 4

В случае, если кому-то нужен другой подход к этому: вы можете найти фрагмент в стеке:

// check if this fragment is on the backstack to avoid creating a new one
    Fragment foundFragment =  fragmentManager.findFragmentByTag("unique_fragment_tag");
    if (foundFragment != null) {
          fragmentManager.popBackStackImmediate("unique_fragment_tag", 0);
            return;
    }