Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Переключение между фрагментами в одном действии

Автор вопроса: nhaarmanОтветов: 3

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

Я хотел реализовать это с помощью Fragments, но у меня это не работает.
Сейчас у меня есть:

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:id="@+id/main_fragmentcontainer" >

    <fragment
        android:id="@+id/mainmenufragment"
        android:name="com.myapp.MainMenuFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <fragment
        android:id="@+id/secondmenufragment"
        android:name="com.myapp.SecondMenuFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

MainMenuFragment с OnClickListener:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.mainmenu, container, false);

    setupButton(view);
    return view;
}

/* Button setup code omitted */

@Override
public void onClick(View v) {
    SherlockFragment secondRunMenuFragment = (SherlockFragment) getSherlockActivity().getSupportFragmentManager().findFragmentById(R.id.secondmenufragment);
    FragmentTransaction transaction = getSherlockActivity().getSupportFragmentManager().beginTransaction();

    transaction.replace(android.R.id.content, secondMenuFragment); //also crashes with R.id.main_fragmentcontainer
    transaction.addToBackStack(null);
    transaction.commit();
}

Теперь, когда я нажимаю кнопку, приложение вылетает с этим логарифмом:

06-27 01:45:26.309: E/AndroidRuntime(8747): java.lang.IllegalStateException: невозможно изменить идентификатор контейнера фрагмента SecondMenuFragment{405e2a70 #1 id=0x7f060029}: был 2131099689, теперь 2131099687
06-27 01:45:26.309: E/AndroidRuntime(8747): на android.support.v4.app.BackStackRecord.doAddOp(Неизвестный источник)
06-27 01:45:26.309: E/AndroidRuntime(8747): на android .support.v4.app.BackStackRecord.replace(неизвестный источник)
06-27 01:45:26.309: E/AndroidRuntime(8747): в android.support.v4.app.BackStackRecord.replace(неизвестный источник) 06-27 01:45:26.309: E/AndroidRuntime(8747): в com.myapp.MainMenuFragment$MyButtonOnClickListener.onClick(MainMenuFragment.java:52)

Что я делаю неправильно?

  • Здесь есть аналогичный вопрос adneal 27.06.2012
  • Если вы пытаетесь создать мастер, для чего нужен второй <fragment>? CommonsWare 27.06.2012
  • Я действительно видел эти ссылки, но я не знаю, как их применить в моем случае. nhaarman 27.06.2012
  • @CommonsWare Первый Fragment показывает первое меню с кнопками 1, 2 и 3. Второй Fragment показывает второе меню с кнопками 1.1, 1.2 и 1.3. В планах добавить третью Fragment с кнопками 2.1, 2.2 и 2.3. Или я подхожу ко всему этому неправильно? nhaarman 27.06.2012

androidandroid-fragmentsandroid-activity

Ответы

Ответ 1 · рейтинг 15 · CommonsWare

Лично у меня не было бы <fragment> элементов.

Шаг № 1: Заполните макет активности <FrameLayout> для переменной части мастера, а также различные кнопки.

Шаг № 2: В onCreate() действия запустите FragmentTransaction, чтобы загрузить первую страницу мастера в FrameLayout.

Шаг № 3: При нажатии кнопки "Далее" запустите FragmentTransaction, чтобы заменить содержимое FrameLayout следующей страницей мастера.

Шаг № 4: Добавьте соответствующие интеллектуальные функции для отключения кнопок, когда они непригодны для использования (например, на первой странице мастера).

Кроме того, вам следует подумать о том, как кнопка НАЗАД должна работать в сочетании с любой экранной кнопкой "назад" в мастере. Если вы хотите, чтобы они оба вели себя одинаково, вам нужно будет добавить каждую транзакцию в задний стек и вытолкнуть материал из заднего стека, когда вы обрабатываете кнопку "назад".

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

Ответ 2 · рейтинг 16 · Josep Escobar

Я создаю этот основной макет:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="horizontal"
   tools:context="com.example.fragmentsexample.MainActivity" >

   <FrameLayout
      android:id="@+id/contentFragment"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:layout_weight="1" />

</LinearLayout>

И я пополнил в FrameActivity:

@Override
public void onCreate(Bundle savedInstanceState) {
  ...
  Fragment fragment = new Dashboard();
  FragmentManager fm = getSupportFragmentManager();
  FragmentTransaction transaction = fm.beginTransaction();
  transaction.replace(R.id.contentFragment, fragment);
  transaction.commit();
  ...
}

И я повторяю метод onClick с тем же кодом, изменяя фрагмент (панель инструментов для событий):

@Override
public void onClick.... {
  ...
  Fragment fragment = new Events();
  FragmentManager fm = getSupportFragmentManager();
  FragmentTransaction transaction = fm.beginTransaction();
  transaction.replace(R.id.contentFragment, fragment); //Container -> R.id.contentFragment
  transaction.commit();
  ...
}

Ответ 3 · LordRaydenMK

Другой вариант - использовать Android-WizardPager от Романа Нурика.

Ключевая особенность:

  • Ветвление или способность шагов мастера влиять на доступность последующих шагов.
  • Предоставление пользователю возможности просмотра перед фиксацией
  • Предоставление пользователю свободной навигации между шагами мастера
  • Поддержка обязательных и необязательных шагов
  • Поддержка классов шагов (технически каждый шаг является экземпляром класса Java, поэтому в мастере может быть несколько экземпляров)

Подробнее здесь.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы