2012-06-06 2 views
3

Helo.Android: Мастер, как активность с фрагментами

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

Я пытаюсь реализовать один, но на данный момент возникли некоторые проблемы.

Вот активность XML с заполнителем для ступенчатых фрагментов:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <FrameLayout 
    android:id="@+id/fragment_container" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_above="@+id/cmd_previous" 
    android:layout_alignParentTop="true" > 
    </FrameLayout> 

    <Button 
    android:id="@+id/cmd_previous" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignRight="@+id/center_separator_buttons" 
    android:text="@string/rpz_cmd_perv" /> 

    <View 
    android:id="@+id/center_separator_buttons" 
    style="@style/wd_center_aligner" 
    android:layout_alignParentBottom="true" /> 

    <Button 
    android:id="@+id/cmd_next" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignLeft="@+id/center_separator_buttons" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentRight="true" 
    android:text="@string/rpz_cmd_next" /> 

</RelativeLayout> 

В OnCreate я добавить первый шаг к деятельности:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_report_wizard); 

    if (this.getIntent().getExtras() != null) { 
    Bundle extra = this.getIntent().getExtras(); 
    if (extra.containsKey(ISelected.ID_KEY)) { 
     _ID = extra.getLong(ISelected.ID_KEY); 
    } 
    } 

    if (findViewById(R.id.fragment_container) != null && savedInstanceState == null) { 
    _ReportTypeAndName = new ReportWizardTypeAndNameFragment(); 
    _ReportTypeAndName.setArguments(getIntent().getExtras()); 
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, _ReportTypeAndName).commit(); 
    } 
} 

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

private void runNext(View view) { 
    switch (_CurrentPage) { 
    case ReportTypeAndName: 
     _ReportSelect = new ReportWizardSelectFragment(); 
     _ReportSelect.setArguments(getIntent().getExtras()); 
     getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, _ReportSelect).addToBackStack(null).commit(); 

     _CurrentPage = ReportWizardPage.ReportSelect; 
     break; 

    case ReportSelect: 
     _CurrentPage = ReportWizardPage.ReportPreview; 
     break; 

    case ReportPreview: 
     _CurrentPage = ReportWizardPage.None; 
     break; 

    default: 
     break; 
    } 
} 

Но на ПРЕДЫДУЩЕЙ кнопке это не работает.

private void runPrevious(View view) { 
    switch (_CurrentPage) { 
    case ReportTypeAndName: 
     // Umstellung des Typs 
     _CurrentPage = ReportWizardPage.None; 
     this.finish(); 
     break; 

    case ReportSelect: 
     _ReportTypeAndName = new ReportWizardTypeAndNameFragment(); 
     _ReportTypeAndName.setArguments(getIntent().getExtras()); 
     getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, _ReportTypeAndName).commit(); 

     _CurrentPage = ReportWizardPage.ReportTypeAndName; 
     break; 

    case ReportPreview: 
     _CurrentPage = ReportWizardPage.ReportSelect; 
     break; 

    default: 
     break; 
    } 
} 

я получил следующую ошибку (LogCat):

FATAL EXCEPTION: main 
android.view.InflateException: Binary XML file line #13: Error inflating class fragment 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697) 
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:739) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 
    at de.webducer.android.worktime.beta.ui.fragment.ReportWizardTypeAndNameFragment.onCreateView(ReportWizardTypeAndNameFragment.java:40) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:870) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080) 
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416) 
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420) 
    at android.os.Handler.handleCallback(Handler.java:605) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4424) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.IllegalArgumentException: Binary XML file line #13: Duplicate id 0x7f05008b, tag null, or parent id 0x0 with another fragment for de.webducer.android.worktime.beta.ui.fragment.ReportTypeSelectorSpinnerFragment 
    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:275) 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:669) 
    ... 18 more 

Линия 40 фрагмента является инфлятор из них

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.frag_report_wizard_1, container, false); 
} 

Как можно связать (добавить/удалить) фрагменты без получения повторяющихся идентификаторов? Или как я могу повторно использовать фрагмент без новой View-Initialization?

enter image description here

+0

Посмотрите на часть «из-за» ... она указывает в другом месте. Опубликуйте «ReportTypeSelectorSpinnerFragment» и, возможно, мы сможем понять это. – Barak

ответ

2

Я использую библиотеку поддержки v4 и панель действий Шерлока.

После некоторых попыток с использованием BackStack и без него и упрощения компоновки фрагментов шага я окончательно нашел причину исключения.

