当前位置: 首页 > 知识库问答 >
问题:

FragmentTabHost-没有标签为空

东弘扬
2023-03-14

几天前,我使用导航抽屉片段中实现了TabHostFramgent,我遇到了一个问题,即以下错误:

java.lang.IllegalStateException:没有已知的标签 null 选项卡

事情是这样的,因为我的< code>NavigationDrawer的第一个项目列表是我的< code>TabHostFragment,所以它工作得很好,但问题是当我在示例中进入第二个项目,然后我想回到第一个项目时,每次我尝试它都会崩溃。

我到处搜索,在< code>SO、< code>code.google.com等等...我仍然没有得到正确的答案。

我的tab_host_test_2.xml看起来像:

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

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

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

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

        <FrameLayout
            android:id="@+id/realtabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    </LinearLayout>

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

我的activity_main.xml我的NavigationDrawer的位置如下所示:

 <android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Framelayout to display Fragments -->
    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <!-- Listview to display slider menu -->
    <ListView
        android:id="@+id/list_slidermenu"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@color/list_divider"
        android:dividerHeight="1dp"
        android:listSelector="@drawable/list_selector"
        android:background="@color/list_background"/>
</android.support.v4.widget.DrawerLayout>

我的TabHostFragment.java

    public class TabHostFragment extends Fragment {

    public TabHostFragment(){

    }
    private FragmentTabHost mTabHost;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.tab_host_test2, container, false);
        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        mTabHost = (FragmentTabHost)view.findViewById(android.R.id.tabhost);
        mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);

        mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab1"),
                MisOfertasFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Tab2"),
                RecomendacionesFragment.class, null);




    }

}

我的< code>ActivityMain.java:

public class MainActivity extends FragmentActivity {
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;
    // saber si esta abierto
    public boolean mDrawerOpened;
    // nav drawer title
    private CharSequence mDrawerTitle;
    private FragmentTabHost mTabHost;
    // used to store app title
    private CharSequence mTitle;

    //para ponerlo visible
    public MenuItem mi;

    // slide menu items
    private String[] navMenuTitles;
    private TypedArray navMenuIcons;

    private ArrayList<NavDrawerItem> navDrawerItems;
    private NavDrawerListAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mTitle = mDrawerTitle = getTitle();

        // load slide menu items
        navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

        // nav drawer icons from resources
        navMenuIcons = getResources()
                .obtainTypedArray(R.array.nav_drawer_icons);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

        navDrawerItems = new ArrayList<NavDrawerItem>();

