【问题标题】:Tab content disappeared after change page切换页面后标签内容消失
【发布时间】:2015-01-24 09:49:03
【问题描述】:

我在包含 ViewPager 的片段中的选项卡(TabHost 或 TabContent)有一个奇怪的问题。

问题是,当我更改页面时,然后我转回带有 tab 和 viewPager 的片段,我的内容或视图消失了。

->

这是我的 TabFragment

代码
package com.halo.mobi.fragment;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabContentFactory;
import android.widget.TabWidget;
import android.widget.TextView;
import com.halo.mobi.R;

public class GameTabFragment extends Fragment {
    Activity myActivity;

    TabWidget tab;
    TabHost tabHost;
    ViewPager pager;
    HorizontalScrollView hsvTab;

    List<String> headers;

    TabPagerAdapter adapter;
    TabContentFactory fac;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        myActivity = this.getActivity();
    }

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

        headers = new ArrayList<String>();

        tabHost = (TabHost) rootView.findViewById(R.id.tabHost);
        pager = (ViewPager) rootView.findViewById(R.id.pager);
        hsvTab = (HorizontalScrollView) rootView.findViewById(R.id.hsvTab);
        hsvTab.setHorizontalScrollBarEnabled(false);

        tabHost.setup();
        fac = new TabContentFactory() {

            @Override
            public View createTabContent(String tag) {
                // TODO Auto-generated method stub
                return new View(myActivity);
            }
        };
        tabHost.addTab(tabHost.newTabSpec("cat")
                .setIndicator(getTabIndicator(myActivity, "CATEGORIES"))
                .setContent(fac));
        tabHost.addTab(tabHost.newTabSpec("new")
                .setIndicator(getTabIndicator(myActivity, "NEW RELEASE"))
                .setContent(fac));
        tabHost.addTab(tabHost.newTabSpec("free")
                .setIndicator(getTabIndicator(myActivity, "TOP FREE"))
                .setContent(fac));
        tabHost.addTab(tabHost.newTabSpec("paid")
                .setIndicator(getTabIndicator(myActivity, "TOP PAID"))
                .setContent(fac));
        tabHost.getTabWidget().setBackgroundColor(
                getResources().getColor(R.color.merah));

        tabHost.setOnTabChangedListener(new OnTabChangeListener() {

            @Override
            public void onTabChanged(String tabId) {
                // TODO Auto-generated method stub
                pager.setCurrentItem(tabHost.getCurrentTab());
                hsvTab.smoothScrollTo(
                        tabHost.getTabWidget()
                                .getChildTabViewAt(tabHost.getCurrentTab())
                                .getLeft(), 0);
            }
        });

        adapter = new TabPagerAdapter(this.getFragmentManager());
        pager.setAdapter(adapter);
        pager.setOffscreenPageLimit(5);
        pager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {
                // TODO Auto-generated method stub
                tabHost.setCurrentTab(arg0);
            }
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub
            }
        });

        return rootView;
    }
    private View getTabIndicator(Context context, String title) {
        View view = LayoutInflater.from(context).inflate(
                R.layout.gametablayout, null);
        TextView tv = (TextView) view.findViewById(R.id.txtTitle);
        tv.setText(title);
        tv.setSingleLine();
        view.setPadding(2, 0, 2, 0);
        return view;
    }
    private class TabPagerAdapter extends FragmentPagerAdapter {
        GameCategoryFragment cat;
        GameNewReleaseFragment newrelease;
        GameTopFreeFragment topfree;
        GameTopPaidFragment toppaid;

        public TabPagerAdapter(FragmentManager fm) {
            super(fm);

            cat = new GameCategoryFragment();
            newrelease = new GameNewReleaseFragment();
            topfree = new GameTopFreeFragment();
            toppaid = new GameTopPaidFragment();
            // TODO Auto-generated constructor stub
        }

        @Override
        public Fragment getItem(int pos) {
            // TODO Auto-generated method stub
            if (pos == 0)
                return cat;
            if (pos == 1)
                return newrelease;
            if (pos == 2)
                return topfree;
            if (pos == 3)
                return toppaid;
            return cat;

        }
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return 4;
        }
    }
}

game_list_tab_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="top|left"
        android:orientation="vertical" >

        <TabHost
            android:id="@+id/tabHost"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

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

                <HorizontalScrollView
                    android:id="@+id/hsvTab"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@color/merah" >

                    <TabWidget
                        android:id="@android:id/tabs"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" >
                    </TabWidget>
                </HorizontalScrollView>

                <FrameLayout
                    android:id="@android:id/tabcontent"
                    android:layout_width="match_parent"
                    android:layout_height="0px"
                    android:orientation="vertical" >
                </FrameLayout>

                <android.support.v4.view.ViewPager
                    android:id="@+id/pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
            </LinearLayout>
        </TabHost>
    </LinearLayout>
</FrameLayout>

这里是 MainActivity.java

package com.halo.mobi.activity;

import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.LayoutParams;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

import com.halo.mobi.R;
import com.halo.mobi.fragment.GameDetailFragment;
import com.halo.mobi.fragment.GameTabFragment;
import com.halo.mobi.fragment.HomeFragment;
import com.halo.mobi.fragment.NavigationDrawerFragment;

