博客园:http://www.cnblogs.com

    农民伯伯: http://www.cnblogs.com/over140

版本

  新浪微博 weibo_10235010.apk

正文

  一、效果图

    

    红色部分是本文要实现的目标。

  二、实现

    maintabs.xml

<?xml version="1.0" encoding="UTF-8"?>
<TabHost android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="0.0dip" android:layout_weight="1.0" />
<TabWidget android:id="@android:id/tabs" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.0" />
<RadioGroup android:gravity="center_vertical" android:layout_gravity="bottom" android:orientation="horizontal" android:id="@id/main_radio" android:background="@drawable/maintab_toolbar_bg" android:layout_width="fill_parent" android:layout_height="wrap_content">
<RadioButton android:text="@string/main_home" android:checked="true" android:id="@+id/radio_button0" android:layout_marginTop="2.0dip" android:drawableTop="@drawable/icon_1_n" style="@style/main_tab_bottom" />
<RadioButton android:id="@+id/radio_button1" android:layout_marginTop="2.0dip" android:text="@string/main_news" android:drawableTop="@drawable/icon_2_n" style="@style/main_tab_bottom" />
<RadioButton android:id="@+id/radio_button2" android:layout_marginTop="2.0dip" android:text="@string/main_my_info" android:drawableTop="@drawable/icon_3_n" style="@style/main_tab_bottom" />
<RadioButton android:id="@+id/radio_button3" android:layout_marginTop="2.0dip" android:text="@string/menu_search" android:drawableTop="@drawable/icon_4_n" style="@style/main_tab_bottom" />
<RadioButton android:id="@+id/radio_button4" android:layout_marginTop="2.0dip" android:text="@string/more" android:drawableTop="@drawable/icon_5_n" style="@style/main_tab_bottom" />
</RadioGroup>
</LinearLayout>
</TabHost>

    styles.xml

<style name="main_tab_bottom">
<item name="android:textSize">@dimen/bottom_tab_font_size</item>
<item name="android:textColor">#ffffffff</item>
<item name="android:ellipsize">marquee</item>
<item name="android:gravity">center_horizontal</item>
<item name="android:background">@drawable/home_btn_bg</item>
<item name="android:paddingTop">@dimen/bottom_tab_padding_up</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:button">@null</item>
<item name="android:singleLine">true</item>
<item name="android:drawablePadding">@dimen/bottom_tab_padding_drawable</item>
<item name="android:layout_weight">1.0</item>
</style>

    home_btn_bg.xml

<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_enabled="true" android:state_pressed="false" android:drawable="@drawable/home_btn_bg_s" />
<item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/home_btn_bg_s" />
<item android:state_enabled="true" android:state_checked="true" android:drawable="@drawable/home_btn_bg_d" />
<item android:drawable="@drawable/transparent" />
</selector>

    代码说明:

        1.  需要注意的是他这里把TabWidget的Visibility设置成了gone!也就是默认难看的风格不见了:,取而代之的是5个带风格的单选按钮.

        2.  注意为单选按钮设置的style,其中最重要的是为其background设置了home_btn_bg.xml,也就是自定义了选中效果。

    Java文件

public class MainTabActivity extends TabActivity implements OnCheckedChangeListener {
private TabHost mHost;
private Intent mMBlogIntent;
private Intent mMoreIntent;
private Intent mInfoIntent;
private Intent mSearchIntent;
private Intent mUserInfoIntent; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.maintabs); // ~~~~~~~~~~~~ 初始化
this.mMBlogIntent = new Intent(this, HomeListActivity.class);
this.mSearchIntent = new Intent(this, SearchSquareActivity.class);
this.mInfoIntent = new Intent(this, MessageGroup.class);
this.mUserInfoIntent = new Intent(this, MyInfoActivity.class);
this.mMoreIntent = new Intent(this, MoreItemsActivity.class); initRadios(); setupIntent();
} /** 初始化底部按钮 */
private void initRadios() {
((RadioButton) findViewById(R.id.radio_button0)).setOnCheckedChangeListener(this);
((RadioButton) findViewById(R.id.radio_button1)).setOnCheckedChangeListener(this);
((RadioButton) findViewById(R.id.radio_button2)).setOnCheckedChangeListener(this);
((RadioButton) findViewById(R.id.radio_button3)).setOnCheckedChangeListener(this);
((RadioButton) findViewById(R.id.radio_button4)).setOnCheckedChangeListener(this);
} /** 切换模块 */
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
switch (buttonView.getId()) {
case R.id.radio_button0:
this.mHost.setCurrentTabByTag("mblog_tab");
break;
case R.id.radio_button1:
this.mHost.setCurrentTabByTag("message_tab");
break;
case R.id.radio_button2:
this.mHost.setCurrentTabByTag("userinfo_tab");
break;
case R.id.radio_button3:
this.mHost.setCurrentTabByTag("search_tab");
break;
case R.id.radio_button4:
this.mHost.setCurrentTabByTag("more_tab");
break;
}
}
} private void setupIntent() {
this.mHost = getTabHost();
TabHost localTabHost = this.mHost; localTabHost.addTab(buildTabSpec("mblog_tab", R.string.main_home, R.drawable.icon_1_n, this.mMBlogIntent));
localTabHost.addTab(buildTabSpec("message_tab", R.string.main_news, R.drawable.icon_2_n, this.mInfoIntent));
localTabHost.addTab(buildTabSpec("userinfo_tab", R.string.main_my_info, R.drawable.icon_3_n, this.mUserInfoIntent));
localTabHost.addTab(buildTabSpec("search_tab", R.string.menu_search, R.drawable.icon_4_n, this.mSearchIntent));
localTabHost.addTab(buildTabSpec("more_tab", R.string.more, R.drawable.icon_5_n, this.mMoreIntent));
} private TabHost.TabSpec buildTabSpec(String tag, int resLabel, int resIcon,
final Intent content) {
return this.mHost.newTabSpec(tag)
          .setIndicator(getString(resLabel),getResources().getDrawable(resIcon))
.setContent(content);
}

    代码说明

      1.  由于TabWidget被隐藏,所以相关的事件也会无效,这里取巧用RadioGroup与RadioButton的特性来处理切换,然后监听事件调用setCurrentTabByTag来切换Activity。

      2.  注意即使TabWidget被隐藏,也要为其设置indicator,否则会保持。

  三、总结

 
   在这之前如果要做这种效果我恐怕第一时间就会想到用ActivityGroup来做,主要是因为TabHost的TabWidget非常难看,用起
