TabHost眼睛会骗人
在上一篇文章“ TabHost 用法”中我们介绍了通过TabHost实现标签页效果。但是在实际项目中我们可能更希望定义自己的 Tab标签 样式使界面效果更佳。既然不能改变系统的 Tab 样式,那么我们可以选择隐藏系统的东西,使用自己定义的东西(这种方式很好用,以后会详细介绍)。反编译新浪微博的项目后会发现,他们在布局中隐藏了 TabWidget 即 Tab 标签而使用一组 RadioButton 来代替。既然是自己定义的,那肯定是可以自己决定显示样式了,那我们的问题也就解决了。 这里我使用的是“ TabHost 用法—两种实现方式”一文种提到的第二种实现方式,继承 Activity 来使用 TabHost 的。先把代码贴上来(红色字体部分为修改或添加的代码)。
TabHostActivity.java
public class TabHostActivity extends Activity implements
OnCheckedChangeListener {
private TabHost tabHost ;
private Intent certificateIntent ;
private Intent feeIntent ;
private Intent scoreIntent ;
private Intent studyIntent ;
private Intent moreIntent ;
@Override
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. tab );
// tabHost = getTabHost();
tabHost = (TabHost) findViewById(R.id. my_tabhost );
LocalActivityManager groupActivity =
new LocalActivityManager( this , false );
groupActivity.dispatchCreate(savedInstanceState);
tabHost .setup(groupActivity);
initIntent();
addSpec();
((RadioGroup) findViewById(R.id.tab_radiogroup ))
.set OnCheckedChangeListener (this );
}
/**
* 初始化各个 tab 标签对应的 intent
*/
private void initIntent() {
studyIntent = new Intent( this , StudyActivity. class );
scoreIntent = new Intent( this , ScoreActivity. class );
feeIntent = new Intent( this , FeeActivity. class );
certificateIntent = new Intent( this , CertificateActivity. class );
moreIntent = new Intent( this , MoreActivity. class );
}
/**
* 为 tabHost 添加各个标签项
*/
private void addSpec() {
tabHost .addTab( this .buildTagSpec( "tab_study" , R.string. study_progress ,
R.drawable. account01 , studyIntent ));
tabHost .addTab( this .buildTagSpec( "tab_score" , R.string. test_score ,
R.drawable. account02 , scoreIntent ));
tabHost .addTab( this .buildTagSpec( "tab_fee" , R.string. fee_pay ,
R.drawable. account03 , feeIntent ));
tabHost .addTab( this .buildTagSpec( "tab_certificate" ,
R.string. certificate_grant , R.drawable. account04 ,
certificateIntent ));
tabHost .addTab( this .buildTagSpec( "tab_more" , R.string. more ,
R.drawable. account05 , moreIntent ));
}
/**
* 自定义创建标签项的方法
* @param tagName 标签标识
* @param tagLable 标签文字
* @param icon 标签图标
* @param content 标签对应的内容
* @return
*/
private TabHost.TabSpec buildTagSpec(String tagName, int tagLable,
int icon, Intent content) {
return tabHost
.newTabSpec(tagName)
.setIndicator(getResources().getString(tagLable),
getResources().getDrawable(icon)).setContent(content);
}
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.radio_button_study :
tabHost.setCurrentTabByTag("tab_study");
break ;
case R.id.radio_button_score :
tabHost.setCurrentTabByTag("tab_score");
break ;
case R.id.radio_button_certificate :
tabHost.setCurrentTabByTag("tab_certificate");
break ;
case R.id.radio_button_fee :
tabHost.setCurrentTabByTag("tab_fee");
break ;
case R.id.radio_button_more :
tabHost.setCurrentTabByTag("tab_more");
break ;
}
}
}
tab.xml
<? xml version = "1.0" encoding = "UTF-8" ?>
< TabHost android:id = "@+id/my_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:id="@+id/tab_radiogroup"
android:background="@drawable/tabs_bg" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:gravity="center_vertical"
android:layout_gravity="bottom" android:orientation="horizontal" >
< RadioButton android:id = "@+id/radio_button_study"
android:layout_marginTop = "2.0dip" android:text = " 学习进度 "
android:drawableTop = "@drawable/account01" style = "@style/tab_button_bottom"
android:checked = "true" />
< RadioButton android:id = "@+id/radio_button_score"
android:layout_marginTop = "2.0dip" android:text = " 考试成绩 "
android:drawableTop = "@drawable/account02" style = "@style/tab_button_bottom" />
< RadioButton android:id = "@+id/radio_button_certificate"
android:layout_marginTop = "2.0dip" android:text = " 证书发放 "
android:drawableTop = "@drawable/account03" style = "@style/tab_button_bottom" />
< RadioButton android:id = "@+id/radio_button_fee"
android:layout_marginTop = "2.0dip" android:text = " 费用缴纳 "
android:drawableTop = "@drawable/account04" style = "@style/tab_button_bottom" />
< RadioButton android:id = "@+id/radio_button_more"
android:layout_marginTop = "2.0dip" android:text = " 更多 "
android:drawableTop = "@drawable/account05" style = "@style/tab_button_bottom" />
</ RadioGroup >
</ LinearLayout >
</ TabHost >
radio_button的背景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="@drawable/tabbar_home_f" />
<item android:state_enabled="true" android:drawable="@drawable/tabbar_home" />
</selector>
styles.xml
<? xml version = "1.0" encoding = "utf-8" ?>
< resources >
<!-- TabHost 标签按钮样式 -->
< style name = "tab_button_bottom" >
< item name = "android:textSize" > 12px </ 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 /tab_btn_bg </ item >
< item name = "android:layout_marginTop" > 2.0dip </ item >
< item name = "android:button" > @null </ item >
< item name = "android:paddingTop" > 6dip </ item >
< item name = "android:drawablePadding" > 4dip </ item >
< item name = "android:layout_width" > fill_parent </ item >
< item name = "android:layout_height" > wrap_content </ item >
< item name = "android:layout_weight" > 1.0 </ item >
< item name = "android:singleLine" > true </ item >
</ style >
<!-- 页面标题 LinearLayout 样式 -->
< style name = "activity_title_background" >
< item name = "android:background" > @drawable /title_background </ item >
< item name = "android:layout_width" > fill_parent </ item >
< item name = "android:layout_height" > wrap_content </ item >
< item name = "android:layout_alignParentTop" > true </ item >
< item name = "android:gravity" > center </ item >
</ style >
<!-- 界面标题 TextView 样式 -->
< style name = "activity_title_text" >
< item name = "android:textSize" > 14dip </ item >
< item name = "android:textColor" > @drawable /white </ item >
< item name = "android:layout_width" > wrap_content </ item >
< item name = "android:layout_height" > wrap_content </ item >
< item name = "android:gravity" > center </ item >
</ style >
</ resources >
运行结果如下图所示
程序重要部分:
1. 红色字体部分。
2. 布局文件 tab.xml, 可以看到该布局文件中将 TabWidget 隐藏 ( android:visibility="gone" ) 而以一个 RadioGroup 取而代之。
3. 为 RadioGroup 设置 OnCheckedChangeListener 监听,通过 onCheckedChanged 方法对各个 RadioButton 点击事件的处理完成标签切换。
其实我当初考虑过为什么要用 RadioButton 而不用普通的 Button 。后来通过自己做项目,发现使用 RadioGroup 有以下优点:
1. 另外就是布局上比较方便易懂,不用再去用 LinearLayout 等布局去包含 Button 。
2. 我们可以很方便的获得当前选中的标签,当然通过 TabHost 的 tabHost.getCurrentTabTag() 和 getCurrentTab() 也是可以的。
3. 设置监听很方便,只需要为 RadioGroup 设置监听就行了,程序中对应的代码是
((RadioGroup) findViewById(R.id.tab_radiogroup ))
.setOnCheckedChangeListener(this );
如果用 Button 的话我们需要为所有的 Button 一个一个去设置监听,相对来说比较麻烦。
4. 或许最重要的一点是因为 RadioButton 本身就支持图片和文字的上下布局,只需指定图片和文字是什么就可以了而不需要我们自己去实现这种布局。
< RadioButton android:id = "@+id/radio_button_more"
android:layout_marginTop = "2.0dip"
android:text=" 更多 "
android:drawableTop="@drawable/account05"
style = "@style/tab_button_bottom" />
TabHost眼睛会骗人相关推荐
- 三十七度的夏天挤公车
"我们渐渐地有细纹了.我们的感情,也该从容静好一些." 得到闺蜜开始谈婚论嫁的消息.她要跟那个男人结婚了. 那个第一次去她女朋友家里吃完饭甩手就走的男人. 那个一开始请她看演唱会, ...
- 123我爱你计算机音谱大全,抖音123我爱你尤克里里琴谱 123我爱你简谱
链接:http://www.j9p.com 来源:剧情狗 着作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. <123我爱你>是一首非常甜的曲子,歌曲好听,旋律也很洗脑, ...
- 属于哪个单元_标配三单元8英寸低音炮!STARKE Echo5.1时尚卫星家庭影院试用
前不久试用了杰士影院包之后,一直有网友问摩大大在1万出头的价位的卫星音响影院套装,还有没有什么值得推荐的产品. 其实在当时试用杰士影院包时,这套音响就一直在我的入户花园中. 这是来自于STARKE的e ...
- PHP刹车助力,自动刹车辅助都是骗人玩意儿?
在K哥还小的时候,每每看到电视或者报纸上关于交通事故的报道,都会思考一个问题 -- 这车要是在快要撞上去的时候,能自动停下来就好了. 没想到还是个孩子的我,无意间思考的一个问题,就触及到了现在各大车企 ...
- 鸿蒙一碰闪屏壁纸,不闪屏骗人吗? 戳穿护眼液晶的五大谎言
01LED背光是逆历史潮流吗? 屏闪问题是从CRT显示器时代就开始出现的.CRT是阴极射线管(Cathode Ray Tube)的意思,使用这种成像器件的显示器,体积都比较的大,就是我们过去使用的那种 ...
- Pyhton,OpenCV对象检测之——Haar级联人脸及眼睛检测
Pyhton,OpenCV对象检测之--Haar级联人脸及眼睛检测 1. 效果图 2. 原理 2.1 Haar人脸检测原理 2.2 Haar级联预训练的模型 3. 源码 3.1 图像面部及眼睛检测 3 ...
- 使用Python,dlib中新型、更快、更小的5点面部标志检测器检测人脸、眼睛、鼻子
这篇博客将介绍一个新的dlib面部标志检测器--5点人脸标志模型,它比原始版本更快(提高了8-10%),效率更高,模型更小(降低了10倍). 该5点面部标志检测器被认为是最初随dlib库一起分发的68 ...
- android Tabhost部件
本文结合源代码和实例来说明TabHost的用法. 使用TabHost 可以在一个屏幕间进行不同版面的切换,例如android自带的拨号应用,截图: 查看tabhost的源代码,主要实例变量有: pri ...
- 基于 Opencv 实现眼睛控制鼠标
作者 | 小白 来源 | 小白学视觉 如何用眼睛来控制鼠标?一种基于单一前向视角的机器学习眼睛姿态估计方法.在此项目中,每次单击鼠标时,我们都会编写代码来裁剪你们的眼睛图像.使用这些数据,我们可以反向 ...
- AI 通过眼睛的反光度,来识别是否 Deepfake 换脸
编译 | 禾木木 出品 | AI科技大本营(ID:rgznai100) Deepfake 是一种 AI换脸工具,现被滥用,从虚假宣传活动到插入一些违法内容,并且篡改后的图像是难以被检测到的. 一种新的 ...
最新文章
- [java语言]——InetAddress类的getByName()方法
- su的时候密码认证失败的解决方法
- Burpsuite爆破含CSRF-Token的程序
- HeadFirst设计模式篇四:工厂模式
- 【研究】Joomla二阶注入
- python之sys库
- 杨辉三角形函数 JavaScript Generator 实现
- VC/MFC 下 递归遍历目录下的所有子目录及文件
- 为什么setTimeout(fn,0)有时有用?
- 哈理工OJ—1309入侵检测(字符串处--剪枝)
- 光盘显示0字节可用_松下PLC编程软件FPWIN Pro7.4.0.0
- 实现米思齐的数码管图形化编程
- 微信小程序 SEO 指南
- iOS开发常用三方库、插件、知名博客等等
- Mystery——团队作业——系统设计
- 学的java,想问问现在想做电商的项目怎末样?
- EMBA必看书籍推荐
- Eigen实现克罗内克内积
- Cocos2dx游戏开发系列笔记5:继续润色《忍者飞镖射幽灵》
- C++ 两点之间最短距离