介绍

现在绝大多数主流的应用主界面,都会包含一个底部菜单,就拿腾讯的QQ与微信来说,看起来是这样的

 《---我是底部菜单

原理

在很久以前,可以通过TabActivity实现相关功能,自从Fragment出来后,就被抛弃了。

原理也很简单

1、底部菜单通过自定义RadioGroup实现,通过setOnCheckedChangeListener监听切换内容。

2、内容切换,可以使用ViewPager(可以实现直接滑动切换),TabHost,FragmentManager来实现。、

PS:类似的,这样也可以通过HorizontalScrollView+ViewPager+RadioGroup实现类似网易新闻的顶部栏目效果(或者ViewPageIndicator),通过ScrollView.scrollTo((int)RadioButton.getLeft())来自动滑动到当前选择项,有空再写篇文章。

实现

在几种组合搭配来看,我比较喜欢使用Fragment+Tabhost+RadioGroup搭配实现。

首先上首页布局代码activity_main.xml,注意加粗id

<?xml version="1.0" encoding="utf-8"?>
<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:background="#FFFFFFFF"
android:orientation="vertical" > <FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" > <FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="fill_parent" > <fragment
android:id="@+id/fragment_main"
android:name="com.example.tabmenu.MainFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" /> <fragment
android:id="@+id/fragment_mycenter"
android:name="com.example.tabmenu.MyCenterFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" /> <fragment
android:id="@+id/fragment_search"
android:name="com.example.tabmenu.SearchFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
</FrameLayout> <TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.0"
android:visibility="gone" />

     <!-- 我只是一条线 -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="3dp"
android:background="@drawable/fbutton_color_emerald" >
</LinearLayout> <RadioGroup
android:id="@+id/radiogroup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/fbutton_color_turquoise"
android:gravity="center_vertical"
android:orientation="horizontal" > <!-- android:background="@drawable/bk_footer" --> <RadioButton
android:id="@+id/radio_search"
style="@style/main_tab_bottom"
android:layout_weight="1"
android:background="@drawable/footer_itembg_selector"
android:drawableTop="@drawable/footer_search_selector"
android:text="搜索" /> <RadioButton
android:id="@+id/radio_main"
style="@style/main_tab_bottom"
android:layout_weight="1"
android:background="@drawable/footer_itembg_selector"
android:button="@null"
android:checked="true"
android:drawableTop="@drawable/footer_main_selector"
android:text="首 页" /> <RadioButton
android:id="@+id/radio_mycenter"
style="@style/main_tab_bottom"
android:layout_weight="1"
android:background="@drawable/footer_itembg_selector"
android:drawableTop="@drawable/footer_mycenter_selector"
android:text="个人中心" />
</RadioGroup>
</LinearLayout> </TabHost>

其中RadioButton的样式按照需要自己定义

    <style name="main_tab_bottom">
<item name="android:textSize">10sp</item>
<item name="android:textColor">#ffffffff</item>
<item name="android:ellipsize">marquee</item>
<item name="android:gravity">center_horizontal</item>
<item name="android:background">#00000000</item>
<item name="android:paddingTop">2dp</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">2dp</item>
<item name="android:layout_weight">1.0</item>
</style>

MainActivity代码

package com.example.tabmenu;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.animation.AnimationUtils;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TabHost; public class MainActivity extends ActionBarActivity {
// tab用参数
private TabHost tabHost;
private RadioGroup radiogroup;
private int menuid; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
radiogroup = (RadioGroup) findViewById(R.id.radiogroup);
tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();
tabHost.addTab(tabHost.newTabSpec("main").setIndicator("main")
.setContent(R.id.fragment_main));
tabHost.addTab(tabHost.newTabSpec("mycenter").setIndicator("mycenter")
.setContent(R.id.fragment_mycenter));
tabHost.addTab(tabHost.newTabSpec("search").setIndicator("search")
.setContent(R.id.fragment_search));
radiogroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
menuid = checkedId;
int currentTab = tabHost.getCurrentTab();
switch (checkedId) {
case R.id.radio_main:
tabHost.setCurrentTabByTag("main");
//如果需要动画效果就使用
//setCurrentTabWithAnim(currentTab, 0, "main");
getSupportActionBar().setTitle("首页");
break;
case R.id.radio_mycenter:
//tabHost.setCurrentTabByTag("mycenter");
setCurrentTabWithAnim(currentTab, 1, "mycenter");
getSupportActionBar().setTitle("个人中心"); break;
case R.id.radio_search:
tabHost.setCurrentTabByTag("search");
getSupportActionBar().setTitle("搜索");
}
// 刷新actionbar的menu
getWindow().invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL);
}
}); } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present. switch (menuid) {
case R.id.radio_main:
getMenuInflater().inflate(R.menu.main, menu);
break;
case R.id.radio_mycenter:
menu.clear();
break;
case R.id.radio_search:
menu.clear();
break;
}
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} // 这个方法是关键,用来判断动画滑动的方向
private void setCurrentTabWithAnim(int now, int next, String tag) {
if (now > next) {
tabHost.getCurrentView().startAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_out));
tabHost.setCurrentTabByTag(tag);
tabHost.getCurrentView().startAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in));
} else {
tabHost.getCurrentView().startAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));
tabHost.setCurrentTabByTag(tag);
tabHost.getCurrentView().startAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
}
}
}

