2012-06-06 51 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; 
    } 
} 

但是在PREVIOUS-Button上,這是行不通的。

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); 
} 

如何我可以綁定(添加/刪除)片段沒有得到重複的ID?或者我怎樣才能重新使用片段沒有新的視圖初始化?

enter image description here

+0

看看「造成」部分......它指向其他地方。發佈'ReportTypeSelectorSpinnerFragment',也許我們可以搞清楚。 – Barak

回答

2

我使用支持庫v4和Sherlock Actionbar。

在嘗試使用和不使用BackStack並簡化了步驟片段的佈局之後,我最終找到了例外的原因。

我在我的第一步驟fragmen使用的片段(selction微調)(參見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

把你的片段在堆棧中,並根據需要給他們打電話回來。

它使用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

,謝謝你通知我 –