想要通过 FragmentTabHost 实现如下的 TAB 效果:
因 Fragment 会对于每一个 addTab 的 Fragment 进行绘制,且会捕捉 TAB 项的点击事件,因此参考 FragmentTabHost 新增了不绘制,不捕捉指定 tag 的 TAB 的点击事件的 TAB 列表,以及改写 doTabChange() 方法,如下代码:
public class MabFragmentTabHost 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 OnTabChangeListener mOnTabChangeListener;
private TabInfo mLastTab;
private boolean mAttached;
/**
* 存储不需要被 Attach 到 window 以及不响应TAB被点击事件
*/
private final ArrayList<String> mNoTabChangedTags = new ArrayList<String>();
public void addNoTabChangedTag(String tag)
{
mNoTabChangedTags.add(tag);
}
... ...
@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.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);
}
}
}
// We are now ready to go. Make sure we are switched to the
// correct tab.
mAttached = true;
// 在初始 attach 至 windows
ft = doTabChanged(currentTab, ft);
if (ft != null)
{
ft.commit();
mFragmentManager.executePendingTransactions();
}
}
@Override
public void onTabChanged(String tabId)
{
if (mAttached)
{
// 当 TAB 列表状态更新时回调
FragmentTransaction ft = doTabChanged(tabId, null);
if (ft != null)
{
ft.commit();
}
}
if (mOnTabChangeListener != null)
{
mOnTabChangeListener.onTabChanged(tabId);
}
}
...
private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
// if tag is no-tab-changed
// then return null
for (int idx = 0; idx < mNoTabChangedTags.size(); ++idx) {
if (mNoTabChangedTags.get(idx).equals(tabId)) {
return null;
}
}
TabInfo newTab = null;
for (int i=0; i<mTabs.size(); i++) {
TabInfo tab = mTabs.get(i);
if (tab.tag.equals(tabId)) {
newTab = tab;
}
}
... ...
return ft;
}
};
下面看一下在 MainActivity 中的实现:
public class MainActivity extends FragmentActivity {
private MabFragmentTabHost tabHost;
public static final String TAB_SPEC_TAB[] = {
"tab1", "tab2", "tab3", "tab4", "tab5"
};
public static final String KEY_TAB_IDX = "key-idx";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = (MabFragmentTabHost) findViewById(android.R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
View viewTab;
TextView tvTitle;
ImageView ivIcon;
for (int idx = 0; idx < 5; ++idx)
{
if (idx == 2)
{
// 中间 TAB(只是占了位)
viewTab = getLayoutInflater().inflate(R.layout.tab_icon, null);
tabHost.addTab(tabHost.newTabSpec(TAB_SPEC_TAB[idx])
.setIndicator(viewTab), NormalFragment.class, null);
// 将此 TAB 加入到 TabHost 的 no-tab-changed 列表
tabHost.addNoTabChangedTag(TAB_SPEC_TAB[idx]);
}
else
{
viewTab = getLayoutInflater().inflate(R.layout.tab_normal, null);
tvTitle = (TextView) viewTab.findViewById(android.R.id.title);
tvTitle.setText("Tab" + (idx+1));
ivIcon = (ImageView) viewTab.findViewById(android.R.id.icon);
ivIcon.setImageResource(android.R.drawable.ic_media_next);
Bundle args = new Bundle();
args.putInt(KEY_TAB_IDX, idx+1);
tabHost.addTab(tabHost.newTabSpec(TAB_SPEC_TAB[idx])
.setIndicator(viewTab), NormalFragment.class, args);
}
}
// 中间按键图片触发
ImageView ivAdd = (ImageView) findViewById(R.id.add_iv);
ivAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "click icon", Toast.LENGTH_SHORT).show();
}
});
}
}
下面为 activity_main.xml 布局文件
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/realtabcontent" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1"/> <com.test.demo.fragtabdemo.MabFragmentTabHost android:id="@android:id/tabhost" android:layout_gravity="bottom" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TabWidget android:id="@android:id/tabs" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="@dimen/DefaultTabWidgetTextHeight" android:divider="@null" android:layout_weight="0"/> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dip" android:layout_height="0dip" android:layout_weight="0"/> </LinearLayout> </com.test.demo.fragtabdemo.MabFragmentTabHost> </LinearLayout> <ImageView android:layout_height="64.0dip" android:layout_width="wrap_content" android:layout_gravity="bottom|center_horizontal" android:id="@+id/add_iv" android:src="@drawable/ic_add"/> </FrameLayout>
转载于:https://blog.51cto.com/quietmadman/1272548