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

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

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

    //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() снова вызван, и так весь фрагмент перестраивается, когда на самом деле я просто хочу вытащить сохраненную версию этого экрана. Возможно ли это с моей текущей настройкой, или я поступил неправильно?

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

Попробуйте использовать fragementTransaction.add вместо замены

Ответ 3

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

Следующий код продемонстрирует, как открыть 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();
        }
    } 
}

Ответ 4

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

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

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.

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

Удачи.