先不多说,上几张效果图看看:

好了,效果图看了,是不是感觉挺不错的呢,那么我们就来实现它吧,其实也不难,底部用到了FragmentTabHost,然后图片和文字的变色用到了selector背景选择器。那么接下来就来一步一步的实现吧。

首先我们来看一张图,解释一下底部的原理:

在这里我们可以看到,底部是一个FragmentTabHost,然后在这个FragmentTabHost中添加TabSpec,然后由indicator组成。下面首先看看TabSpec的官方解释:

A tab has a tab indicator, content, and a tag that is used to keep track of it. This builder helps choose among these options. For the tab indicator, your choices are: 1) set a label 2) set a label and an icon For the tab content, your choices are: 1) the id of a View 2) a TabHost.TabContentFactory that creates the View content. 3) an Intent that launches an Activity.大概意思就是说有一个选项卡指示器,帮助我们在选项卡中进行选择,我们可以放入图片和文字

那么我们来说下这个View,也就是说图标和文字是同一个View,包含了一个ImageView和一个TextView,那么我们首先来创建这个View吧。

tab_indicator.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:layout_marginTop="3dp"android:layout_gravity="center"android:gravity="center"android:orientation="vertical"android:paddingBottom="3dp"><ImageView
        android:id="@+id/icon_tab"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextView
        android:textColor="@color/selector_color_text"android:id="@+id/text_indicator"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="2dp"/>
</LinearLayout>

说到了tabhost,我们首先看看这个布局文件如何创建的吧,也就是说上代码:

activity_main.xml:


//这个官方的文档中也没有给出例子,还是我没有找到呢,不过网上的大都都是以下这样写的,tabcontent这个只是一个假的,真的是realtabcontent。
<?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"><FrameLayout
        android:id="@+id/realtabcontent"android:layout_weight="1"android:background="@color/bg_color"android:layout_width="match_parent"android:layout_height="0dip"/><com.example.ruolan.letgo.widget.FragmentTabHost
        android:id="@android:id/tabhost"android:background="@color/white"android:layout_width="match_parent"android:layout_height="wrap_content"><FrameLayout
            android:layout_weight="0"//android:id="@android:id/tabcontent"android:layout_width="0dp"android:layout_height="0dp"></FrameLayout></com.example.ruolan.letgo.widget.FragmentTabHost>
</LinearLayout>

当然了哈,这里的FragmentTabHost并不是官方的哈,而是找的一个文件(我可没有那么大的本事)

那么好了,既然布局文件已经创建了,我们就开始实现我们需要的功能吧:
在实现之前我们先要知道FragmentTabHost用法的用法:
那么就先来看看官方给的例子吧:

 private FragmentTabHost mTabHost;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {mTabHost = new FragmentTabHost(getActivity());mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.fragment1);mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),FragmentStackSupport.CountingFragment.class, null);mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),LoaderCursorSupport.CursorLoaderListFragment.class, null);mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),LoaderCustomSupport.AppListFragment.class, null);mTabHost.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);return mTabHost;}

可以看得出来,有三步:

第一步是:activity继承FragmentActivity
第二步是:调用setup()方法
第三步是:添加tabSpec

**好了,既然知道了怎么使用,下面我们就先实现一个吧:
主要的代码:**

        mInflater = LayoutInflater.from(this);mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);//调用setup()方法mTabHost.setup(this,getSupportFragmentManager(),R.id.realtabcontent);//新建TabSpecTabHost.TabSpec tabSpec = mTabHost.newTabSpec("主页");//创建新的View,也就是刚才前面讲的ViewView view = mInflater.inflate(R.layout.tab_indicator,null);img = (ImageView) view.findViewById(R.id.icon_tab);text = (TextView) view.findViewById(R.id.text_indicator);img.setBackgroundResource(R.mipmap.icon_home);text.setText(R.string.home);tabSpec.setIndicator(view);//添加tabSpec,这里我们要传三个参数//分别是tabSpec、class、nullmTabHost.addTab(tabSpec,HomeFragment.class,null);

实现的效果图:

是不是有点小激动了,我刚开始实现的时候也是很激动的,以前自己想都不敢想,不过实现之后,想想就是这么一回事(万事开头难)。

那么接下来的四个,其实如果不想麻烦的话,就是cory代码,实现其余的四个,不过是不是感觉有点浪费呢,让我cory五份,多么不好哈,太麻烦了哈,哈哈,那么我们就来建一个bean类吧,看看需要什么参数吧。大家也看到了,我们需要三个参数,就是Class–>Fragment , title—-> 文字 image –>图片

创建想必大家都会创建,我就不多说了,直接上代码:

