FragmentTabHost 图形布局不呈现

Posted

技术标签:

【中文标题】FragmentTabHost 图形布局不呈现【英文标题】:FragmentTabHost graphical layout doesn't render 【发布时间】:2012-12-31 12:00:07 【问题描述】:

简单的 android.support.v4.app.FragmentTabHost 的图形布局永远不会在 Eclipse 或 Android Studio 中呈现。 我得到的控制台错误始终是:Exception raised during rendering: No tab known for tag null

我使用的是最基本的 XML 文件:

<android.support.v4.app.FragmentTabHost
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_
    android:layout_>

    <LinearLayout
        android:orientation="vertical"
        android:layout_
        android:layout_>

        <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_
            android:layout_
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_
            android:layout_
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@+id/realtabcontent"
            android:layout_
            android:layout_
            android:layout_weight="1"/>

    </LinearLayout>
</android.support.v4.app.FragmentTabHost>

但同样的错误发生了。

我只是想在选项卡小部件和框架布局的上方或下方添加更多视图。 我不太关心看到标签内容;我只想查看 我的布局的其余部分 - 但问题是当一个 android.support.v4.app.FragmentTabHost 驻留在布局中时不会呈现其他视图

我已阅读并尝试通过此帖子的答案解决问题:Android: Tabs at the bottom with FragmentTabHost 但我不认为那是我的问题;我不想在底部放置 TabWidget。

我的每个其他 XML 文件都可以完美打开。

同样的问题出现在Android Studio中:

【问题讨论】:

那个错误是 logcat 还是控制台?如果是logcat,请发帖。 这是一个错误日志:在 Eclipse 中:(渲染期间引发的异常:No tab known for tag null 异常详细信息记录在 Window > Show View > Error Log 中) FragmentTabHost 不会显示任何内容,因为内容是动态添加的。所以他们没有问题。当您在代码中添加选项卡并对其进行测试时,应该可以工作。 androidhive.info/2011/08/android-tab-layout-tutorial 我打开了一个错误报告,请投票:code.google.com/p/android/issues/detail?id=78772 【参考方案1】:

我遇到了同样的渲染问题以及编译错误。我通过发现在创建 Addtab 时没有传递 Fragment 来解决问题。您必须在 mTab​​Host.addTab 上传递至少一个片段。下面是工作代码。

private FragmentTabHost mTabHost;
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
            mTabHost.setup(HomeActivity.this, getSupportFragmentManager(), android.R.id.tabcontent);

            mTabHost.addTab(mTabHost.newTabSpec("home").setIndicator("Home"), HomeFragment.class, null);
            mTabHost.addTab(mTabHost.newTabSpec("mysheets").setIndicator("MySheets"));
            mTabHost.addTab(mTabHost.newTabSpec("bookmarks").setIndicator("Bookmarks"));

【讨论】:

【参考方案2】:

不确定您遇到的错误(抱歉,我现在真的很忙,所以不能花更多时间检查)但总的来说,支持库中的 FragmentTabHost 似乎并不关心xml。请参阅我之前对另一个问题的回答:

FragmentTabHost with horizontal scroll

【讨论】:

【参考方案3】:

从布局我得到相同的错误..所以,我只通过代码解决了这个问题......它工作正常..请试试这个代码

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class DetailFragment extends Fragment 

    /******************************************************************************************************************
     * Mandatory empty constructor for the fragment manager to instantiate the fragment (e.g. upon screen orientation changes).
     *****************************************************************************************************************/
    public DetailFragment() 
    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        // R.layout.fragment_tabs_pager contains the layout as specified in your question
        View rootView = inflater.inflate(R.layout.fragment_tabs_pager, container, false);

        // Initialise the tab-host
        FragmentTabHost mTabHost = (FragmentTabHost) rootView.findViewById(R.id.tabhost);
        mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);

        // Initialise this list somewhere with the content that should be displayed
        List<String> itemsToBeDisplayed;

        for (String subItem : itemsToBeDisplayed) 
            // Give along the name - you can use this to hand over an ID for example
            Bundle b = new Bundle();
            b.putString("TAB_ITEM_NAME", subItem);

            // Add a tab to the tabHost
            mTabHost.addTab(mTabHost.newTabSpec(subItem).setIndicator(subItem), YourContentFragment.class, b);
        
        return rootView;
    




/********************************************************
This class contains the actual content of a single tab  
**********************************************************/
public class YourContentFragment extends Fragment 

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        Bundle extras = getArguments();
        if (extras != null) 
            if (extras.containsKey("TAB_ITEM_NAME")) 
                String subItem = extras.getString("TAB_ITEM_NAME");
                // Do something with that string
            
        
    

【讨论】:

【参考方案4】:

如果你需要在屏幕底部放置碎片标签... @fallow 未提及--

