Android MasterDetail layout inside ActivityTab avoiding nested Fragments

99封情书 提交于 2020-01-15 03:11:06

问题


I'm not very expert in android's Fragment. In my last project i was using TabActivity, but because of it's deprecation now I'm starting implements an ActionBar using Fragments.

Here is the code of my Tab Class:

public class TabInterventoClass extends FragmentActivity{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayShowTitleEnabled(false);

    Tab tab = actionBar.newTab()
            .setText("Dati")
            .setTabListener(new TabListener<DatiFragment_>(this, "dati", DatiFragment_.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab()
            .setText("Sistemi alimentazione")
            .setTabListener(new TabListener<SistemaAlimentazioneFragment_>(this, "Sistemi alimentazione", SistemaAlimentazioneFragment_.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab()
        .setText("Home")
        .setTabListener(new TabListener<HomeFragment_>(this, "home", HomeFragment_.class));
    actionBar.addTab(tab);
}

I've implemented ActionBar.TabListener in this way:

public class TabListener<T extends Fragment> implements ActionBar.TabListener {
    private Fragment mFragment;
    private final FragmentActivity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    public TabListener(FragmentActivity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // Check if the fragment is already initialized
        if (mFragment == null) {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            // If it exists, simply attach it in order to show it
            //ft.attach(mFragment);
            ft.show(mFragment);
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            // Detach the fragment, because another one is being attached
            //ft.detach(mFragment);
            ft.hide(mFragment);
        }
    }
}

Please note the comment on attach/detach method in favor of show/hide. This is because in my SECOND tab I get an exception the 2nd time I enter it (surely for bad design of second Tab Fragment). Here the exception:

10-18 11:10:13.093: E/AndroidRuntime(3777): Caused by: java.lang.IllegalArgumentException: Binary XML file line #38: Duplicate id 0xffffffff, tag sistemiList, or parent id 0x0 with another fragment for it.cpmapave.mt.ui.intervento.SistemaAlimentazioneListFragment_

(Removing the tag and the id of <fragment android:name="it.cpmapave.mt.ui.intervento.SistemaAlimentazioneListFragment_" /> solve the problem.. but I need a way to get it in order to refresh his adapter! So I show/hide Fragments instead of attach/detach). Luckily I have to fix orientation so I have no problem of overlapping fragments when orientation changes using show/hide.

Here is the FIRST tab display DatiFragment, which extends Fragment class.

And this seems to be ok!

And here is on the SECOND tab, which displays StrumentiFragment. Here is the layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:divider="?android:attr/dividerHorizontal"
android:showDividers="middle">
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
       android:layout_height="fill_parent"
       android:layout_width="wrap_content"
       android:gravity="center_vertical"
       android:text="Sistema di alimentazione:" />

    <Spinner 
        android:id="@+id/sistemiDiAlimentazione"
        android:layout_height="fill_parent"
        android:layout_width="wrap_content" />

     <Button 
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Aggiungi"
        android:id="@+id/addSistemaAlimentazione" />           

</LinearLayout>
<LinearLayout
    android:baselineAligned="false"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <fragment android:name="it.cpmapave.mt.ui.intervento.SistemaAlimentazioneListFragment_"
        android:layout_width="0dp"
        android:tag="sistemiList"
        android:layout_height="match_parent"
        android:layout_weight="1" />
    <FrameLayout android:id="@+id/item_detail_container"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3" />
</LinearLayout>

Adding an element from Spinner in Fragment A update the FragmentList B. Selecting an element from Fragment List B update details in the Fragment C.

I think the problem could be caused by nested Fragments.. but I don't know how con I design it in a different way.. maybe I make it out to be more difficult than it really is..

I've omitted to say and to show in the code that I'm using ActionBarSherlock, only because I think that is not cause of my problem!

So at the end.. the question is:

I need to obtain a functional layout like the one showed in the second picture. But I obtained it only by nesting fragments.. I must avoid to do it. How can i do?

Thank you for any response Marco


回答1:


I've solved putting each Frame in a FrameLayout, showing/hiding when needed.

I've also defined a custom layout for the class where I created my ActionTab:

<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TabWidget
        android:id="@android:id/tabs"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0"/>

    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <LinearLayout
        android:baselineAligned="false"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <FrameLayout
            android:id="@+android:id/navtabcontent"
            android:layout_width="0dp"
            android:layout_height="600dp"
            android:layout_weight="1"/>
        <FrameLayout
            android:id="@+android:id/realtabcontent"
            android:layout_width="0dp"
            android:layout_height="600dp"
            android:layout_weight="3"/>
    </LinearLayout>
</LinearLayout>

I hope this can be useful for someone!



来源:https://stackoverflow.com/questions/12951670/android-masterdetail-layout-inside-activitytab-avoiding-nested-fragments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!