Android - FragmentTabHost
|
FragmentTabHost可实现类似IOS中的UITabBarController的功能,FramentTabHost实现效果与UITabBarController一样,但是前者比较麻烦,而且注意事项也很多,不过只要用过一两次,基本也就掌握了,2年多没开发Android应用了,Eclipse早已远去,接下来我将详细记录基于Android Studio使用FramentTabHost的过程。
主要分两部分:tabhost(底部菜单)、tabcontent(页面内容)
一、Item的信息:TabItem.java
public enum TabItem {
HOME(
0, R.string.
main_tab_name_shouyw, R.drawable.
tabbar_selector_home,
HomeFragment. class), ACTIVITY( 1, R.string. main_tab_name_huodong, R.drawable. tabbar_selector_activity, ActivityFragment. class), MINE( 2, R.string. main_tab_name_wode, R.drawable. tabbar_selector_mine, HomeFragment. class);
private int
idx;
private int resName; private int resIcon; private Class<?> clz; private TabItem( int idx, int resName, int resIcon, Class<?> clz) { this. idx = idx; this. resName = resName; this. resIcon = resIcon; this. clz = clz; } public int getIdx() { return idx; } public void setIdx( int idx) { this. idx = idx; } public int getResName() { return resName; } public void setResName( int resName) { this. resName = resName; } public int getResIcon() { return resIcon; } public void setResIcon( int resIcon) { this. resIcon = resIcon; } public Class<?> getClz() { return clz; } public void setClz(Class<?> clz) { this. clz = clz; } } |
二、item的布局文件:tabitem_layout.xml
<?
xml version=
"1.0"
encoding=
"utf-8"
?>
< LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" android :layout_width= "match_parent" android :layout_height= "match_parent" android :orientation= "vertical" android :id= "@+id/id_fragment_item_layout"> < ImageView android :id= "@+id/iv_icon" android :layout_marginTop= "6dp" android :layout_width= "match_parent" android :layout_height= "36dp" android :layout_centerHorizontal= "true" android :background= "@color/CDCOR_Clear" /> < TextView android :id= "@+id/tab_title" android :layout_below= "@id/iv_icon" android :layout_width= "match_parent" android :layout_height= "wrap_content" android :layout_centerHorizontal= "true" android :textAlignment= "center" android :textColor= "@color/tab_titletext_selector" android :textSize= "13sp" />
</LinearLayout>
|
三、需要创建一个Activity(TabbarActivity),这个Activity的布局文件中用于放置FragmentTabHost
/**
* Created by luohan on 16/7/10. */ public class TabBarActivity extends AppCompatActivity implements View.OnTouchListener,TabHost.OnTabChangeListener {
private MyFragmentTabHost mTabHost;
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. tabbar_activity);
initViews();
}
private void initViews() { mTabHost = (MyFragmentTabHost) findViewById(android. R.id. tabhost); mTabHost.setup( this, getSupportFragmentManager(), android.R.id. tabcontent); mTabHost.setOnTabChangedListener( this); // mTabHost.getTabWidget().setDividerDrawable(null); // 去掉分割线
TabItem[] tabs = TabItem.
values();
int size = tabs. length; for ( int i = 0; i < mImages. length; i++) { TabItem mainTab = tabs[i]; WindowManager wm = (WindowManager) this.getSystemService(Context. WINDOW_SERVICE); int swidth = wm.getDefaultDisplay().getWidth(); // Tab按钮添加文字和图片 View indicator = View. inflate( this, R.layout. tabitem_layout, null); TextView title = (TextView) indicator.findViewById(R.id. tab_title); ImageView icon = (ImageView) indicator.findViewById(R.id. iv_icon); title.setText(getString(mainTab.getResName())); Drawable drawable = this.getResources().getDrawable(mainTab.getResIcon()); icon.setImageDrawable(drawable); TabHost.TabSpec spec = mTabHost.newTabSpec( mFragmentTags[i]); spec.setIndicator(indicator); spec.setContent( new TabHost.TabContentFactory() { @Override public View createTabContent(String tag) { return new View(TabBarActivity. this); } }); // 添加Fragment mTabHost.addTab(spec, mainTab.getClz(), null); // 设置Tab按钮的背景 mTabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.color. CDCOR_FFFFFF); mTabHost.getTabWidget().getChildAt(i).setOnTouchListener( this); }
}
@Override public void onTabChanged(String tabId) { final int size = mTabHost.getTabWidget().getTabCount(); for ( int i = 0; i < size; i++) { View v = mTabHost.getTabWidget().getChildAt(i); if (i == mTabHost.getCurrentTab()) { v.setSelected( true); } else { v.setSelected( false); } } supportInvalidateOptionsMenu(); }
@Override
public boolean onTouch(View view, MotionEvent motionEvent) { return false;
}
}
|
四、TabBarActivity对应的布局文件:(红色部分必须使用android提供的标准id)
tabcontent:页面内容显示区域,使用Frament填充
tabhost:底部菜单区域,使用上面的tabitem_layout.xml布局文件填充,布局文件的相关资源来源于TabItem.java
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
< android.support.v4.widget.DrawerLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http://schemas.android.com/tools" android :id= "@+id/id_drawer_layout" android :layout_width= "match_parent"
android:layout_height="match_parent"
tools
:context=
"com.example.luohan.a_app01.TabBarActivity”
>
< 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= "0dip" android :layout_weight= "1" /> < FrameLayout android :layout_width= "match_parent" android :layout_height= "wrap_content" android :background= "@color/CDCOR_Clear"> < com.example.luohan.a_app01.widget.MyFragmentTabHost android :id= "@android:id/tabhost" android :layout_width= "match_parent" android :layout_height= "wrap_content" android :layout_gravity= "center_vertical" /> < View android :layout_width= "match_parent" android :layout_height= "1px" android :background= "@color/DCOR_GRAY_bcbcbc" /> </ FrameLayout> </ LinearLayout>
</android.support.v4.widget.DrawerLayout>
|
五、分别创建三个界面的显示内容:Frament(另外两个界面省略)
public class HomeFragment
extends Fragment {
private View mViewContent; // 缓存视图内容 @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout. fragment_home, container, false);
}
}
|
六、MyFragmentTabHost
public class MyFragmentTabHost
extends FragmentTabHost {
private String mCurrentTag;
private String
mNoTabChangedTag;
public MyFragmentTabHost(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; }
}
|
其他资源文件:
tabbar_selector_home.xml(另外两个省略)
<?
xml version=
"1.0"
encoding=
"utf-8"
?>
< selector xmlns: android = "http://schemas.android.com/apk/res/android"> < item android :state_pressed= "true" android :drawable= "@mipmap/tab_home_selected" /> < item android :state_checked= "true" android :drawable= "@mipmap/tab_home_selected" /> < item android :state_selected= "true" android :drawable= "@mipmap/tab_home_selected" /> < item android :drawable= "@mipmap/tab_home_default" />
</selector>
|
tab_titletext_selector.xml
<?
xml version=
"1.0"
encoding=
"utf-8"
?> < selector xmlns: android = "http://schemas.android.com/apk/res/android"> < item android :state_pressed= "true" android :color= "@color/DCOR_RED_fd7778"/> < item android :state_selected= "true" android :color= "@color/DCOR_RED_fd7778"/> < item android :color= "@color/DCOR_GRAY_787878"/> </ selector> |