TabHost自定义外观
博客园: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自定义外观的更多相关文章
- 44.Qt通过子类化qstyle实现自定义外观
main.cpp #include <QtGui> #include "brozedialog.h" #include "bronzestyle.h" ...
- 43.qt通过qss自定义外观
样式: 文件格式类型: candy.qss /* R1 */ QDialog { /*设置背景图片*/ background-image: url(:/images/background.png); ...
- IOS开发之UISearchBar自定义外观
MySearchBar.h如下: @interface MySearchBar : UISearchBar - (void)layoutSubviews; @end MySearchBar.m如下 ...
- MyEclipse使用教程:使用主题自定义工作台外观
[MyEclipse CI 2019.4.0安装包下载] 您可以通过选择Window>Preferences>General>Appearance来使用主题自定义的工作台外观,可以从 ...
- 取消TableViewCell选中状态的外观变化
tabelViewcell 使用Xib创建自定义外观的时候,在tableview选中的时候,cell的外观会发生变化,在定义Xib中如下图将选中的外观状态取消掉 也有其他选项,可以选择控制选中的时候的 ...
- 通过Qt样式表定制程序外观(比较通俗易懂)
1. 何为Qt样式表[喝小酒的网摘]http://blog.hehehehehe.cn/a/10270.htm2. 样式表语法基础3. 方箱模型4. 前景与背景5. 创建可缩放样式6. 控制大小7. ...
- Flex自定义组件、皮肤,并调用
标签:Flex 自定义组件 自定义皮肤 主应用调用模块 本程序样例学习自flex 实战教程.但因原教程代码不全,且根据个人需求有更改. 1文件列表 自定义as类Reveal.as,该类实现组件的 ...
- ProgressBar学习笔记,自定义横向进度条的样式(包含ActionBar上面的进度条)
点显示进度条后→ android:max="100" 进度条的最大值 android:progress 进度条已经完成的进度值 android:progressDrawab ...
- Cesium官方教程8-- 几何体和外观效果
原文地址:https://cesiumjs.org/tutorials/Geometry-and-Appearances/ 几何体和外观效果(Geometry and Appearances) 这篇教 ...
随机推荐
- Linux下使用openvpn客户端
安装 root 权限用户下 :yum install openvpn fedora23的yum可能会切换到dnf源上安装不必在意,等待就ok. 稍等片刻将自动安装好openvpn需要的软件包.安装完成 ...
- svn-主副分支使用
主改bug 副加功能, :主合并到副(在副中切换主分支),副调试成功,合并回主(在主切换回副分支) 奇葩的实现了需求 主改bug 副加功能, :主合并到副(在副中切换主分支),副调试成功,合并回主(在 ...
- Ubuntu15.10 编译VLC Android(安卓)过程记录
持续更新中... 最后一次修改于 2016-03-20 15:33:45 1.必要库的安装 除基本编译环境(gcc.g++等外),需要额外安装如下的库(用于下载必要的依赖文件) (1)JDK 推荐安装 ...
- iis post 请求.html文件报405
其实本地文件默认是不允许post请求的,但是需要配置一下,配置如下: 我的iis版本是8.5 当然默认也是不能post请求 *.html或是*.json的的文件的,这个问题困 ...
- jquery多级手风琴插件–accordion.js
手风琴菜单一般用于下拉导航,由于外观非常简洁,使用起来跟手风琴一样可以拉伸和收缩而得名,项目中适当应用手风琴效果会给用户带来非常好的体验.本文借助jQuery插件轻松打造一个非常不错的手风琴效果的菜单 ...
- 启动python解释器的命令(python manage.py shell和python的区别)
如果你曾经使用过Python,你一定好奇,为什么我们运行python manage.py shell而不是python.这两个命令都会启动交互解释器,但是manage.py shell命令有一个重要的 ...
- Why longest path problem doesn't have optimal substructure?
We all know that the shortest path problem has optimal substructure. The reasoning is like below: Su ...
- 在openshift上自定义node.js的版本
https://github.com/ramr/nodejs-custom-version-openshift 由于是线上服务器,一步一步来: 先把上面的工程拉下来,覆盖到初始化的工程里,提交,让服务 ...
- MySQL 对于大表(千万级),要怎么优化呢?
http://www.zhihu.com/question/19719997 提问:如何设计或优化千万级别的大表?此外无其他信息,个人觉得这个话题有点范,就只好简单说下该如何做,对于一个存储设计,必须 ...
- SaltStack的salt-api里如何指定用户执行cmd.script
在杨威的协助下,命令行,API调用都完美搞定. 主要是RUNAS参数的位置,以及它作为CURL POST -D DATA的使用. salt '1.2.3.4' cmd.script "sal ...