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

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992

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

先看一下实现的效果吧。

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

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

https://github.com/ZhaoKaiQiang/IndicatorNavigationBar

时间: 2024-08-01 21:03:32

带有指示器的自定义底部导航栏的实现的相关文章

自定义底部导航栏(tabBar)

前言如果大家用过微信提供的tabBar就会发现,他的tabBar有很大的局限性.暂且不说样式局限性了,他提供的app.json配置文件中没有function.这也就意味着使用它提供的这个组件,你只能用于跳转页面,不能干其它的事情 我YY的 以下是代码说明:小程序的很大异步分思想体现了封装,以提高复用性.对此,一些简单代码我也封装了,考虑到了以后维护的方便性目录结构如下: 图片配置文件:imgURI.js(由于小程序不支持xml和读取本地json,故用js代替) 1 var host="/img/

再谈小程序自定义底部导航

小程序自定义tabBar再探索 前言 最近有很多微信开发者朋友在QQ上加我好友,忽然意识到大家对微信自定义底部导航栏需求还是挺大的,故而再次整理下底部导航栏组件开发思路.和之前的文章还是有些区别,并且底部导航栏组件增加新的特性以及一些优化开发体验的骚操作. 技术选型 与之前不同,现在我们有两种方法实现自定义底部导航栏,因为小程序在2.5.0开始支持自定义底部导航栏了戳此处看文档,所以我们现在的可选方案为: 通过HideTabBar接口hack底部导航栏 通过小程序支持配置实现底部导航栏 下面根据

uni-app添加自定义底部导航栏,实现根据权限动态切换底部栏目的功能

uni-app针对底部导航栏TabBar,只提供了动态修改样式文字和图标的API,并没有提供动态修改某个栏目的跳转链接.追加或者删除某个栏目的功能. 问题阐述:实际开发的项目中的确需要判断登录账户的权限,来动态显示某两个,或者某三个栏目 如:管理用户显示[首页,管理,我的],普通用户显示[首页,我的],中间的管理页面,就得动态判断是否要追加了 解决方案:隐藏原有的tabBar,添加自定义的底部导航栏 1.思路:参照原来导航栏的写法,延用原来TabBar的样式布局,在每个栏目的首页添加自定义导航栏

Android基础入门教程——5.2.3 Fragment实例精讲——底部导航栏的实现(方法3)

Android基础入门教程--5.2.3 Fragment实例精讲--底部导航栏的实现(方法3) 标签(空格分隔): Android基础入门教程 本节引言 前面我们已经跟大家讲解了实现底部导航栏的两种方案,但是这两种方案只适合普通的情况,如果 是像新浪微博那样的,想在底部导航栏上的item带有一个红色的小点,然后加上一个消息数目这样, 前面两种方案就显得无力了,我们来看看别人的APP是怎么做的,打开手机的开发者选项,勾选里面的: 显示布局边界,然后打开我们参考的那个App,可以看到底部导航栏是这

仿Android印象笔记底部导航栏

最近用上了印象笔记,觉得android 版的底部导航栏挺不错的,好多应用里面都有用到,想着自己动手实现一下,不多说,先上图: 要完成这样的效果.需要自定义ViewGroup. 1.onMeasure(测量过程) 2.onLayout(布局) 3.添加动画 onMeasure(测量过程) @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int count = getChildCoun

Android开源项目——带图标文字的底部导航栏IconTabPageIndicator

接下来的博客计划是,在<Android官方技术文档翻译>之间会发一些Android开源项目的介绍,直接剩下的几篇Android技术文档发完,然后就是Android开源项目和Gradle翻译了.当然,其他的文章笔记也会偶尔发一下. 本文原创,转载请注明在CSDN上的出处: http://blog.csdn.net/maosidiaoxian/article/details/42638245 简介 本篇文章介绍的是一个底部导航栏,叫IconTabPageIndicator,一个带图标文字的导航栏.

底部导航栏使用BottomNavigationBar

1.github地址 https://github.com/zhouxu88/BottomNavigationBar 2.基本使用 2,1添加依赖 implementation 'com.ashokvarma.android:bottom-navigation-bar:2.0.5' 2.2布局中使用 <com.ashokvarma.bottomnavigation.BottomNavigationBar android:layout_width="match_parent" an

实现底部导航栏

许多的App都使用底部导航栏来实现导航功能,我们可以使用RadioGroup+RadioButton的形式或者直接Button数组的方式实现,而谷歌官方提供了FragmentTabHost来方便快捷实现底部导航栏. android.support.v4.app.FragmentTabHost 主要代码: fragmentTabHost.setup(this, getSupportFragmentManager(), R.id.layout_content); for (int i = 0; i 

Android实习札记(5)---Fragment之底部导航栏的实现

Android实习札记(5)---Fragment之底部导航栏的实现 --转载请注明出处:coder-pig 在Part 4我们回顾了一下Fragment的基本概念,在本节中我们就来学习Fragment应用的简单例子吧! 就是使用Fragment来实现简单的底部导航栏,先贴下效果图: 看上去很简单,实现起来也是很简单的哈!那么接着下来就看下实现的流程图吧: 实现流程图: 看完流程图是不是有大概的思路了,那么接着就开始代码的编写吧: 代码实现: ①先写布局,布局的话很简单,一个FrameLayou