最后demo截图,其他文件件demo

demo下载地址:

链接:http://pan.baidu.com/s/1dbuKA 密码:84iw

参考:

http://blog.csdn.net/loongggdroid/article/details/9469935

http://blog.csdn.net/eyebrows_cs/article/details/8145913

http://www.cnblogs.com/over140/archive/2011/03/02/1968042.html

Android应用主界面底部菜单实现的更多相关文章

  1. Xamarin.Android 利用Fragment实现底部菜单

    效果图: 第一步:添加引用 引用 Crosslight.Xamarin.Android.Support.v7.AppCompat 这个包. 第二步:绘制Main和Fragment界面 fg_home. ...

  2. Android自定义控件系列(四)—底部菜单(下)

    转载请注明出处:http://www.cnblogs.com/landptf/p/6290862.html 在app中经常会用到底部菜单的控件,每次都需要写好多代码,今天我们用到了前几篇博客里的控件来 ...

  3. [模拟Android微信]主界面

    首先看很像模仿: 走出来: 实现过程: 依赖类库:actionbarsherlock 用actionbarsherlock来实现顶部的搜索的效果. tab用的是Viewpaper实现的. 详细细节: ...

  4. ViewPager + Fragment 实现主界面底部导航栏

    1. 四个类似的Frament布局 tab_main_fragment.xml <LinearLayout xmlns:android="http://schemas.android. ...

  5. android笔记---主界面(二)自定义actionbar环境的配置

    第一步,添加java文件 第二步,添加actionbar的item文件 是个选择器,点中状态和选中状态 <?xml version="1.0" encoding=" ...

  6. android笔记---主界面(一)

    <?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="htt ...

  7. 【Android】5.0 第5章 常用基本控件--本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-02-06 这一章主要介绍Android简单控件的基本用法.本章源程序共有9个示例,这些示例都在同一个项目中. 项目名:ch05demo ...

  8. Android学习系列(22)--App主界面比较

    本文算是一篇漫谈,谈一谈当前几个流行应用的主界面布局,找个经典的布局我们自己也来实现一个.不是为了追求到底有多难,而是为了明白我们确实需要这么做. 走个题,android的UI差异化市场依然很大,依然 ...

  9. Android ActionBar应用实战,高仿微信主界面的设计

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/26365683 经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对 ...

随机推荐

  1. linux下安装vsftp

    1. yum安装vsftp # yum install vsftpd 2. 配置Vsftpd 安装完之后我们要对它进行配置,才能正常使用.编辑vsftpd的配置文件vi /etc/vsftpd/vsf ...

  2. mvc从xheditor编辑器中获取内容时存在潜在危险

    xmfdsh在使用xheditor提交要发布的文章等内容的时候出现了如下的错误: 从客户端(Content="<p style="text-align...")中检 ...

  3. VC++之GetLastError()使用说明

    VC中GetLastError()获取错误信息的使用 在VC中编写应用程序时,经常需要涉及到错误处理问题.许多函数调用只用TRUE和FALSE来表明函数的运行结果.一旦出现错误,MSDN中往往会指出请 ...

  4. JDK各个版本下载页面

    http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html 需 ...

  5. PHP合并数组array_merge函数运算符加号与的区别

    两个的区别是:1.数组键名为数字键名时,要合并的两个数组中有同名数字KEY的时候,使用array_merge()不会覆盖掉原来的值,而使用“+”合并数组则会把最先出现的值作为最终结果返回,而把后面的数 ...

  6. 在iptables防火墙下开启vsftpd的端口

    在开启vsftpd端口后发现用客户端工具能登陆,但无法浏览文件和新建文件.此时看了一下ftp的协议,发现ftp有主动模式和被动模式.在服务端开21端口是让客户端进来,并没有出去的端口,还在服务端开启出 ...

  7. kafka配置

    官网:http://kafka.apache.org/ 主要有3种安装方式: 1. 单机单broker 2. 单机多broker 3. 多机多broker 1. wget http://mirror. ...

  8. Struts2 Convention插件的使用(3)方法前的@Action注解

    package com.hyy.action; import org.apache.struts2.convention.annotation.Action; import com.opensymph ...

  9. 安装 M2eclipse 插件

    安装 M2eclipse 插件 在 Eclipse 中集成 Maven 插件能极大的方便创建 Maven project 并对其进行操作.使用以下的步骤来完成 M2eclipse 插件的安装: 在 E ...

  10. Log4net学习

    转自:http://www.cnblogs.com/sirkevin/archive/2012/06/13/2548449.html Log4net简介根据日志类别保存到不同的文件,并按照日期生成不同 ...