重写TabHost。原因:重启打开过的页面时,代码中设置的ui界面会混乱,重写后使用show和hide来显示或隐藏界面
public class MyFragmentTabHost extends TabHost implements TabHost.OnTabChangeListener
{
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private FrameLayout mRealTabContent;
private Context mContext;
private FragmentManager mFragmentManager;
private int mContainerId;
private TabHost.OnTabChangeListener mOnTabChangeListener;
private TabInfo mLastTab;
private boolean mAttached;
public boolean changeFragment = true;
static final class TabInfo
{
private final String tag;
private final Class<?> clss;
private final Bundle args;
protected Fragment fragment;
TabInfo(String _tag, Class<?> _class, Bundle _args)
{
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory
{
private final Context mContext;
public DummyTabFactory(Context context)
{
mContext = context;
}
@Override
public View createTabContent(String tag)
{
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
static class SavedState extends BaseSavedState
{
String curTab;
SavedState(Parcelable superState)
{
super(superState);
}
private SavedState(Parcel in)
{
super(in);
curTab = in.readString();
}
@Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeString(curTab);
}
@Override
public String toString()
{
return "FragmentTabHost.SavedState{"
+ Integer.toHexString(System.identityHashCode(this))
+ " curTab=" + curTab + "}";
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>()
{
public SavedState createFromParcel(Parcel in)
{
return new SavedState(in);
}
public SavedState[] newArray(int size)
{
return new SavedState[size];
}
};
}
public MyFragmentTabHost(Context context)
{
// Note that we call through to the version that takes an AttributeSet,
// because the simple Context construct can result in a broken object!
super(context, null);
initFragmentTabHost(context, null);
}
public MyFragmentTabHost(Context context, AttributeSet attrs)
{
super(context, attrs);
initFragmentTabHost(context, attrs);
}
private void initFragmentTabHost(Context context, AttributeSet attrs)
{
TypedArray a = context.obtainStyledAttributes(attrs,
new int[]{android.R.attr.inflatedId}, 0, 0);
mContainerId = a.getResourceId(0, 0);
a.recycle();
super.setOnTabChangedListener(this);
}
private void ensureHierarchy(Context context)
{
// If owner hasn't made its own view hierarchy, then as a convenience
// we will construct a standard one here.
if (findViewById(android.R.id.tabs) == null)
{
LinearLayout ll = new LinearLayout(context);
ll.setOrientation(LinearLayout.VERTICAL);
addView(ll, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
TabWidget tw = new TabWidget(context);
tw.setId(android.R.id.tabs);
tw.setOrientation(TabWidget.HORIZONTAL);
ll.addView(tw, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0));
FrameLayout fl = new FrameLayout(context);
fl.setId(android.R.id.tabcontent);
ll.addView(fl, new LinearLayout.LayoutParams(0, 0, 0));
mRealTabContent = fl = new FrameLayout(context);
mRealTabContent.setId(mContainerId);
ll.addView(fl, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, 0, 1));
}
}
/**
* @deprecated Don't call the original TabHost setup, you must instead call
* {@link #setup(Context, FragmentManager)} or
* {@link #setup(Context, FragmentManager, int)}.
*/
@Override
@Deprecated
public void setup()
{
throw new IllegalStateException(
"Must call setup() that takes a Context and FragmentManager");
}
public void setup(Context context, FragmentManager manager)
{
ensureHierarchy(context); // Ensure views required by super.setup()
super.setup();
mContext = context;
mFragmentManager = manager;
ensureContent();
}
public void setup(Context context, FragmentManager manager, int containerId)
{
ensureHierarchy(context); // Ensure views required by super.setup()
super.setup();
mContext = context;
mFragmentManager = manager;
mContainerId = containerId;
ensureContent();
mRealTabContent.setId(containerId);
// We must have an ID to be able to save/restore our state. If
// the owner hasn't set one at this point, we will set it ourself.
if (getId() == View.NO_ID)
{
setId(android.R.id.tabhost);
}
}
private void ensureContent()
{
if (mRealTabContent == null)
{
mRealTabContent = (FrameLayout) findViewById(mContainerId);
if (mRealTabContent == null)
{
throw new IllegalStateException(
"No tab content FrameLayout found for id "
+ mContainerId);
}
}
}
@Override
public void setOnTabChangedListener(OnTabChangeListener l)
{
mOnTabChangeListener = l;
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args)
{
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
if (mAttached)
{
// If we are already attached to the window, then check to make
// sure this tab's fragment is inactive if it exists. This shouldn't
// normally happen.
info.fragment = mFragmentManager.findFragmentByTag(tag);
if (info.fragment != null && !info.fragment.isDetached())
{
FragmentTransaction ft = mFragmentManager.beginTransaction();
// ft.detach(info.fragment);
ft.hide(info.fragment);
ft.commit();
}
}
mTabs.add(info);
addTab(tabSpec);
}
@Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow();
String currentTab = getCurrentTabTag();
// Go through all tabs and make sure their fragments match
// the correct state.
FragmentTransaction ft = null;
for (int i = 0; i < mTabs.size(); i++)
{
TabInfo tab = mTabs.get(i);
tab.fragment = mFragmentManager.findFragmentByTag(tab.tag);
// if (tab.fragment != null && !tab.fragment.isDetached()) {
if (tab.fragment != null)
{
if (tab.tag.equals(currentTab))
{
// The fragment for this tab is already there and
// active, and it is what we really want to have
// as the current tab. Nothing to do.
mLastTab = tab;
} else
{
// This fragment was restored in the active state,
// but is not the current tab. Deactivate it.
if (ft == null)
{
ft = mFragmentManager.beginTransaction();
}
// ft.detach(tab.fragment);
ft.hide(tab.fragment);
}
}
}
// We are now ready to go. Make sure we are switched to the
// correct tab.
mAttached = true;
ft = doTabChanged(currentTab, ft);
if (ft != null)
{
ft.commit();
mFragmentManager.executePendingTransactions();
}
}
@Override
protected void onDetachedFromWindow()
{
super.onDetachedFromWindow();
mAttached = false;
}
@Override
protected Parcelable onSaveInstanceState()
{
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.curTab = getCurrentTabTag();
return ss;
}
@Override
protected void onRestoreInstanceState(Parcelable state)
{
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setCurrentTabByTag(ss.curTab);
}
@Override
public void onTabChanged(String tabId)
{
if (mOnTabChangeListener != null)
{
mOnTabChangeListener.onTabChanged(tabId);
}
if (mAttached && changeFragment)
{
FragmentTransaction ft = doTabChanged(tabId, null);
if (ft != null)
{
ft.commit();
}
}
}
private FragmentTransaction doTabChanged(String tabId,
FragmentTransaction ft)
{
TabInfo newTab = null;
for (int i = 0; i < mTabs.size(); i++)
{
TabInfo tab = mTabs.get(i);
if (tab.tag.equals(tabId))
{
newTab = tab;
}
}
if (newTab == null)
{
throw new IllegalStateException("No tab known for tag " + tabId);
}
if (mLastTab != newTab)
{
if (ft == null)
{
ft = mFragmentManager.beginTransaction();
}
if (mLastTab != null)
{
if (mLastTab.fragment != null)
{
// ft.detach(mLastTab.fragment);
ft.hide(mLastTab.fragment);
}
}
if (newTab != null)
{
if (newTab.fragment == null)
{
newTab.fragment = Fragment.instantiate(mContext,
newTab.clss.getName(), newTab.args);
ft.add(mContainerId, newTab.fragment, newTab.tag);
} else
{
// ft.attach(newTab.fragment);
ft.show(newTab.fragment);
}
}
mLastTab = newTab;
}
return ft;
}
}
XML中(只用修改包名,android:id不需要修改)
<包名.MyFragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<!--<View-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="4dp"-->
<!--android:background="@drawable/bg_shadow"/>-->
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@color/white"
android:paddingTop="10dp"
android:translationY="3dp"/>
</LinearLayout>
</包名.MyFragmentTabHost>
主程序中
public class MainActivity extends BaseActivity
{
@BindView(android.R.id.tabhost)
MyFragmentTabHost mTabHost;
// 标题
private String mFragmentTags[] = {
"标题一", "标题二", "标题三", "标题四"
};
// 未点击图片
@DrawableRes
private int mImages[] = {
R.mipmap.ic_main56,
R.mipmap.ic_main59,
R.mipmap.ic_main62,
R.mipmap.ic_main65
};
//点击图片
@DrawableRes
private int selectImages[] = {
R.mipmap.ic_zuanz03,
R.mipmap.ic_zuanz05,
R.mipmap.ic_zuanz07,
R.mipmap.ic_zuanz09
};
private Class[] fragments = {Fragment1.class, Fragment2.class, Fragment3.class, Fragment4.class};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
StatusBarCompat.compat(this);
initTab();
selectTab(mFragmentTags[0]);
}
@Override
protected void onResume()
{
super.onResume();
checkTab();
}
public void checkTab()
{
if (TextUtils.isEmpty(Constant.MAIN_TAB_ID))
mTabHost.onTabChanged(mFragmentTags[0]);
else
mTabHost.onTabChanged(Constant.MAIN_TAB_ID);
}
private void initTab()
{
mTabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
mTabHost.getTabWidget().setDividerDrawable(null); // 去掉分割线
for (int i = 0; i < 4; i++)
{
// Tab按钮添加文字和图片
TabHost.TabSpec tabSpec = mTabHost.newTabSpec(mFragmentTags[i]).setIndicator(getView(i));
// 添加Fragment
mTabHost.addTab(tabSpec, fragments[i], null);
// 设置Tab按钮的背景
// mTabHost.getTabWidget().getChildAt(i).findViewById(R.id.iv_tab);
final int finalI = i;
mTabHost.getTabWidget().getChildAt(i).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
mTabHost.onTabChanged(mFragmentTags[finalI]);
}
});
}
mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener()
{
@Override
public void onTabChanged(String tabId)
{
Log.i("点击", tabId);
Constant.MAIN_TAB_ID = tabId;
if (tabId.equals(mFragmentTags[0]))
{
selectTab(tabId);
} else
{
if (SPUtil.getLoginData(mBaseActivity).user_id == 0)
{
mTabHost.changeFragment = false;
startActivity(new Intent(mBaseActivity, LoginActivity.class));
} else
{
selectTab(tabId);
}
}
}
});
}
// 获得图片资源
private View getImageView(int index)
{
@SuppressLint("InflateParams")
View view = getLayoutInflater().inflate(R.layout.layout_tab, null);
ImageView imageView = (ImageView) view.findViewById(R.id.iv_tab);
imageView.setImageResource(mImages[index]);
TextView textView = (TextView) view.findViewById(R.id.tv_tab);
textView.setText(mFragmentTags[index]);
return view;
}
private void selectTab(String tabId)
{
mTabHost.changeFragment = true;
for (int i = 0; i < mFragmentTags.length; i++)
{
View mView = mTabHost.getTabWidget().getChildAt(i);//0是代表第一个Tab
ImageView imageView = (ImageView) mView.findViewById(R.id.iv_tab);//获取控件imageView
TextView textView = (TextView) mView.findViewById(R.id.tv_tab);
if (tabId.equals(mFragmentTags[i]))
{
imageView.setImageResource(selectImages[i]);
textView.setTextColor(getResources().getColor(R.color.bule));
} else
{
imageView.setImageResource(mImages[i]);
textView.setTextColor(getResources().getColor(R.color.home_txt2));
}
}
}
private long firstTime = 0;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN)
{
if (System.currentTimeMillis() - firstTime > 2000)
{
Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
firstTime = System.currentTimeMillis();
} else
{
finish();
System.exit(0);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}