在商城第一篇的开篇当中,我们看到商城的效果图里面有一个底部导航栏效果,如下图所示:

  

  今天我们就来实现商城底部导航栏,最终效果图如下所示:

  

  那么这种效果是如何实现,实现的方式有很多种,最常见的就是使用Fragment+RadioButton去实现。下面我们来写一个例子

  首先我们先在activity_mian.xml定义布局,整个布局的外面是线性布局,上面是帧布局切换不同的Fragment,底下是RadioGroup嵌套的是RadioButton。代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#ffffff"
  6. android:orientation="vertical">
  7.  
  8. <FrameLayout
  9. android:id="@+id/frameLayout"
  10. android:layout_width="match_parent"
  11. android:layout_height="0dp"
  12. android:layout_weight="1" />
  13.  
  14. <RadioGroup
  15. android:id="@+id/rg_main"
  16. android:layout_width="match_parent"
  17. android:layout_height="wrap_content"
  18. android:layout_alignParentBottom="true"
  19. android:background="@drawable/home_bottom_parent_bg"
  20. android:orientation="horizontal">
  21.  
  22. <RadioButton
  23. android:id="@+id/rb_home"
  24. style="@style/MainButtonStyle"
  25. android:drawableTop="@drawable/home_button_selector"
  26. android:text="首页" />
  27.  
  28. <RadioButton
  29. android:id="@+id/rb_type"
  30. style="@style/MainButtonStyle"
  31. android:drawableTop="@drawable/type_button_selector"
  32. android:text="分类" />
  33.  
  34. <RadioButton
  35. android:id="@+id/rb_community"
  36. style="@style/MainButtonStyle"
  37. android:drawableTop="@drawable/community_button_selector"
  38. android:paddingTop="10dp"
  39. android:text="发现" />
  40.  
  41. <RadioButton
  42. android:id="@+id/rb_cart"
  43. style="@style/MainButtonStyle"
  44. android:drawableTop="@drawable/cart_button_selector"
  45. android:text="购物车" />
  46.  
  47. <RadioButton
  48. android:id="@+id/rb_user"
  49. style="@style/MainButtonStyle"
  50. android:drawableTop="@drawable/user_button_selector"
  51. android:text="个人中心" />
  52. </RadioGroup>
  53.  
  54. </LinearLayout>

  注意:上面还有样式和drawable,下面我们一个一个的来完善。

  首先来看样式,打开【res】—【values】—【styles】,代码如下所示:

  1. <style name="MainButtonStyle">
  2. <!-- Customize your theme here. -->
  3. <item name="android:layout_width">0dp</item>
  4. <item name="android:layout_height">wrap_content</item>
  5. <item name="android:layout_weight">1</item>
  6. <item name="android:button">@null</item>
  7. <!-- <item name="android:drawablePadding">3dp</item>-->
  8. <item name="android:textColor">@drawable/bottom_button_text_selector</item>
  9. <item name="android:textSize">10sp</item>
  10. <item name="android:gravity">center</item>
  11. </style>

  里面还有一个<item name="android:textColor">@drawable/bottom_button_text_selector</item>,这个是设置图片和文字的颜色,在drawable的目录下建bottom_button_text_selector,代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3.  
  4. <item android:color="#535353" android:state_checked="false"></item>
  5. <item android:color="#ff4040" android:state_checked="true"></item>
  6.  
  7. </selector>

  接着我们继续来完善drawable,有【首页】【分类】【发现】【购物车】【个人中心】,写法都是一样的,这里用【首页】来做例子,在drawable目录下建home_button_selector,代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3.  
  4. <item android:drawable="@drawable/main_home" android:state_checked="false"></item>
  5. <item android:drawable="@drawable/main_home_press" android:state_checked="true"></item>
  6.  
  7. </selector>

   接下来看MainActivity中的代码,代码如下:

  1. package com.nyl.shoppingmall.app.activity;
  2.  
  3. import android.os.Bundle;
  4. import android.support.v4.app.Fragment;
  5. import android.support.v4.app.FragmentActivity;
  6. import android.support.v4.app.FragmentTransaction;
  7. import android.widget.FrameLayout;
  8. import android.widget.RadioGroup;
  9.  
  10. import com.nyl.shoppingmall.R;
  11. import com.nyl.shoppingmall.base.BaseFragment;
  12. import com.nyl.shoppingmall.community.fragment.CommunityFragment;
  13. import com.nyl.shoppingmall.home.fragment.HomeFragment;
  14. import com.nyl.shoppingmall.shoppingcart.fragment.ShoppingCartFragment;
  15. import com.nyl.shoppingmall.type.fragment.TypeCartFragment;
  16. import com.nyl.shoppingmall.user.fragment.UserCartFragment;
  17.  
  18. import java.util.ArrayList;
  19.  
  20. import butterknife.Bind;
  21. import butterknife.ButterKnife;
  22.  
  23. public class MainActivity extends FragmentActivity{
  24.  
  25. @Bind(R.id.frameLayout)
  26. FrameLayout frameLayout;
  27. @Bind(R.id.rg_main)
  28. RadioGroup rgMain;
  29.  
  30. //装fragment的实例集合
  31. private ArrayList<BaseFragment> fragments;
  32.  
  33. private int position = 0;
  34.  
  35. //缓存Fragment或上次显示的Fragment
  36. private Fragment tempFragment;
  37.  
  38. @Override
  39. protected void onCreate(Bundle savedInstanceState) {
  40. super.onCreate(savedInstanceState);
  41. setContentView(R.layout.activity_main);
  42. //ButterKnife和当前Activity绑定
  43. ButterKnife.bind(this);
  44.  
  45. //初始化Fragment
  46. initFragment();
  47. //设置RadioGroup的监听
  48. initListener();
  49. }
  50.  
  51. private void initListener() {
  52. rgMain.check(R.id.rb_home);
  53. rgMain.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
  54. @Override
  55. public void onCheckedChanged(RadioGroup radioGroup, int i) {
  56. switch (i){
  57. case R.id.rb_home: //首页
  58. position = 0;
  59. break;
  60. case R.id.rb_type: //分类
  61. position = 1;
  62. break;
  63. case R.id.rb_community: //发现
  64. position = 2;
  65. break;
  66. case R.id.rb_cart: //购物车
  67. position = 3;
  68. break;
  69. case R.id.rb_user: //个人中心
  70. position = 4;
  71. break;
  72. default:
  73. position = 0;
  74. break;
  75. }
  76. //根据位置得到相应的Fragment
  77. BaseFragment baseFragment = getFragment(position);
  78. /**
  79. * 第一个参数: 上次显示的Fragment
  80. * 第二个参数: 当前正要显示的Fragment
  81. */
  82. switchFragment(tempFragment,baseFragment);
  83. }
  84. });
  85. }
  86.  
  87. /**
  88. * 添加的时候按照顺序
  89. */
  90. private void initFragment(){
  91. fragments = new ArrayList<>();
  92. fragments.add(new HomeFragment());
  93. fragments.add(new TypeCartFragment());
  94. fragments.add(new CommunityFragment());
  95. fragments.add(new ShoppingCartFragment());
  96. fragments.add(new UserCartFragment());
  97. }
  98.  
  99. /**
  100. * 根据位置得到对应的 Fragment
  101. * @param position
  102. * @return
  103. */
  104. private BaseFragment getFragment(int position){
  105. if(fragments != null && fragments.size()>0){
  106. BaseFragment baseFragment = fragments.get(position);
  107. return baseFragment;
  108. }
  109. return null;
  110. }
  111.  
  112. /**
  113. * 切换Fragment
  114. * @param fragment
  115. * @param nextFragment
  116. */
  117. private void switchFragment(Fragment fragment,BaseFragment nextFragment){
  118. if (tempFragment != nextFragment){
  119. tempFragment = nextFragment;
  120. if (nextFragment != null){
  121. FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
  122. //判断nextFragment是否添加成功
  123. if (!nextFragment.isAdded()){
  124. //隐藏当前的Fragment
  125. if (fragment != null){
  126. transaction.hide(fragment);
  127. }
  128. //添加Fragment
  129. transaction.add(R.id.frameLayout,nextFragment).commit();
  130. }else {
  131. //隐藏当前Fragment
  132. if (fragment != null){
  133. transaction.hide(fragment);
  134. }
  135. transaction.show(nextFragment).commit();
  136. }
  137. }
  138. }
  139. }
  140. }

  首先使用ButterKnife初始化布局控件,然后在onCreate方法中初始化Fragment和绑定RadioGroup的选中改变事件,为了方便初始化Fragment,写了一个initFragment方法,在方法内部创建HomeFragment,TypeCartFragment,CommunityFragment,ShoppingCartFragment,UserCartFragment四个Fragment实例,然后使用一个fragments集合存储这四个实例。接下来写一个switchFragment方法,用于切换显示指定的Fragmetn,当RadioGroup的选中改变时,首先根据选中的位置获取到对应的Fragment,然后将获取到的Fragment传入到switchFragment方法中进行显示。由于每次RadioGroup的选中改变获取到的Fragment都不一样,从而可以实现根据选中的RadioGroup展示不同的Fragment效果,也就是常见的Tab切换效果。

  Activity中用到的HomeFragment,TypeCartFragment,CommunityFragment,ShoppingCartFragment,UserCartFragment这四个Fragment的代码比较简单,以HomeFragment为例,代码如下:

  1. package com.nyl.shoppingmall.home.fragment;
  2.  
  3. import android.util.Log;
  4. import android.view.Gravity;
  5. import android.view.View;
  6. import android.widget.TextView;
  7.  
  8. import com.nyl.shoppingmall.base.BaseFragment;
  9.  
  10. /**
  11. * 首页Fragment
  12. */
  13. public class HomeFragment extends BaseFragment {
  14.  
  15. private final static String TAG = HomeFragment.class.getSimpleName();
  16.  
  17. private TextView textView;
  18.  
  19. @Override
  20. public View initView() {
  21. textView = new TextView(mContext);
  22. textView.setGravity(Gravity.CENTER);
  23. textView.setTextSize(25);
  24. Log.e(TAG,"主页面的Fragment的UI被初始化了");
  25. return textView;
  26. }
  27.  
  28. @Override
  29. public void initData() {
  30. super.initData();
  31. textView.setText("首页");
  32. Log.e(TAG,"主页面的Fragment的数据被初始化了");
  33. }
  34. }
  1.   HomeFragment继承自BaseFragment,然后重写父类的initView方法和initData方法,BaseFragment的代码如下:
  1. package com.nyl.shoppingmall.base;
  2.  
  3. import android.content.Context;
  4. import android.os.Bundle;
  5. import android.support.annotation.Nullable;
  6. import android.support.v4.app.Fragment;
  7. import android.view.LayoutInflater;
  8. import android.view.View;
  9. import android.view.ViewGroup;
  10.  
  11. /**
  12. * 基类Fragment
  13. * 首页:HomeFragment
  14. * 分类:TypeFragment
  15. * 发现:CommunityFragment
  16. * 购物车:ShoppingCartFragment
  17. * 用户中心:UserFragment
  18. * 等等都要继承该类
  19. */
  20.  
  21. public abstract class BaseFragment extends Fragment{
  22.  
  23. protected Context mContext;
  24.  
  25. /**
  26. * 当该类被系统创建的时候回调
  27. * @param savedInstanceState
  28. */
  29. @Override
  30. public void onCreate(@Nullable Bundle savedInstanceState) {
  31. super.onCreate(savedInstanceState);
  32. mContext = getActivity();
  33. }
  34.  
  35. @Nullable
  36. @Override
  37. public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  38. return initView();
  39. }
  40.  
  41. //抽象类,由孩子实现,实现不同的效果
  42. public abstract View initView();
  43.  
  44. @Override
  45. public void onActivityCreated(@Nullable Bundle savedInstanceState) {
  46. super.onActivityCreated(savedInstanceState);
  47. initData();
  48. }
  49.  
  50. /**
  51. * 当子类需要联网请求数据的时候,可以重写该方法,该方法中联网请求
  52. */
  53. public void initData() {
  54. }
  55. }

  其余几个Fragment的代码也类似,这里就不再细说了,使用Fragment+RadioButton实现底部导航栏的思路和代码实现就是这样的。

