Activity 选项卡内的 Android 主细节布局避免嵌套 fragment

标签 android android-layout android-fragments android-actionbar android-fragmentactivity

我对android的Fragment不是很专家。在我的上一个项目中,我使用了 TabActivity,但由于它已被弃用,现在我开始使用 Fragments 实现 ActionBar。

这是我的选项卡类的代码:

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

我以这种方式实现了 ActionBar.TabListener:

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

请注意有关附加/分离方法的注释,以支持显示/隐藏。这是因为在我的第二个选项卡中,我在第二次输入它时遇到异常(肯定是因为第二个选项卡 fragment 的设计不好)。这里有一个异常(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_

(删除 <fragment android:name="it.cpmapave.mt.ui.intervento.SistemaAlimentazioneListFragment_" /> 的标签和 id 可以解决问题..但我需要一种方法来获取它以刷新他的适配器!所以我显示/隐藏 fragment 而不是附加/分离)。幸运的是,我必须修复方向,因此当使用显示/隐藏更改方向时,我不会出现 fragment 重叠的问题。

这是第一个选项卡显示的 DatiFragment,它扩展了 Fragment 类。

First Fragment

这似乎没问题!

这里是第二个选项卡,其中显示了 StrumentiFragment。这是布局:

<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>

enter image description here

从 fragment A 中的 Spinner 添加元素会更新 fragment 列表 B。从 fragment 列表 B 中选择元素会更新 fragment C 中的详细信息。

我认为问题可能是由嵌套的 fragment 引起的..但我不知道如何以不同的方式设计它..也许我发现它比实际情况更困难..

我在代码中省略了说明和显示我正在使用 ActionBarSherlock,只是因为我认为这不是我的问题的原因!

所以最后......问题是:

我需要获得像第二张图片所示的功能布局。但我只能通过嵌套 fragment 来获得它..我必须避免这样做。我该怎么办?

感谢您的回复 马可

最佳答案

我已经解决了将每个框架放入 FrameLayout 中,并在需要时显示/隐藏的问题。

我还为创建 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>

我希望这对某人有用!

关于 Activity 选项卡内的 Android 主细节布局避免嵌套 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12951670/

相关文章:

java - 我如何能够在 fragment 的 ImageView 中显示大量图像?

android - YouTube Android fragment 闪烁

android - 使用 surfaceView 捕捉视频

android - 如何在一次显示多个 fragment 的同时在 viewpager 中查找当前可见的 fragment

android - Android 应用程序根本不接收 GCM 消息

java - 返回当前的 android 布局或屏幕宽度以进行调试

java - 为什么我的 fragment 中没有调用我的 android.R.id.home?

android - 同一行上的多个按钮/对象

java - Android 中的 3D 游戏

android - CollapsingToolbarLayout 不适用于 NestedScrollView