package com.example.ruolan.letgo.bean;/*** Created by ruolan on 2015/11/29.*/
public class Tab {private int title;private int image;private Class fragment;public Tab(int title, int image, Class fragment) {this.title = title;this.image = image;this.fragment = fragment;}public int getTitle() {return title;}public void setTitle(int title) {this.title = title;}public Class getFragment() {return fragment;}public void setFragment(Class fragment) {this.fragment = fragment;}public int getImage() {return image;}public void setImage(int image) {this.image = image;}
}

那么我们的activity中的代码也需要改了,也就是我们的专业名词(封装)。

private void initTab() {//虽然说要简便,不过该少的还是不能少的哈,最少你得创建这5个tab吧Tab home = new Tab(R.string.home,R.drawable.selector_icon_home,HomeFragment.class);Tab hot = new Tab(R.string.hot,R.drawable.selector_icon_hot, HotFragment.class);Tab category = new Tab(R.string.category,R.drawable.selector_icon_category,CategoryFragment.class);Tab cart = new Tab(R.string.cart,R.drawable.selector_icon_cart,CartFragment.class);Tab mine = new Tab(R.string.mine,R.drawable.selector_icon_mine,MineFragment.class);//mTabs是一个list数组,需要存放我们创建的五个tabmTabs.add(home);mTabs.add(hot);mTabs.add(category);mTabs.add(cart);mTabs.add(mine);mInflater = LayoutInflater.from(this);mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);//调用setup()方法mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);//遍历这个数组,把每个都设置好,for (Tab tab:mTabs) {TabHost.TabSpec tabSpec = mTabHost.newTabSpec(getString(tab.getTitle()));tabSpec.setIndicator(builderIndiator(tab));mTabHost.addTab(tabSpec,tab.getFragment(),null);}//去掉分割线mTabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);mTabHost.setCurrentTab(0);}//既然说到了代码良好,好看,那么我们就重新创建一个方法private View builderIndiator(Tab tab){View view = mInflater.inflate(R.layout.tab_indicator, null);img = (ImageView) view.findViewById(R.id.icon_tab);text = (TextView) view.findViewById(R.id.text_indicator);img.setBackgroundResource(tab.getImage());text.setText(tab.getTitle());return view;}

当然这里当我们点击图片的时候,图片是可以变色的,文字也会可以变色的,这个就要使用selector背景选择器了。当然我们首先看看selector的状态:

1.android:state_pressed="true/false"
true:表示按下状态下使用,false:表示非按下状态下使用。2.android:state_focused="true/false"
ture:表示聚焦状态使用(例如使用滚动球/D-pad聚焦Button),false:表示非聚集状态下使用。3.android:state_selected="true/false"
true:表示被选中状态下使用,false:表示非选中下使用4.android:state_active="true/false"
true:表示可勾选状态时使用,false:表示不可勾选状态下使用5. android:state_checkable="true/false"
true:表示勾选状态下使用,false:表示非勾选状态使用6.android:state_checked="true/false"
true:表示勾选状态下使用,false:表示非勾选状态使用7. android:state_enabled="true/false"
true:表示可用状态使用(能接收触摸/点击事件),false:表示不可用状态使用8. android:state_window_focused="true/false"
true:表示应用程序窗口有焦点时使用(应用程序在前台),false:表示无焦点时使用

当然我们最常用的还是前面三种:
如果是图片的背景选择器,我们首先在res/drawable文件目录下(我用的是AS)创建:
selector_icon_home.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_focused="true" android:drawable="@mipmap/icon_home_press"/><item android:state_selected="true" android:drawable="@mipmap/icon_home_press"/><item android:drawable="@mipmap/icon_home"/>
</selector>

上面的使用的时候直接在使用图片资源的时候使用。

文字的背景选择器,这个要在res/color目录
selector_color_text.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:color="#eb4f38" android:state_selected="true"/><item android:color="#eb4f38" android:state_active="true"/><item android:color="#a9b7b7" android:state_activated="false"/><item android:color="#a9b7b7" android:state_active="false"/>
</selector>

这个在布局文件textview中使用 android:textColor=”@color/selector_color_text”

好了,最后就在onCreate()方法中调用initTab()方法就行了,运行的效果图就是刚开始的那个效果图,我就不上了,最后这个小的项目已经上传至我的github,可以下载源码。下载地址:https://github.com/wuyinlei/FragmentTabHost.git,如果有不对的地方,还请大神们指点迷津,我也是刚刚使用的哈。

用 FragmentTabHost 实现底部菜单相关推荐

  1. 【Android】FragmentTabHost实现底部Tab菜单选项

    以前实现类似微博底部菜单使用的是TabHost+Activity来实现,但是使用的时候提醒已经被弃用,现在我们可以通过FragmentTabHost+Fragment来实现.下面就是demo: 1.m ...

  2. [Android] 底部菜单布局+PopupWindows实现弹出菜单功能(初级篇)

        这篇文章主要是自己研究如何对底部菜单进行布局,并简单的实现点击不同"按钮"实现图片切换和背景切换的功能,最后通过PopupWindows实现弹出菜单,点击不同按钮能实现不同 ...

  3. 【微信小程序】之如何创建底部菜单?tabBar、mp-tabbar

    方法一:通过app.json配置底部菜单(常用) 小程序根目录下的 app.json 文件用来对微信小程序进行全局配置.文件内容为一个 JSON 对象全局配置 | 微信开放文档微信开发者平台文档htt ...

  4. 替代TabActivity,底部菜单主框架搭建

    看到还有些人在使用TabActvity,这个已经被Google废弃了的类,为了大家方便,写了一个能代替TabActivity的东西.说白了也就是对viewpager跟底部菜单进行了一个封装,标准的底部 ...

  5. 小巫新闻客户端底部菜单切换实现

    Android-小巫新闻客户端底部菜单切换实现 2012年12月7日 星期五 真快啊,12月了,到了一年的最后一个月,意味着学期也快要结束了.小巫还在认真得学习着Android,尽管学习得不怎么样,但 ...

  6. 底部居中_中文编程:安卓的底部菜单设计

    原创所有,侵权必究! 完成中文编程的安卓开发环境.电脑版的手机模拟器安装.设置. 我们开始中文安卓的开发吧,本文先尝试实现"底部菜单.上部内容"的界面设计. 新建项目 打开&quo ...

  7. android 底部菜单

    2019独角兽企业重金招聘Python工程师标准>>> 新浪微薄上的一个底部菜单的实现,有兴趣的 可以看一下 转载:http://www.adobex.com/android/sou ...

  8. 解决input获取焦点时底部菜单被顶上来问题

    当input获取焦点时底部菜单被顶上来问题解决方案: 1.如果是短页面,比如登录页,上部的登录表单div与底部的菜单div不会重合(两个div是同级的),可以通过设置登录表单div的z-index比底 ...

  9. 转-TabHost组件(二)(实现底部菜单导航)

    http://www.cnblogs.com/lichenwei/p/3975095.html 上面文章<安卓开发复习笔记--TabHost组件(一)(实现底部菜单导航)>中提到了利用自定 ...

  10. 微信小程序怎么添加底部菜单按钮

    继续微信小程序方面的教程,今天讲怎么在空白的小程序页面添加几个类似菜单的按钮,实现点击某个按钮跳转到对应界面,而不是单单局限于一个页面. 需要什么: 微信小程序账户 电脑一台 电脑安装微信开发者工具软 ...

最新文章

  1. VScode 插件、配置记录
  2. Docker背后的内核知识:命名空间资源隔离
  3. python3改变路径出现的SyntaxError问题
  4. 高级图像去雾算法的快速实现
  5. oracle 导数据报exp00058_一文看懂oracle12c数据库跨小版本迁移
  6. c++一元稀疏多项式计算器_武忠祥真题班归纳(更新至一元函数积分未完)
  7. 浏览器中关于事件的那点事儿
  8. 几万条数据的excel导入到mysql_【记录】2万多条数据的Excel表格数据导入mysql数据库...
  9. [css] 说说你对z-index的理解
  10. Qt中QSS的简单使用
  11. 分割线不显示_90后都30岁了,为什么还不结婚
  12. python 预测 位置_Python:核岭回归预测,KRR
  13. npm package.json 文件基础知识
  14. AR技术介绍(Located in Android)
  15. 设计心理学2-与复杂共处【读书笔记】
  16. 指数基金投资指南读书笔记
  17. 【MQTT】SpringBoot整合MQTT(EMQX)
  18. ata高级计算机系统,ATAOffice2010年高级解题步骤.pdf
  19. Java基础 DAY17
  20. CoppeliaSim添加ROS自定义消息类型

热门文章

  1. Pycharm 优雅的刷 leetcode 算法
  2. CSS 实现水晶按钮特效 - 来自 www.codesc.net
  3. 崩坏3服务器维护2月8号,崩坏3V3.4版本8月29日版本更新维护通知
  4. 下载离线地图数据(支持谷歌、百度、高德等所有地图源)
  5. php seo技巧,十个对排名最有效的SEO​技巧
  6. WWW2023即将截稿
  7. POC_Jenkins
  8. HCIE公开课之VLAN
  9. 第6章 索引和数据完整性
  10. IDEA控制台output中文乱码