二、Fragment+RadioButton实现底部导航栏的更多相关文章

  1. [Android]--RadioGroup+RadioButton实现底部导航栏

    RadioGroup+RadioButton组合方式打造简单实用的底部导航栏 代码块: <?xml version="1.0" encoding="utf-8&qu ...

  2. Android商城开发系列(三)——使用Fragment+RadioButton实现商城底部导航栏

    在商城第一篇的开篇当中,我们看到商城的效果图里面有一个底部导航栏效果,如下图所示: 今天我们就来实现商城底部导航栏,最终效果图如下所示:   那么这种效果是如何实现,实现的方式有很多种,最常见的就是使 ...

  3. TextView+Fragment实现底部导航栏

    前言:项目第二版刚上线没多久,产品又对需求进行了大改动,以前用的是左滑菜单,现在又要换成底部导航栏,于是今天又苦逼加班了.花了几个小时实现了一个底部导航栏的demo,然后总结一下.写一篇博客.供自己以 ...

  4. Android_ViewPager+Fragment实现页面滑动和底部导航栏

    1.Xml中底部导航栏由一个RadioGroup组成,其上是ViewPager. <?xml version="1.0" encoding="utf-8" ...

  5. Android学习笔记- Fragment实例 底部导航栏的实现

    1.要实现的效果图以及工程目录结构: 先看看效果图吧: 接着看看我们的工程的目录结构: 2.实现流程: Step 1:写下底部选项的一些资源文件 我们从图上可以看到,我们底部的每一项点击的时候都有不同 ...

  6. [置顶] xamarin android Fragment实现底部导航栏

    前段时间写了篇关于Fragment的文章,介绍了基础的概念,用静态和动态的方式加载Fragment  Xamarin Android Fragment的两种加载方式.下面的这个例子介绍xamarin ...

  7. AndroidStudio制作底部导航栏以及用Fragment实现切换功能

    前言 大家好,给大家带来AndroidStudio制作底部导航栏以及用Fragment实现切换功能的概述,希望你们喜欢 学习目标 AndroidStudio制作底部导航栏以及用Fragment实现切换 ...

  8. React-native 底部导航栏(二)

    1.组件安装:npm install react-native-router-flux --save 2.定义菜单图片和文字: import React, { Component } from 're ...

  9. Android底部导航栏——FrameLayout + RadioGroup

    原创文章,转载请注明出处http://www.cnblogs.com/baipengzhan/p/6285881.html Android底部导航栏有多种实现方式,本文详细介绍FrameLayout ...

