Android实现带有指示器的自定义底部导航栏

今天这篇文章,主要是给大家实现一个自定义的带有指示器的底部导航栏。

先看一下实现的效果吧。

这个自定义控件的使用要注意以下几个方面:

1.没有布局文件及资源文件,只需要一个java文件就可调用

2.可以非常灵活的使用,一句代码就可以添加到项目中

3.暂时只支持4.0以上版本,颜色值使用的是系统自带色值,如需在低版本使用,请自己替换颜色值

4.支持智能适配,可以根据底部按钮的数量,自动的调整布局

5.主内容区域,必须使用Fragment实现,通过附加到Viewpager上实现界面的左右滑动

下面给出主程序的实现,注释很清楚哈

package com.example.indicatornavigationbar; 

import android.app.Activity;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.TextView; 

/**
 *
 * @ClassName: com.mengle.activity.IndicatorNavigationBar
 * @Description: 带有指示器的底部导航栏
 * @author zhaokaiqiang
 * @date 2014-10-17 上午11:07:40
 *
 */
public class IndicatorNavigationBar extends LinearLayout implements
  OnClickListener, OnPageChangeListener { 

 // 导航栏默认高度,不包括指示器高度,单位是dp
 private static final int HEIGHT_NAVIGATION_BAR = 40;
 // 指示器默认高度,单位是dp
 private static final int HEIGHT_INDICATOR = 4; 

 private Context context;
 private ViewPager viewPager;
 // 指示器
 private ImageView ivBottomLine;
 // 当前显示的index
 private int currIndex = 0;
 // 存储移动位置
 private int positions[];
 // 标题数量
 private int titleCount; 

 public IndicatorNavigationBar(Context context) {
  super(context);
  this.context = context;
 } 

 /**
  *
  * @Description: 依附到父布局上
  * @param viewGroup
  *   要依附在的父布局
  * @param titles
  *   底部显示的导航文字
  * @param viewPager
  *   绑定的ViewPager对象
  * @return void
  */
 public void attachToParent(ViewGroup viewGroup, String[] titles,
   ViewPager viewPager) { 

  this.viewPager = viewPager;
  titleCount = titles.length; 

  // 初始化主布局
  setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
    dip2px(HEIGHT_NAVIGATION_BAR + HEIGHT_INDICATOR)));
  setBackgroundColor(getResources().getColor(android.R.color.transparent));
  setOrientation(VERTICAL); 

  // 导航栏布局
  LinearLayout ll_navigation = new LinearLayout(context);
  ll_navigation.setLayoutParams(new LayoutParams(
    LayoutParams.MATCH_PARENT, dip2px(HEIGHT_NAVIGATION_BAR)));
  ll_navigation.setBackgroundColor(getResources().getColor(
    android.R.color.holo_blue_light));
  ll_navigation.setOrientation(HORIZONTAL); 

  // 生成导航按钮(TextView)
  for (int i = 0; i < titles.length; i++) { 

   TextView textView = new TextView(context);
   textView.setLayoutParams(new LayoutParams(0,
     dip2px(HEIGHT_NAVIGATION_BAR), 1));
   textView.setText(titles[i]);
   textView.setGravity(Gravity.CENTER);
   textView.setTextSize(16);
   textView.setTextColor(getResources()
     .getColor(android.R.color.white));
   textView.setId(i);
   textView.setOnClickListener(this);
   ll_navigation.addView(textView);
  }
  // 添加导航
  this.addView(ll_navigation); 

  // 指示器布局
  LinearLayout ll_indicator = new LinearLayout(context);
  ll_indicator.setLayoutParams(new LayoutParams(
    LayoutParams.MATCH_PARENT, dip2px(HEIGHT_INDICATOR)));
  ll_indicator.setBackgroundColor(getResources().getColor(
    android.R.color.holo_blue_light));
  ll_indicator.setOrientation(HORIZONTAL); 

  // 指示器
  ivBottomLine = new ImageView(context);
  ivBottomLine.setImageResource(android.R.color.holo_orange_light);
  ivBottomLine.setScaleType(ScaleType.MATRIX);
  ivBottomLine
    .setLayoutParams(new LinearLayout.LayoutParams(
      getScreenWidth(context) / titleCount,
      dip2px(HEIGHT_INDICATOR)));
  ll_indicator.addView(ivBottomLine);
  // 添加指示器
  this.addView(ll_indicator); 

  viewGroup.addView(this);
  viewPager.setOnPageChangeListener(this); 

  // 初始化移动位置
  positions = new int[titleCount];
  positions[0] = 0;
  int distance = (int) (getScreenWidth(context) / titleCount);
  for (int i = 1; i < titleCount; i++) {
   positions[i] = distance * i;
  } 

 } 

 @Override
 public void onClick(View v) {
  viewPager.setCurrentItem(v.getId());
 } 

 @Override
 public void onPageScrollStateChanged(int arg0) { 

 } 

 @Override
 public void onPageScrolled(int position, float positionOffset,
   int positionOffsetPixels) { 

 } 

 @Override
 public void onPageSelected(int position) { 

  Animation animation = new TranslateAnimation(currIndex * positions[1],
    positions[position], 0, 0);
  currIndex = position;
  animation.setFillAfter(true);
  animation.setDuration(300);
  ivBottomLine.startAnimation(animation);
 } 

 private int dip2px(float dpValue) {
  final float scale = context.getResources().getDisplayMetrics().density;
  return (int) (dpValue * scale + 0.5f);
 } 

 // 获取屏幕宽度
 private int getScreenWidth(Context context) {
  DisplayMetrics dm = new DisplayMetrics();
  ((Activity) context).getWindowManager().getDefaultDisplay()
    .getMetrics(dm);
  return dm.widthPixels;
 }
} 

