Android фрагмент, возвращаясь без воссоздания / перезагрузки фрагмента

Я видел довольно много вопросов о so о фрагментах, и я все еще не могу понять, возможно ли то, что я хочу сделать, и тем более, если мой шаблон дизайна просто поврежден, и мне нужно переработать весь процесс. В принципе, как и большинство вопросов, которые были заданы, у меня есть ActionBar с NavigationTabs( используя ActionBarSherlock), то в каждой вкладке есть FragementActivity, а затем FragmentActivities нажимают новые фрагменты при выборе строки (я пытаюсь воссоздать проект iOS в Android, и это просто базовое навигационное приложение с некоторыми вкладками, которые могут детализироваться в конкретную информацию). Когда я нажимаю кнопку "назад" на телефоне, предыдущий фрагмент загружается, но фрагмент повторно создает себя (поэтому веб-службы вызываются снова для каждого представления), и это не требуется, так как информация не изменится в предыдущем представлении при движении назад. Поэтому в основном я хочу выяснить, как настроить мои фрагменты, чтобы при нажатии кнопки " Назад телефон, предыдущий фрагмент просто подтягивается с предыдущими уже созданными элементами. Ниже приведен мой текущий код:

    //This is from my FragmentActivity Class that contains the ActionBar and Tab Selection Control
    @Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
    // TODO Auto-generated method stub
    int selectedTab = tab.getPosition();

    if (selectedTab == 0) {
        SalesMainScreen salesScreen = new SalesMainScreen();
        ft.replace(R.id.content, salesScreen);
    }
    else if (selectedTab == 1) {
        ClientMainScreen clientScreen = new ClientMainScreen();
        ft.replace(R.id.content, clientScreen);
    }.....

   //This is within the ClientMainScreen Fragment Class, which handles moving to the Detail Fragment
   row.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            //Do something if Row is clicked
                            try{
                                String selectedClientName = clientObject.getString("ClientName");
                                String selectedClientID = clientObject.getString("ClientID");
                                String selectedValue = clientObject.getString("ClientValue");
                                transaction = getFragmentManager().beginTransaction();
                                ClientDetailScreen detailScreen = new ClientDetailScreen();
                                detailScreen.clientID = selectedClientID;
                                detailScreen.clientName = selectedClientName;
                                detailScreen.clientValue = selectedValue;
                                int currentID = ((ViewGroup)getView().getParent()).getId();
                                transaction.replace(currentID,detailScreen);
                                transaction.addToBackStack(null);
                                transaction.commit();

                            }
                            catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });....

     //And then this is the Client Detail Fragment, with the method being called to Call the Web Service and create thew (since what is displayed on this screen is dependent on what is found in the Web Service
          @Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved) {
    return inflater.inflate(R.layout.clientdetailscreen, group, false);
}

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    //Setup Preferences File Link
    this.preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());

    //initialize the table object
    mainTable = (TableLayout)getActivity().findViewById(R.id.mainTable);

    //setup the detail table
    setupRelatedClientSection();

}

затем экран сведений о клиенте может детализироваться еще раз, используя тот же метод, что и главный экран клиента, но когда я возвращаюсь с этого нового экрана на экран сведений, метод seuptRelatedClientSection() вызывается снова, и поэтому весь фрагмент перестраивается, когда на самом деле я просто хочу вытащить сохраненную версию этого экрана. Это возможно с моя текущая настройка, или я подошел к этому неправильно?

4 ответов


Я считаю, что вы ищете show() и hide().

Я думаю, вы все равно можете добавить их в backstack.

 transaction.hide(currentFragment);
 transaction.show(detailScreen);
 transaction.addToBackStack(null);
 transaction.commit();

у меня не было моего кода, чтобы посмотреть, но я считаю,что это так... Попробуйте, если у кого-то другого нет лучшего способа. Я не пробовал backstack с show() hide (), но я считаю, что он принимает изменения, которые сделаны до фиксации транзакций, и отменит их, если нажата кнопка "Назад". Пожалуйста, перезвони мне. потому что мне интересно знать.

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


попробуйте использовать fragementTransaction.добавить, а не заменить


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

следующий код продемонстрирует, как открыть FragmentB из FragmentA и вернуться к FragmentA из FragmentB (без обновления FragmentA), нажав кнопку Назад.

public class FragmentA extends Fragment{

   ...

   void openFragmentB(){

       FragmentManager fragmentManager = 
           getActivity().getSupportFragmentManager();
       FragmentB fragmentB = FragmentB.newInstance();

       if (fragmentB.isAdded()) {

           return;
       } else {

           fragmentManager.
               beginTransaction().
               add(R.id.mainContainer,fragmentB).
               addToBackStack(FragmentB.TAG).
               commit();
      }
   }
}

public class FragmentB extends Fragment{

    public static final String TAG = 
        FragmentB.class.getSimpleName();

    ...

    public static FragmentB newInstance(){

        FragmentB fragmentB = new FragmentB();
        return fragmentB;
    }

    @Override
    public void onResume() {

        super.onResume();
        // add this piece of code in onResume method
        this.getView().setFocusableInTouchMode(true);
        this.getView().requestFocus();
    }
}

в вашем MainActivity переопределить onBackPressed ()

class MainActivity extends Activity{
    ...

    @Override
    public void onBackPressed() {

        if (getFragmentManager().getBackStackEntryCount() > 0) {

            getFragmentManager().popBackStack();
        } else {

            super.onBackPressed();
        }
    } 
}

вы правы, был ряд предыдущих вопросов / документации по этой теме;)

документация по фрагментам, в частности раздел о транзакциях и состоянии сохранения, поможет вам найти ответ.

http://developer.android.com/guide/components/fragments.html#Transactions

http://developer.android.com/guide/components/activities.html#SavingActivityState

Android-фрагмент onActivityResult избегайте перезагрузки

фрагменты могут иметь поддержку onSaveInstanceState а не onRestoreInstanceState, поэтому, если вы хотите сохранить ссылку на представления таблицы, сохраните их в Bundle и вы можете получить доступ к сохраненной посмотреть в вашем onActivityCreated метод. Вы также можете использовать Fragments back stack.

данное руководство имеет очень подробные инструкции / примеры на заднем стеке и сохранение состояния фрагмента.

удачи