        // adding nav drawer items to array
        // Home
        navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
        // Find People
        navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
        // Photos
        navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
        // Communities, Will add a counter here
        navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1)));
        // Pages
        navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
        // What's hot, We  will add a counter here
        navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1)));
        //AyudaSugerencias
        navDrawerItems.add(new NavDrawerItem(navMenuTitles[6], navMenuIcons.getResourceId(6, -1)));
        navDrawerItems.add(new NavDrawerItem(navMenuTitles[7], navMenuIcons.getResourceId(7, -1)));


        // Recycle the typed array
        navMenuIcons.recycle();

        mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

        // setting the nav drawer list adapter
        adapter = new NavDrawerListAdapter(getApplicationContext(),
                navDrawerItems);
        mDrawerList.setAdapter(adapter);

        // enabling action bar app icon and behaving it as toggle button

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setBackgroundDrawable(new ColorDrawable(0xff1d97dd));
        getActionBar().setHomeButtonEnabled(true);

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, //nav menu toggle icon
                R.string.app_name, // nav drawer open - description for accessibility
                R.string.app_name // nav drawer close - description for accessibility
        ) {
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(
                        Html.fromHtml("<font color='ffffff'>"
                                + mTitle + "</font>"));

                // calling onPrepareOptionsMenu() to show action bar icons
                invalidateOptionsMenu();
                mDrawerOpened = false;
                syncState();

            }

            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(
                        Html.fromHtml("<font color='ffffff'>"
                                + mDrawerTitle + "</font>"));

                // calling onPrepareOptionsMenu() to hide action bar icons
                invalidateOptionsMenu();
                mDrawerOpened = true;
                syncState();
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if (savedInstanceState == null) {
            // on first time display view for first nav item
            displayView(0);
        }
    }

    /**
     * Slide menu item click listener
     */
    private class SlideMenuClickListener implements
            ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {
            // display view for selected nav drawer item
            displayView(position);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {


        getMenuInflater().inflate(R.menu.main, menu);


        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Fragment fragment = null;
        // toggle nav drawer on selecting action bar app icon/title
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle action bar actions click
        switch (item.getItemId()) {
            case R.id.action_settings:
                return true;
            case R.id.ofertasRefresh:
                return true;
            case R.id.menu_search:
                return true;
            case R.id.newOffer:
                getFragmentManager().beginTransaction().replace(R.id.frame_container, new TipusNouProducte()).commit();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    /* *
     * Called when invalidateOptionsMenu() is triggered
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // if nav drawer is opened, hide the action items
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
        if (mDrawerOpened) {
            menu.removeItem(R.id.ofertasRefresh);
            menu.removeItem(R.id.menu_search);
            menu.removeItem(R.id.newOffer);
        }
        if (!mDrawerOpened) {
            menu.add(Menu.NONE, R.id.ofertasRefresh, Menu.NONE, mTitle);
        }
        return super.onPrepareOptionsMenu(menu);

    }

    /**
     * Diplaying fragment view for selected nav drawer list item
     */
    private void displayView(int position) {
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
        Fragment fragment = null;

        switch (position) {
            case 0:
                fragment = new TabHostFragment();
                break;
            case 1:
                fragment = new RecomendacionesFragment();
                break;
            case 2:
                fragment = new LocalizacionFragment();
                break;
            case 3:
                fragment = new ListaProductosFragment();
                break;
            case 4:
                fragment = new ConfiguracionFragment();
                break;
            case 5:
                fragment = new AyudaSugerenciasFragment();
                break;
            case 6:
                fragment = new AyudaSugerencias();
                break;

            default:

                break;
        }


        if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.frame_container, fragment).commit(); /// here says that replace android.app.Fragment in FragmentTransaction cannot be applied...

            // update selected item and title, then close the drawer
            mDrawerList.setItemChecked(position, true);
            mDrawerList.setSelection(position);
            setTitle(navMenuTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);
        } else {
            // error in creating fragment
            Log.e("MainActivity", "Error in creating fragment");
        }
    }


    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getActionBar().setTitle(mTitle);

    }

    /**
     * When using the ActionBarDrawerToggle, you must call it during
     * onPostCreate() and onConfigurationChanged()...
     */

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggls
        mDrawerToggle.onConfigurationChanged(newConfig);
    }



}

完整的 LogCat 错误是:

  03-04 16:53:05.708    2232-2232/info.androidhive.slidingmenu E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: info.androidhive.slidingmenu, PID: 2232
java.lang.IllegalStateException: No tab known for tag null
        at android.support.v4.app.FragmentTabHost.doTabChanged(FragmentTabHost.java:330)
        at android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:280)
        at android.view.View.dispatchAttachedToWindow(View.java:13406)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2707)
        at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2714)
        at android.view.ViewGroup.addViewInner(ViewGroup.java:3919)
        at android.view.ViewGroup.addView(ViewGroup.java:3733)
        at android.view.ViewGroup.addView(ViewGroup.java:3678)
        at android.view.ViewGroup.addView(ViewGroup.java:3654)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:958)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:454)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

编辑

@Y.S.的答案与我所要求的有点不同,但这可能是一个解决方案,但它根本无法正常工作,并且NavigationDrawer位于TabHostFragment下,等等......我不想更改任何布局。

共有3个答案

池麒
2023-03-14

在.xml文件中指定使用此TabHostFragment的位置(完整路径,如com.my.TabHostFragment)。喜欢

 <com.my.TabHostFragment
        android:id="@+id/fragmentId"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         />
汪高岑
2023-03-14

这里还有另一种显示选项卡的方法。

像这样定义TabHostFraank

public class TabHostFragment extends Fragment implements ActionBar.TabListener{

    public TabHostFragment(){

    }

