FragmentTabHost使用遇到的问题

本文记录一下在使用fragmentTabHost的时候所遇到的问题。

fragment的重新建立的原因

原生的fragmenttabhost在切换tab的时候,会导致fragment的重新建立

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
.......省略部分代码
if (mLastTab != newTab) {
if (ft == null) {
ft = mFragmentManager.beginTransaction();
}
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(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);
}
}
mLastTab = newTab;
}
return ft;
}

很清楚的看到在切换的时候上个fragment调用detach,新的fragment调用的是attach,所以会导致重新初始化。

解决办法

就是把源码复杂一份,修改这个部分代码就可以解决了。

1
2
3
4
5
6
7
8
9
10
11
12
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.hide(mLastTab.fragment); //detach改为hide
}
}
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(mContext,
newTab.clss.getName(), newTab.args);
ft.add(mContainerId, newTab.fragment, newTab.tag);
} else {
ft.show(newTab.fragment); //attach改为show
}

要求是当点击其中一个tab的时候不导致fragment的切换,而是做一些其他的操作

解决办法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class NoTabFragmentTabHost extends FragmentTabHost {
private String mCurrentTag;
private String mNoTabChangedTag;
public NoTabFragmentTabHost(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onTabChanged(String tag) {
if (tag.equals(mNoTabChangedTag)) {
setCurrentTabByTag(mCurrentTag);
} else {
super.onTabChanged(tag);
mCurrentTag = tag;
}
}
public void setNoTabChangedTag(String tag) {
this.mNoTabChangedTag = tag;
}
}

app当再次点击当前tab的时候会去刷新操作

1
mTabHost.getTabWidget().getChildAt(i).setOnTouchListener(this);

给每个的tabwidget的子view设置监听事件,再onTouch的处理

1
2
3
4
5
6
7
8
9
boolean consumed = false;
if (event.getAction() == MotionEvent.ACTION_DOWN
&& v.equals(mTabHost.getCurrentTabView())) {
Log.d("再次点击了", "再次点击了");
consumed = true;
}
}
return consumed;

在这里你就可以获取当前的fragment再处理逻辑了。