本项目使用了相对布局和单选按钮实现了安卓app常见的底部导航栏(带有消息圆点指示器),效果如果所示
一、布局代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!-- Fragment显示内容的容器 -->
<FrameLayout
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/nav_layout" />
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_above="@+id/nav_layout"
android:background="@color/line_bg" />
<LinearLayout
android:id="@+id/nav_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<!-- 首页 -->
<RelativeLayout
android:id="@+id/rlHomePage"
android:layout_width="0dp"
android:layout_height="match_parent"
android:padding="2dp"
android:background="@drawable/selector_nav_rl"
android:layout_weight="2">
<RadioButton
android:id="@+id/rbtnHomePage"
style="@style/nav_radio_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:checked="true"
android:drawableTop="@drawable/selector_home_page"
android:text="首页"
android:textColor="@color/nav_selector_text_color" />
<!-- 消息提示圆点 -->
<TextView
android:id="@+id/tvHomePageIndicator"
android:layout_width="9dp"
android:layout_height="9dp"
android:layout_alignRight="@id/rbtnHomePage"
android:layout_alignTop="@id/rbtnHomePage"
android:layout_gravity="right"
android:background="@drawable/shape_message_indicator"
android:clickable="false"
android:gravity="center" />
</RelativeLayout>
<!-- 养生 -->
<RelativeLayout
android:id="@+id/rlHealthPage"
android:layout_width="0dp"
android:layout_height="match_parent"
android:padding="2dp"
android:background="@drawable/selector_nav_rl"
android:layout_weight="2" >
<RadioButton
android:id="@+id/rbtnHealth"
style="@style/nav_radio_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:drawableTop="@drawable/selector_health_page"
android:text="养生"
android:textColor="@color/nav_selector_text_color" />
<!-- 消息提示圆点 -->
<TextView
android:id="@+id/tvNoticeIndicator"
android:layout_width="17dp"
android:layout_height="17dp"
android:layout_alignRight="@id/rbtnHealth"
android:layout_alignTop="@id/rbtnHealth"
android:layout_gravity="right"
android:layout_marginRight="-5dp"
android:background="@drawable/shape_message_indicator"
android:gravity="center"
android:text="99+"
android:textColor="@color/white"
android:textSize="8sp"
android:textStyle="bold" />
</RelativeLayout>
<!-- 消息 -->
<RelativeLayout
android:id="@+id/rlMessagePage"
android:layout_width="0dp"
android:layout_height="match_parent"
android:padding="1dp"
android:background="@drawable/selector_nav_rl"
android:layout_weight="2" >
<RadioButton
android:id="@+id/rbtnMessage"
style="@style/nav_radio_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:drawableTop="@drawable/seletor_message_page"
android:text="消息"
android:textColor="@color/nav_selector_text_color" />
<!-- 消息提示圆点 -->
<TextView
android:id="@+id/tvRelatedToMeIndicator"
android:layout_width="17dp"
android:layout_height="17dp"
android:layout_alignRight="@id/rbtnMessage"
android:layout_alignTop="@id/rbtnMessage"
android:layout_gravity="right"
android:background="@drawable/shape_message_indicator"
android:clickable="false"
android:gravity="center"
android:text="99+"
android:textColor="@color/white"
android:textSize="8sp"
android:textStyle="bold" />
</RelativeLayout>
<!-- 个人中心 -->
<RelativeLayout
android:id="@+id/rlMinePage"
android:layout_width="0dp"
android:layout_height="match_parent"
android:padding="2dp"
android:background="@drawable/selector_nav_rl"
android:layout_weight="2" >
<RadioButton
android:id="@+id/rbtnMine"
style="@style/nav_radio_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:drawableTop="@drawable/selector_mine_page"
android:text="个人中心"
android:textColor="@color/nav_selector_text_color" />
<!-- 消息提示圆点 -->
<TextView
android:id="@+id/tvPersonalIndicator"
android:layout_width="9dp"
android:layout_height="9dp"
android:layout_alignRight="@id/rbtnMine"
android:layout_alignTop="@id/rbtnMine"
android:layout_gravity="right"
android:layout_marginRight="7dp"
android:background="@drawable/shape_message_indicator"
android:clickable="false"
android:gravity="center" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
整体的父布局是相对布局,底部导航栏使用了横向的线性布局,每个导航项又使用了相对布局,在里面放置相应的控件。相对布局的特点就是要找好参照物,性能要比其他布局好很多,控件的位置也比较好控制。用它来实现导航布局是比较方便的。
导航项的状态切换是通过单选按钮的checked属性来实现的。这里使用了一个selector(选择器),每一个导航项都有一个自己的选择器。选择器根据checked的属性值来改变单选的背景和文本颜色,从而实现视觉效果的改变,效果很不错。单选按钮这一块,需要注意的地方是要让单选按钮的”android:clickable“属性为false,即让单选按钮不可以点击,否则在MainActivity切换fragment的时候会出现切换不成功的现象。
二、fragment的简介
本项目的页面切换使用了fragment。使用fragment布局的好处之一就是可以动态地在Activity中进行添加、删除和替换,这一特性使得fragment被广泛应用,用于建立多个UI面板,灵活而且方便。每一个页面都要创建一个Fragment类,重写类中的onCreateView方法,加载对应的布局文件,以及对控件进行初始化。
在本项目中,我建立了一个BaseFragment基类,用于派生类的继承。之前做项目的时候,发现所用到的fragment类有很多类似的代码段,例如Context、View对象,还有一些个人习惯的方法(findView、initView等),现在写这个项目的时候,我进行代码重构,把它们都放到了fragment基类当中,复用代码,减少工作量。大家在写项目当中多注意下这方面,学会优化代码。copy虽然很方便,但是它的坏处是显而易见的,如果一处地方修改,其它地方可能也要随之改变,到时候的工作量会让你崩溃。所以,学会代码重构是一个程序员的进阶过程。
三、fragment的切换
实现fragment的切换需要用到FragmentManager对象(fragment管理器)和FragmentTransaction(fragment事物管理对象)。实现fragment切换的过程如下:
(1)先添加所有的fragment对象到fragment事物管理对象当中,并提交事物。
(2)隐藏所有的fragment对象,然后显示默认的fragment。
(3)在点击导航项切换fragment的时候也是隐藏所有的fragment对象,然后显示默认的fragment。
(4)切换fragment的时候要改变单选按钮的状态,更新状态。
两个方法的代码如下:
/**
* 显示指定的fragment
*
* @param fragment
*/
private void showFragment(Fragment fragment) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.show(fragment);
ft.commit();
}
/**
* 隐藏所有Fragment
*/
private void hideAllFragment() {
// 获取Fragment管理器
FragmentManager fm = getFragmentManager();
// 获取Fragment事物对象
FragmentTransaction ft = fm.beginTransaction();
for (Fragment fragment : mFragmentList) {
ft.hide(fragment);
}
// 提交事物
ft.commit();
}
demo源码地址下载: http://download.csdn.net/detail/qq_33721382/9893220