    AppSectionsPagerAdapter mAppSectionsPagerAdapter;
    ViewPager mViewPager;

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

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState){
        mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getChildFragmentManager());

        final ActionBar actionBar = ((FragmentActivity)getActivity()).getSupportActionBar();

        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        mViewPager = (ViewPager) view.findViewById(R.id.pager);
        mViewPager.setAdapter(mAppSectionsPagerAdapter);
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

        for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
            actionBar.addTab(
                actionBar.newTab()
                        .setText(mAppSectionsPagerAdapter.getPageTitle(i))
                        .setTabListener(this));
        }
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {

        public AppSectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int i) {
            Fragment f = null;
            switch (i) {
                case 0:
                    f = new MisOfertasFragment();
                    break;

                case 1:
                    f = new RecomendacionesFragment();
                    break;
            }

            return f;
        }

        @Override
        public int getCount() {
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return getFragmentTitle(position);
        }

        private String getFragmentTitle(int position){
            if(position == 0)
                return "Tab 1";
            else if(position == 1)
                return "Tab 2";
            else
                return "";
        }
    }
}

像这样定义tab_host_test2.xml

<android.support.v4.view.ViewPager 
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

代码的其余部分保持不变。

试试这个。这应该有效。

编辑:

将其添加到 displayView() 方法中:

if(position != 0)
    getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
宗政楚
2023-03-14

正如错误所示

Java:非法状态异常:没有标签空的已知选项卡

您试图初始化TabHost,但TabHost为空

尝试我用于初始化TabHost的代码,它工作正常。将您的代码保留在onCreateView()中。当您尝试在onViewCreated()中设置您的FragmentTabHost时会出现此问题,这是调用为时已晚。尝试在onCreateView()中设置它,并在返回视图Object之前添加至少一个选项卡。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {

    // Create FragmentTabHost
    mTabHost = new FragmentTabHost(getActivity());
    // Locate fragment1.xml to create FragmentTabHost
    mTabHost.setup(getActivity(), getChildFragmentManager(), R.layout.fragment1);
    mTabHost.addTab(mTabHost.newTabSpec("groups").setIndicator("",getResources().getDrawable(R.drawable.tab_group_icon)),FragmentTab1.class, null);
    mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("",getResources().getDrawable(R.drawable.tab_user_icon)),FragmentTab2.class, null);

    MainActivity.fabButton.setVisibility(View.VISIBLE);
    return mTabHost;
}

布局更改为:

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

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" />

    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

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

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

</LinearLayout>

希望有帮助。

 类似资料:
  • 悬而未决-詹金斯没有mypod标签 我指的是Kubernetes Jenkins插件--总是离线的从机来配置Jenkins系统。我发现这个问题被描述为一个缺陷,我不知道这是否更新到最新的詹金斯图像。以下是链接:https://github.com/jenkinsci/kubernetes-plugin/pull/127 下一个错误: 这会不会是因为400D1ED?那么KuberNetesDecla

  • 我正在尝试使用python管理运行appserver。py runserver与Python3.8。2和django 3.0。3.我已经建立了一个mysql数据库连接,并将我的“myApp.apps.myAppConfig”插入到已安装的应用程序中,声明了两个基于数据库视图的模型,一个表单和一个视图。对于我找到的教程来说,没有什么看起来太偏僻了。当我运行python Manager时。py run

  • 我有一个简单的Spring云配置服务器,它使用git服务器的配置。 ConfigServer引导。yml: 当我在本地部署ConfigServer时,我可以从http://localhost:8888/myapp/test 。但当我在测试服务器上部署ConfigServer时,当我点击

  • 问题内容: 我正在努力寻找一种方法来做到这一点。在父组件中,模板描述了及其元素,但将渲染委托给了另一个组件,如下所示: 每个myResult组件都呈现其自己的标签,基本上是这样的: 我之所以没有将其直接放在父组件中(避免需要使用myResult组件)是因为myResult组件实际上比此处显示的要复杂,因此我想将其行为放在单独的组件和文件中。 产生的DOM看起来很糟。我相信这是因为它无效,因为它只能

  • 我必须找出XPath的代码: 使用firebug,XPath是: /html/body/div/div/div[4]/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td /table/tbody/tr[5]/td/div/div/form/table/tbody/tr[2]/td[4]/输入 但我如何能有一个更短的XPath?例

  • 问题内容: 我的Maven有一个小问题。当我运行命令mvn package时,出现以下警告: [警告] JAR将为空-未标记任何内容! 生成成功,但是如警告所示,生成的jar文件为空。 为什么会这样,我在做什么错呢? 这是我的pom.xml 问题答案: 我希望您有充分的理由 不 遵循标准的目录布局,否则请考虑重新排列文件夹:这将使您的生活(以及您的同事)更加轻松。我的猜测是什么都没有被编译。在这种