来也不方便。其实从源码可以看出,TabActivity也是继承自ActivityGroup,这里结合了单选按钮和TabHost,各取其长,有时间
可以专门写一个这样的自定义控件:)

  四、相关文章

    [Android]使用ActivityGroup来切换Activity和Layout

结束

   本文中使用的资源均反编译自apk文件,这里主要是讲思路,欢迎大家交流。

TabHost自定义外观的更多相关文章

  1. 44.Qt通过子类化qstyle实现自定义外观

    main.cpp #include <QtGui> #include "brozedialog.h" #include "bronzestyle.h" ...

  2. 43.qt通过qss自定义外观

    样式: 文件格式类型: candy.qss /* R1 */ QDialog { /*设置背景图片*/ background-image: url(:/images/background.png); ...

  3. IOS开发之UISearchBar自定义外观

      MySearchBar.h如下: @interface MySearchBar : UISearchBar - (void)layoutSubviews; @end MySearchBar.m如下 ...

  4. MyEclipse使用教程:使用主题自定义工作台外观

    [MyEclipse CI 2019.4.0安装包下载] 您可以通过选择Window>Preferences>General>Appearance来使用主题自定义的工作台外观,可以从 ...

  5. 取消TableViewCell选中状态的外观变化

    tabelViewcell 使用Xib创建自定义外观的时候,在tableview选中的时候,cell的外观会发生变化,在定义Xib中如下图将选中的外观状态取消掉 也有其他选项,可以选择控制选中的时候的 ...

  6. 通过Qt样式表定制程序外观(比较通俗易懂)

    1. 何为Qt样式表[喝小酒的网摘]http://blog.hehehehehe.cn/a/10270.htm2. 样式表语法基础3. 方箱模型4. 前景与背景5. 创建可缩放样式6. 控制大小7. ...

  7. Flex自定义组件、皮肤,并调用

    标签:Flex  自定义组件  自定义皮肤  主应用调用模块 本程序样例学习自flex 实战教程.但因原教程代码不全,且根据个人需求有更改. 1文件列表 自定义as类Reveal.as,该类实现组件的 ...

  8. ProgressBar学习笔记,自定义横向进度条的样式(包含ActionBar上面的进度条)

     点显示进度条后→   android:max="100" 进度条的最大值 android:progress  进度条已经完成的进度值 android:progressDrawab ...

  9. Cesium官方教程8-- 几何体和外观效果

    原文地址:https://cesiumjs.org/tutorials/Geometry-and-Appearances/ 几何体和外观效果(Geometry and Appearances) 这篇教 ...

随机推荐

  1. 网站开发常用jQuery插件总结(13)定位插件scrollto

    一.scrollto插件功能 scrollto用于定位页面中元素的位置,并使滚动条滚动到当前元素. 二.scrollto官方地址 https://github.com/flesler/jquery.s ...

  2. 『奇葩问题集锦』Cannot find module 'webpack/lib/node/NodeTemplatePlugin'

    第一步:npm config get prefix ,获取输出path“C:\Users\jaxGu\AppData\Roaming\npm”加上"\node_modules"用于 ...

  3. php练习3——猜拳游戏,评委打分问题

    用户与计算机猜拳 程序caiQuan.html和caiQuan.php: 结果: 评委打分问题,去掉一个最低分和最高分,求平均分,并找出最低分和最高分对应第几个评委,    再找出最佳评委(打分最接近 ...

  4. POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数

    题目链接: http://poj.org/problem?id=2299 题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数. 利用归并排序求解,内存和耗时都比较少, 但是有 ...

  5. C# 两时间,时间间隔

    #region 返回时间差        public static string DateDiff(DateTime DateTime1, DateTime DateTime2)        {  ...

  6. LightOj_1364 Expected Cards

    题目链接 题意: 一副牌, 每个花色13张牌,加上大小王,共54张. 遇到大小王可以代替其中某种花色. 给定C, D, H, S. 每次抽一张牌, 问抽到C张梅花, D张方块, H张红桃, S张黑桃所 ...

  7. ms-on-input

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. java 容器类大集结

    这个世界是程序员的世界,归根到底是数据的世界,要统治这个世界,首先要学会征服数据. 没有最好的,只有最合适的,如何在不同的环境先选择最优的存储的结构呢?且看下文分解: 以下内容部分来自网络,参考: h ...

  9. activemq启动不起来,报错Address already in use: JVM_Bind

    之前莫名其妙的activemq怎么都启动不起来后来多方查询是因为widows 的ICS服务. 解决方案是,我的电脑上邮件,选择服务,然后在服务中找到Internet Connection Sharin ...

  10. delphi xe5 android 开发数据访问server端(二)

    上一篇我们创建了一个拟给手机端访问的webservices服务 接下来创建一个返回数据集的过程,用webservices发布,供手机端调用.这里我使用firedac 1.打开上一篇自动创建的WebMo ...