问题
I have a weird issue with my Tab (TabHost or TabContent) in my Fragment that contains a ViewPager.
The problem is that when I change the page, then I turn back to the fragment with tab and viewPager, my content or view disappeared.


Here's my code for 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>
and here's 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);
}
}
Any help would be very appreciated.
回答1:
I had the same problem. In your TabFragment class (GameTabFragment) replace getFragmentManager with getChildFragmentManager.
Instead of: adapter = new TabPagerAdapter(this.getFragmentManager());
Use this: adapter = new TabPagerAdapter(this.getChildFragmentManager());
This should fix it.
回答2:
I have 3 tabs and experienced same issue. I used below code and problem fixed.
pager.setOffscreenPageLimit(2);
回答3:
In PagerFragment 's onResume() add this:
@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:
It may be too late, but I was stack with the same issue for hours even of all of the above answers, so I ended up making my own one which consists of:
Using
getChildFragmentManager()
to commit the firsttransaction
(the commit you usually do in the root Fragment which is one of yourviewpager
'stabs
)getFragmentManager()
to commit the rest of transactions (used to replace the nested fragments).
This might be an answer to this question IllegalArgumentException: No view found for id for fragment --- ViewPager in ViewPager too.
Hope this is going to help someone-else too!
来源:https://stackoverflow.com/questions/27142850/tab-content-disappeared-after-change-page