Я использую фрагмент (выделенный вращатель) в моем первом шагах Фрагмен (см XML-схема)

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <TextView 
    android:id="@+id/lbl_report_type" 
    style="@style/wd_field_label" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentTop="true" 
    android:text="@string/rpz_lbl_report_type" /> 

    <fragment 
    android:id="@+id/frag_report_type_spinner" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentLeft="true" 
    android:layout_below="@+id/lbl_report_type" 
    class="de.webducer.android.ReportTypeSelectorSpinnerFragment" /> 

    <TextView 
    android:id="@+id/lbl_report_name" 
    style="@style/wd_field_label" 
    android:layout_alignParentLeft="true" 
    android:layout_below="@+id/frag_report_type_spinner" 
    android:text="@string/rpz_lbl_report_name" /> 

    <EditText 
    android:id="@+id/report_name" 
    style="@style/wd_text_edit_pref" 
    android:layout_alignParentLeft="true" 
    android:layout_below="@+id/lbl_report_name" 
    android:hint="@string/rpz_hint_report_name" /> 

    <TextView 
    android:id="@+id/lbl_report_comment" 
    style="@style/wd_field_label" 
    android:layout_alignParentLeft="true" 
    android:layout_below="@+id/report_name" 
    android:text="@string/rpz_lbl_report_comment" /> 

    <EditText 
    android:id="@+id/report_comment" 
    style="@style/wd_text_multi_edit_pref" 
    android:layout_alignParentLeft="true" 
    android:layout_below="@+id/lbl_report_comment" 
    android:hint="@string/rpz_hint_report_comment" /> 

    <TextView 
    android:id="@+id/lbl_active" 
    style="@style/wd_field_label" 
    android:layout_alignParentLeft="true" 
    android:layout_below="@+id/report_comment" 
    android:text="@string/lbl_active" /> 

    <CheckBox 
    android:id="@+id/report_type_active" 
    style="@style/wd_text_edit_pref" 
    android:layout_alignParentLeft="true" 
    android:layout_below="@+id/lbl_active" 
    android:checked="true" 
    android:text="@string/rpz_hint_report_type_active" /> 

</RelativeLayout> 

Ithis внутреннего фрагмент произвел исключение, потому что внешнего фрагмент пытается в onCreateView раздувать внутренних фрагмент. И этот уже находится в FragmentManager с данным ID.

Мое решение теперь уничтожить внутренний фрагмент bevore заменить на новый или перед вызовом из задней стопки.

private void runPrevious(View view) { 
    switch (_CurrentPage) { 
    case ReportTypeAndName: 
     // Umstellung des Typs 
     _CurrentPage = ReportWizardPage.None; 
     this.finish(); 
     break; 

    case ReportSelect: 
     if (getSupportFragmentManager().findFragmentById(R.id.frag_report_type_spinner) != null) { 
     getSupportFragmentManager().beginTransaction() 
      .remove(getSupportFragmentManager().findFragmentById(R.id.frag_report_type_spinner)).commit(); 
     } 
     getSupportFragmentManager().popBackStack(); 
     // Umstellung des Typs 
     _CurrentPage = ReportWizardPage.ReportTypeAndName; 
     break; 

    case ReportPreview: 
     _CurrentPage = ReportWizardPage.ReportSelect; 
     break; 

    default: 
     break; 
    } 
    setButtonState(); 
} 

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

+0

Вы должны выбрать это как принятый ответ. :) – Barak

2

Положите фрагменты в backstack и называть их обратно по мере необходимости.

Добавьте его в backstack с помощью addToBackStack:

list = new ListFragment_List(); 
getFragmentManager().beginTransaction().replace(R.id.pane, listlist).addToBackStack(null).commit(); 

Потяните его обратно с помощью popBackStack:

FragmentManager fm = getActivity().getSupportFragmentManager(); 
fm.popBackStack(); 

Примечание Этот код пришел из приложения шахты с использованием библиотеки поддержки v4, поэтому вызов менеджера фрагментов будет немного отличаться, если вы разрабатываете только для Android 3.0+.

+0

Я попробовал это, прежде чем писать здесь и сейчас. У меня такое же исключение в LogCat. – WebDucer

2

Я думал, что вы, возможно, захотите узнать, что теперь есть рабочее решение именно для того, что вы искали. Это легкая Android-библиотека под названием WizarDroid.

+0

Ссылка на них сломана. Можете ли вы его обновить? –

+1

обновлено, спасибо, что уведомило (а) –

Смежные вопросы