Android 1.6与Fragment和Tabhost

16

我正在升级一个使用 TabHost 显示三个不同选项卡和嵌套活动的 Android 应用程序 (1.6 兼容性)。

当时使用 ActivityGroup 技巧在选项卡中显示嵌套活动,但我对此方法非常不满意,因为处理某些功能真的很麻烦。

我听说了适用于 1.6 的碎片 API 兼容包,而且一个 Fragment 看起来非常适合我想做的事情(在选项卡中显示嵌套视图 / 功能并具有过渡效果等),但我无法使其与 TabHost 结合使用(它是用于与 Action Bar 一起使用的,但在兼容包中不可用)。

你们有没有找到一种方法在应用程序中创建这样的结构?

我这里的错误是:

ERROR/AndroidRuntime(955): Caused by: java.lang.RuntimeException: Unable

启动活动 ComponentInfo{com.XXX} 时发生错误:在片段 MyFragment 中没有找到 id 为 0x1020011 的视图。

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

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

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:layout_weight="1" />

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

    </LinearLayout>

</TabHost>

MainActivity.java

public class MainActivity extends TabActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        Resources res = getResources();
        final TabHost tabs = getTabHost(); 
        TabHost.TabSpec spec;
        Intent i;

        i = new Intent(this, MyActivity.class);
        spec = tabs.newTabSpec("MyActivity").setIndicator("MyActivity",res.getDrawable(R.drawable.tab)).setContent(i);
        tabs.addTab(spec);

    }

}

MyActivity.class

public class MyActivity extends FragmentActivity {

    private static String TAG = "MyActivity";
    private static FragmentManager fragmentManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        ListeResultatFragment fragment = MyFragment.newInstance();
        fragmentTransaction.add(android.R.id.tabcontent, fragment, "MyFragment");
        fragmentTransaction.commit();

    }

}

MyFragment.java

public class MyFragment extends Fragment {

    public static MyFragment newInstance() {
        MyFragment instance = new MyFragment();
        return instance;
    }

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

}

你是说在TabHost中不能将<fragment>元素放置在FrameLayout的子级吗?我本以为这应该可以,但我个人还没有尝试过。 - CommonsWare
请解释一下我的程序哪里出了问题。记住,您始终可以通过编程方式添加片段。 - oriharel
你有什么想法,为什么我无法在android.R.id.tabcontent中显示内容? - Vivi
ActionBar 不在兼容包中可用,但您可以使用 https://github.com/JakeWharton/ActionBarSherlock。 - Macarse
2个回答

10
问题在于您的MyActivity尝试使用android.R.id.tabcontent作为容器id来访问封闭的MainActivity。这是不可能的。相反,MyActivity需要具有自己的布局(例如FrameLayout),可用作片段的父级。在此布局中,必须存在一个可以通过ID引用的视图。
假设您有一个名为activity_layout.xml的布局,其中包含一个带有ID“framelayout”的FrameLayout。然后,您可以将MyActivity中的onCreate方法修改为以下内容:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    View parent = getLayoutInflater().inflate(R.layout.activity_layout, null);
    setContentView(parent);

    fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment fragment = MyFragment.newInstance();
    fragmentTransaction.add(R.id.framelayout, fragment, "MyFragment");
    fragmentTransaction.commit();
}

换句话说,MyActivity 需要能够独立工作。先尝试让它单独运行,然后再将 MyActivity 嵌入包含 TabHost 的 MainActivity 中。


4

为什么不自己创建标签栏呢?它很容易构建。只需添加一个LinearLayout,并在其中添加一些按钮,然后使用FragmentManager设置onClickListener来切换片段。FragmentManager可以从FragmentActivity中获取。

FragmentManager fragmentManager = getSupportFragmentManager();

在onClick处理程序中,您只需执行事务以切换到正确的片段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接