介绍
现在绝大多数主流的应用主界面,都会包含一个底部菜单,就拿腾讯的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