在我的github上可以下载这个项目的DEMO

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android程序开发之Fragment实现底部导航栏实例代码
  • Android实现沉浸式通知栏通知栏背景颜色跟随app导航栏背景颜色而改变
  • Android实现底部导航栏功能(选项卡)
  • Android仿网易客户端顶部导航栏效果
  • Android 沉浸式状态栏与隐藏导航栏实例详解
  • Android项目实战之仿网易顶部导航栏效果
  • Android实现顶部导航栏可点击可滑动效果(仿微信仿豆瓣网)
  • Android中TabLayout+ViewPager 简单实现app底部Tab导航栏
  • Android design包自定义tablayout的底部导航栏的实现方法
  • Android实现沉浸式导航栏实例代码
(0)

相关推荐

  • Android仿网易客户端顶部导航栏效果

    最近刚写了一个网易客户端首页导航条的动画效果,现在分享出来给大家学习学习.我说一下这个效果的核心原理.下面是效果图: 首先是布局,这个布局是我从网易客户端反编译后弄来的.大家看后应该明白,布局文件如下: <FrameLayout android:id="@id/column_navi" android:layout_width="fill_parent" android:layout_height="wrap_content" androi

  • Android design包自定义tablayout的底部导航栏的实现方法

    以前做项目大多用的radiobutton,今天用tablayout来做一个tab切换页面的的效果. 实现的效果就是类似QQ.微信的页面间(也就是Fragment间)的切换.如图: 布局只要一个tablayout <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id=&

  • Android中TabLayout+ViewPager 简单实现app底部Tab导航栏

    前言 在谷歌发布Android Design Support Library之前,app底部tab布局的实现方法就有很多种,其中有RadioGroup+FrameLayout.TabHost+Fragment.FragmentPagerAdapter+ViewPager等方法,虽然这些方法虽然能达到同样的效果,但我个人总觉得有些繁琐.然而,Google在2015的IO大会上,给开发者们带来了全新的Android Design Support Library,里面包含了许多新控件,这些新控件有许多

  • Android实现底部导航栏功能(选项卡)

    现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个底部的导航栏的功能. 我们先看下该demo实例的框架图: 其中各个类的作用以及资源文件就不详细解释了,还有资源图片(在该Demo中借用了其它应用程序的资源图片)也不提供了,大家可以自行更换自己需要的资源图片.直接上各个布局文件或各个类的代码: 1. res/layout目录下的 maintabs.xml 源码: <?xml version="1.0&q

  • Android实现顶部导航栏可点击可滑动效果(仿微信仿豆瓣网)

    使用ViewPager,PagerSlidingTabStrip,SwipeRefreshLayout打造一款可以点击可以侧滑的顶部导航栏. 先简单介绍一下所用的两个个开源库. PagerSlidingTabStrip Github地址 用法: 1.向app Module中的build.gradle中添加依赖 dependencies { compile 'com.astuetz:pagerslidingtabstrip:1.0.1' } 2.把PagerSlidingTabStrip这个控件添

  • Android实现沉浸式通知栏通知栏背景颜色跟随app导航栏背景颜色而改变

    最近好多app都已经满足了沉浸式通知栏, 所谓沉浸式通知栏:就是把用来导航的各种界面操作空间隐藏在以程序内容为主的情景中,通过相对"隐形"的界面来达到把用户可视范围最大化地用到内容本身上. 而最新安卓4.4系统的通知栏沉浸模式就是在软件打开的时候通知栏和软件顶部颜色融为一体,这样不仅可以使软件和系统本身更加融为一体. 就是手机的通知栏的颜色不再是白色.黑色简单的两种了,本人用的小米4手机,米4手机中的自带软件都支持沉浸式通知栏, 举个例子:大家可以看一下自己的qq,它的标题的背景颜色是

  • Android 沉浸式状态栏与隐藏导航栏实例详解

    1 前言 一般我们在Android的APP开发中,APP的界面如下: 可以看到,有状态栏.ActionBar(ToolBar).导航栏等,一般来说,APP实现沉浸式有三种需求:沉浸式状态栏,隐藏导航栏,APP全屏 沉浸式状态栏是指状态栏与ActionBar颜色相匹配, 隐藏导航栏不用多说,就是将导航栏隐藏,去掉下面的黑条. APP全屏是指将状态栏与导航栏都隐藏,例如很多游戏界面,都是APP全屏. 所以,在做这一步时,关键要问清楚产品狗的需求,免得白费功夫. 下面,分别来介绍这三种方式的实现. 2

  • Android项目实战之仿网易顶部导航栏效果

    随着时间的推移现在的软件要求显示的内容越来越多,所以要在小的屏幕上能够更好的显示更多的内容,首先我们会想到底部菜单栏,但是有时候想网易新闻要显示的内容太多,而且又想在主页面全部显示出来,所以有加了顶部导航栏,但是Android这样的移动设备内存是受限的,那么多界面缓存到内存中,很容易导致内存溢出,这个是比较致命的,所以不得不考虑.虽然我在之前也做过网易的顶部导航栏但是方式并不好,就像使用viewpager做一些复杂的界面由于图片占用内存过多,很容易导致内存溢出,学习了今天的内容大家做一下对比相信

  • Android程序开发之Fragment实现底部导航栏实例代码

    流行的应用的导航一般分为两种,一种是底部导航,一种是侧边栏. 说明 IDE:AS,Android studio; 模拟器:genymotion; 实现的效果,见下图. 具体实现 为了讲明白这个实现过程,我们贴出来的代码多一写,这样更方便理解 [最后还会放出完整的代码实现] .看上图的界面做的比较粗糙,但实现过程的骨架都具有了,想要更完美的设计,之后自行完善吧 ^0^. 布局 通过观察上述效果图,发现任意一个选项页面都有三部分组成: 顶部去除ActionBar后的标题栏: 中间一个Fragment

  • Android实现沉浸式导航栏实例代码

    废话不多说了,直接给大家贴代码了,具体代码如下所示: private SystemBarTintManager tintManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // getWindow().addFlags(WindowManager.Layo

随机推荐