不得不说的是,TabHost是一个很老的控件了,网上的教程也有很多,而且是谷歌已经把这个控件废弃了o(╯□╰)o
不过,在群里经常能看到有些人再问一些TabHost的问题,而且感觉很生疏的样子。
好吧,今天就来一个“终极教程”吧,\(^o^)/~只是交流而已啦
我们先从最基础的来
1、最基础的TabHost
1)首先是一个layout(布局)
<TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0.0" /> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1.0" android:gravity="center" /> </LinearLayout> </TabHost>
2)然后是一个activity,这个activity要继承TabActivity,获取TabHost,然后添加子Activity
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTabHost = (TabHost) findViewById(android.R.id.tabhost); //first Intent intent = new Intent(getApplicationContext(),FirstActivity.class); TabHost.TabSpec localTabSpec = mTabHost.newTabSpec("0") .setIndicator("First").setContent(intent); mTabHost.addTab(localTabSpec); //second intent = new Intent(getApplicationContext(),SecondActivity.class); localTabSpec = mTabHost.newTabSpec("1") .setIndicator("Second").setContent(intent); mTabHost.addTab(localTabSpec); //third intent = new Intent(getApplicationContext(),ThirdActivity.class); localTabSpec = mTabHost.newTabSpec("2") .setIndicator("Third").setContent(intent); mTabHost.addTab(localTabSpec); }FirstActivity、SecondActivity、ThirdActivity为子activity,可以随意创建
到此,一个TabHost就可以显示出来了,简单吧
注意:
1)activity要在androidmanifest里加声明
2)主activity要继承TabActivity
3)setIndecator为显示的内容,newTabSpec可理解为一个tag,给控件打个标签
在androidmanifest里修改application的theme可以改变不同版本的显示样式
这个api11之前的效果
android:theme="@android:style/Theme.Light.NoTitleBar"
这个是api11之后的效果
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
差别还是蛮多的,之后的版本漂亮多了
2、带有图片及标题的TabHost
1)还有个setIndicator(CharSequence label, Drawable icon)方法,第二个传个drawable图片就可以了
//first Intent intent = new Intent(getApplicationContext(),FirstActivity.class); Drawable drawable = getResources().getDrawable(R.drawable.ic_menu_user_off); TabHost.TabSpec localTabSpec = mTabHost.newTabSpec("0") .setIndicator("first",drawable).setContent(intent); mTabHost.addTab(localTabSpec);效果如下
api11之后用这个方法,传个图片也不会显示了,文字会居中显示
3、自定义选项TabHost
用自带的,你会发现tab底部有一条东西,是去不掉的,而且也不怎么好看
1)我们看api的时候,可以发现还有个setIndicator(View view),顾名思义,我们是可以传一个自定义的view过去的,好的,那我们就自定义一个view
private View createTabView(int res, String text) { View view = LayoutInflater.from(this).inflate(R.layout.main_tab_indicator,null); ImageView img = (ImageView) view.findViewById(R.id.main_tab_img); TextView tv = (TextView) view.findViewById(R.id.main_tab_txt); img.setImageResource(res); tv.setText(text); return view; }效果如下
这时,我们会发现选中和常态是一样的,区分不出来。也许你会说,用布局写一个drawable,选中不就改变图片了嘛
可是这样是不行的,会报错,文字的话是可以的,选中是可以改变颜色的
那我们就要转变思路,用别的方法进行实现
O(∩_∩)O哈哈~我们可以将主activity实现onTabChanged接口,这样我们监听到了tab的状态,就可以做一些事情了
public void onTabChanged(String tabId) { int item = Integer.valueOf(tabId); for (int i = 0; i < mTabWidget.getChildCount(); i++) { int res = i == item ? R.drawable.com_tenpay_keyitem_bottom_high : R.drawable.com_tenpay_keyitem_bottom; mTabWidget.getChildAt(i).setBackgroundResource(res); } }
其中mTabWight是这个控件
mTabWidget = (TabWidget)findViewById(android.R.id.tabs);这时我们就会发现,tab背景色是可以随着tab的改变而改变的,而前景色是不变的
要修改前景色,我们可以这样做
public void onTabChanged(String tabId) { int item = Integer.valueOf(tabId); for (int i = 0; i < mTabWidget.getChildCount(); i++) { int res = i == item ? R.drawable.com_tenpay_keyitem_bottom_high : R.drawable.com_tenpay_keyitem_bottom; LinearLayout view = (LinearLayout)mTabWidget.getChildAt(i); view.setBackgroundResource(res); int fRes = i == item ? R.drawable.ic_menu_deal_on :R.drawable.ic_menu_deal_off; ImageView imageView = (ImageView)view.getChildAt(0); imageView.setImageResource(fRes); } }效果如下
4、用tabhost来实现底部菜单
我们会发现现在很多的UI,都有个底部菜单,比如微信,美团等,那我们如何用TabHost来实现一下这个效果呢
很简单,我们只要修改一下布局就可以了
<TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1.0" android:gravity="center" /> <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0.0" /> </LinearLayout> </TabHost>与之前布局不同的是把id为tabcontent的控件调到了tabWight前面,因为tabcontent是用来显示内容的,放到了tabWight上,自然菜单就跑到了下面,好理解吧,O(∩_∩)O哈哈~
讲了那么多,让我们来实战一下吧,以美团为例吧
美团是这个样子的:
我们的样子是这样的
当然跟美图会有一些差异,因为没时间调呀,我们也就是为了运用一下我们刚写到的知识来实现一下效果而已
不要太认真,认真你就输了
不过,在我看来,美图应该用的不是tabhost,可能是fragment,O(∩_∩)O哈哈~fragment是以后的趋势了
看到网上有好多的教程了,我就不要重复了,不过,有时间的话,也可以写点什么
之前的 《Viewpager+fragment数据更新问题》 就是用fragment来实现的
下篇文章我们来讲一下TabHost的点击事件