public class MainActivity extends ActionBarActivity implements
        NavigationDrawerFragment.NavigationDrawerCallbacks {

    /**
     * Fragment managing the behaviors, interactions and presentation of the
     * navigation drawer.
     */
    private NavigationDrawerFragment mNavigationDrawerFragment;

    private DrawerLayout drawerLayout;
    /**
     * Used to store the last screen title. For use in
     * {@link #restoreActionBar()}.
     */
    private int pos;
    FragmentManager fragmentManager;

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

        mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager()
                .findFragmentById(R.id.navigation_drawer);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        // Set up the drawer.
        mNavigationDrawerFragment.setUp(R.id.navigation_drawer, drawerLayout);
    }

    @Override
    public void onNavigationDrawerItemSelected(int position) {
        // update the main content by replacing fragments

        fragmentManager = getSupportFragmentManager();

        switch (position) {
        case 0:
            fragmentManager.beginTransaction()
                    .replace(R.id.container, new HomeFragment())
                    .addToBackStack("TAG_FRAGMENT").commit();
            break;
        case 1:

            fragmentManager.beginTransaction()
                    .replace(R.id.container, new GameTabFragment())
                    .addToBackStack("TAG_FRAGMENT").commit();
            break;
        default:
            fragmentManager.beginTransaction()
                    .replace(R.id.container, new HomeFragment())
                    .addToBackStack("TAG_FRAGMENT").commit();
            break;
        }
    }

    public void onSectionAttached(int number, int gameId) {
        pos = number;
        if (gameId != 0) {
            fragmentManager = getSupportFragmentManager();
            fragmentManager
                    .beginTransaction()
                    .replace(R.id.container,
                            GameDetailFragment.newInstance(number, gameId))
                    // .addToBackStack("TAG_FRAGMENT")
                    .commit();
        }
    }

    @Override
    public void onBackPressed() {
        // TODO Auto-generated method stub
        if (pos == 0) {
            finish();
        } else {
            onNavigationDrawerItemSelected(pos);
        }
    }

    public void restoreActionBar() {
        ActionBar mActionBar = getSupportActionBar();
        mActionBar.setDisplayShowHomeEnabled(false);
        mActionBar.setDisplayShowTitleEnabled(false);
        LayoutInflater mInflater = LayoutInflater.from(this);

        View mCustomView = mInflater.inflate(R.layout.custom_actionbar, null);

        ImageView imageButton = (ImageView) mCustomView
                .findViewById(R.id.btnMenu);
        imageButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {
                mNavigationDrawerFragment.openDrawer();
            }
        });

        mActionBar.setCustomView(mCustomView, new LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
        mActionBar.setDisplayShowCustomEnabled(true);
    }
}

任何帮助将不胜感激。

【问题讨论】:

  • 使用getChildFragmentManager() 而不是getSupportFragmentManager()
  • @Yugesh:我应该把它放在哪里?因为我无法放入 onNavigationDrawerItemSelected,我收到这样的警告“方法 getChildFragmentManager() 未定义 MainActivity 类型”
  • 可以加MainActivity代码吗?
  • @Yugesh:我已经添加了我的MainActivity,希望你能给我启发
  • 感谢您的代码,它对我帮助很大,thaku huni 的回答解决了内容被删除的问题。 “我遇到了同样的问题。在您的 TabFragment 类 (GameTabFragment) 中,将 getFragmentManager 替换为 getChildFragmentManager。而不是:adapter = new TabPagerAdapter(this.getFragmentManager()); 使用这个:adapter = new TabPagerAdapter(this.getChildFragmentManager()); 这个应该修复它。”

标签: android android-fragments fragment android-tabhost


【解决方案1】:

我遇到了同样的问题。在您的 TabFragment 类 (GameTabFragment) 中,将 getFragmentManager 替换为 getChildFragmentManager。

而不是: 适配器 = 新 TabPagerAdapter(this.getFragmentManager());

使用这个: 适配器 = new TabPagerAdapter(this.getChildFragmentManager());

这应该可以解决它。

【讨论】:

  • 谢谢,真的很管用!如果你能解释为什么会这样,那就完美了)
  • 真的非常感谢您。这个解决方案在浪费了这么多工时后奏效了..
【解决方案2】:

我有 3 个标签并且遇到了同样的问题。我使用下面的代码并修复了问题。

pager.setOffscreenPageLimit(2);

【讨论】:

    【解决方案3】:

    在 PagerFragment 的 onResume() 中添加:

    @Override
    public void onResume() {
        super.onResume();
    
        for (Fragment fragment : getFragmentManager().getFragments()) {
            if (fragment instanceof Tab1Fragment || fragment instanceof Tab2Fragment) {
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                ft.detach(fragment);
                ft.attach(fragment);
                ft.commit();
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      可能为时已晚,但即使是上述所有答案,我也被同一个问题困扰了好几个小时,所以我最终制作了自己的一个,其中包括:

      使用

      • getChildFragmentManager() 提交 first transaction(您通常在 root Fragment 中执行的提交,这是您的 viewpagertabs 之一)李>
      • getFragmentManager() 提交其余事务(用于 替换嵌套的片段)。

      这也可能是IllegalArgumentException: No view found for id for fragment --- ViewPager in ViewPager这个问题的答案。

      希望这对其他人也有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-02
        • 1970-01-01
        • 2017-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多