随机推荐

  1. ArcGIS API for JavaScript 4.2学习笔记[3] 官方第二章Mapping and Views概览与解释

    目录如下: 连接:第二章 Mapping and Views 根据本人体会, [这一章节主要是介绍地图(Map)和视图(View)的.] 其中,Get started with MapView(2D) ...

  2. java系列笔记---正则表达式(1)常用符号

    正则表达式---常用符号 首先声明,我这里列表的是经常使用的一些符号,如果你想得到全部,那建议你通过API中,搜索Pattern类,会得到所有符号. 字符类 [abc] a.b 或 c(简单类) [^ ...

  3. 《Effective C#中文版:改善C#程序的50种方法》读书笔记

    作者: suyan010203  来源: 博客园  发布时间: 2011-07-09 14:47  阅读: 8988 次  推荐: 4                   原文链接   [收藏] 从去 ...

  4. 判断数据是否服从某一分布(二)——简单易用fitdistrplus包

    一.对数据的分布进行初步判断     1.1 原理 对于不同的分布,有特定的偏度(skewness)和峰度(kurtosis),正态分布.均匀分布.逻辑斯谛分布.指数分布的偏度和峰度都是特定的值,在偏 ...

  5. Kafka概念入门(一)

    序:如何保证kafka全局消息有序? 比如,有100条有序数据,生产者发送到kafka集群,kafka的分片有4个,可能的情况就是一个分片保存0-25,一个保存25-50......这样消息在kafk ...

  6. executssql 函数的每一句代码的意思

    Public Function Executesql(ByVal sql As String, Msgstring As String) As ADODB.Recordset Dim cnn As A ...

  7. angular ng-repeat数组中的数组

    //先定义一个数组anular代码: var app = angular.module('serApp', []); app.controller('indexCtrl', function($sco ...

  8. 一个技术汪的开源梦 —— 微信开发工具包(WeixinSDK)

    由于春节的关系 WeixinSDK 这个开源项目的进展比预期推迟了大约一个月的时间,值得高兴的是到目前为止该项目的重要模块已经开发完毕.  - 关于项目 该项目的背景是现在微信公众号.微信服务号乃至微 ...

  9. Java 去除 ArrayList 集合中的重复元素

    // One practice package Collection; import java.util.ArrayList; import java.util.Iterator; // 去除 Arr ...

  10. CSS里padding和margin的区别是什么?

    通俗地说——padding 就是内容与边框的距离:margin 就是边框与其他元素的距离.