像这样制作你的 xml 文件 ..

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_
        android:layout_
        android:orientation="vertical" >

       <!--   <RelativeLayout 
            android:layout_ 
            android:layout_>  android:layout_alignParentTop="true"  -->

         <FrameLayout
            android:id="@+id/realtabcontent"
            android:layout_
            android:layout_
            android:layout_weight="1" />


        <android.support.v4.app.FragmentTabHost
            android:id="@android:id/tabhost"
            android:layout_
            android:layout_
            >

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_
                android:layout_
                android:layout_weight="0" />

        </android.support.v4.app.FragmentTabHost>

    </LinearLayout>

现在,如果您担心在单个碎片选项卡中打开多个碎片...

@follow steps ::

    创建一个容器片段。此容器片段将是您所有标签内容的默认设置。 对于每个选项卡内容,用此容器替换 U 需要的片段。

例如:- 就像你用不同的床单替换你的床.. :)

将在不同选项卡中以不同方式使用的容器片段类...“LearnContainerFragment.java”

    public class LearnContainerFragment extends BaseContainerFragment 

        private boolean mIsViewInited;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
            Log.e("test", "tab 1 oncreateview");
            return inflater.inflate(R.layout.container_fragment, null);
        

        @Override
        public void onActivityCreated(Bundle savedInstanceState) 
            super.onActivityCreated(savedInstanceState);
            Log.e("test", "tab 1 container on activity created");
            if (!mIsViewInited) 
                mIsViewInited = true;
                initView();
            
        

        private void initView() 
            Log.e("test", "tab 1 init view");
            replaceFragment(new Learn(), false);
        

    

LearnContainerFragment.java ---> xml 文件 container_fragment.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/container_framelayout"
        android:layout_
        android:layout_>


    </FrameLayout>

@如何使用Conatiner..

    对于 U 需要的每个片段,都将替换为此容器片段的 id。

@last 你的 BaseContainerFragment.java 类 --

public class BaseContainerFragment extends Fragment 

    public void replaceFragment(Fragment fragment, boolean addToBackStack) 
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        if (addToBackStack) 
            transaction.addToBackStack(null);
        
        transaction.replace(R.id.container_framelayout, fragment);
        transaction.commit();
        getChildFragmentManager().executePendingTransactions();
    

    public boolean popFragment() 
        Log.e("test", "pop fragment: " + getChildFragmentManager().getBackStackEntryCount());
        boolean isPop = false;
        if (getChildFragmentManager().getBackStackEntryCount() > 0) 
            isPop = true;
            getChildFragmentManager().popBackStack();
        
        return isPop;
    


希望对你有帮助..... 干杯!

【讨论】:

【参考方案5】:

不确定....但是您的布局中不应该在 tabwidget 的线性布局上方有一个 tabhost 标签吗?

<TabHost
    android:id="@+id/tabhost"
    android:layout_
    android:layout_
    android:background="@drawable/background"
>

不久前我做了一个应用程序,它使用 tabhost 实现了选项卡,这就是我的布局方式......一个选项卡有一个日历视图,一个有一个图像切换器,一个有一个列表视图......对不起,我不能更多帮助

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:background="@drawable/background"
tools:context=".MainActivity" >

<TabHost
    android:id="@+id/tabhost"
    android:layout_
    android:layout_
    android:background="@drawable/background"
>

    <LinearLayout
        android:layout_
        android:layout_
        android:background="@drawable/background"
        android:orientation="vertical" >

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_
            android:layout_ >

        </TabWidget>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_
            android:layout_ >

            <LinearLayout
                android:id="@+id/tab1"
                android:layout_
                android:layout_
                android:orientation="vertical" >

                <ListView
                    android:id="@+id/listView1"
                    android:layout_
                    android:layout_ >
                </ListView>
            </LinearLayout>

            <LinearLayout
                android:id="@+id/tab2"
                android:layout_
                android:layout_
                android:orientation="vertical" >

                <ImageSwitcher
                    android:id="@+id/imageSwitcher1"
                    android:layout_
                    android:layout_ >
                </ImageSwitcher>

                <TextView
                    android:id="@+id/tv"
                    android:layout_
                    android:layout_
                    android:scrollbars="vertical" />

            </LinearLayout>

            <LinearLayout
                android:id="@+id/tab3"
                android:layout_
                android:layout_
                android:orientation="vertical" >

                <CalendarView
                    android:id="@+id/calendarView1"
                    android:layout_
                    android:layout_ />
            </LinearLayout>

        </FrameLayout>
    </LinearLayout>

</TabHost>

【讨论】:

好吧,一个普通的 android.widget.TabHost 可以工作,除了 [android.app.TabActivity is deprecated][tabactivity] 支持使用 FragmentTabHosts 和 Fragments。 [tabactivity]:[developer.android.com/reference/android/app/TabActivity.html]

以上是关于FragmentTabHost 图形布局不呈现的主要内容,如果未能解决你的问题,请参考以下文章

FragmentTabHost + Fragment 使用小记

FragmentTabHost+Fragment搭建应用主框架

FragmentTabHost+Fragment搭建应用主框架

FragmentTabHost的使用方法总结

FragmentTabHostTopDemoFragmentTabHost固定宽度且居中

android中 Fragment+FragmentTabHost