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

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

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

    先看一下实现的效果吧。带有指示器的自定义底部导航栏的实现_第1张图片

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

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

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

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

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

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


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

[java]  view plain copy
  1. package com.example.indicatornavigationbar;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.support.v4.view.ViewPager;  
  6. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  7. import android.util.DisplayMetrics;  
  8. import android.view.Gravity;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.view.ViewGroup;  
  12. import android.view.animation.Animation;  
  13. import android.view.animation.TranslateAnimation;  
  14. import android.widget.ImageView;  
  15. import android.widget.ImageView.ScaleType;  
  16. import android.widget.LinearLayout;  
  17. import android.widget.TextView;  
  18.   
  19. /** 
  20.  *  
  21.  * @ClassName: com.mengle.activity.IndicatorNavigationBar 
  22.  * @Description: 带有指示器的底部导航栏 
  23.  * @author zhaokaiqiang 
  24.  * @date 2014-10-17 上午11:07:40 
  25.  *  
  26.  */  
  27. public class IndicatorNavigationBar extends LinearLayout implements  
  28.         OnClickListener, OnPageChangeListener {  
  29.   
  30.     // 导航栏默认高度,不包括指示器高度,单位是dp  
  31.     private static final int HEIGHT_NAVIGATION_BAR = 40;  
  32.     // 指示器默认高度,单位是dp  
  33.     private static final int HEIGHT_INDICATOR = 4;  
  34.   
  35.     private Context context;  
  36.     private ViewPager viewPager;  
  37.     // 指示器  
  38.     private ImageView ivBottomLine;  
  39.     // 当前显示的index  
  40.     private int currIndex = 0;  
  41.     // 存储移动位置  
  42.     private int positions[];  
  43.     // 标题数量  
  44.     private int titleCount;  
  45.   
  46.     public IndicatorNavigationBar(Context context) {  
  47.         super(context);  
  48.         this.context = context;  
  49.     }  
  50.   
  51.     /** 
  52.      *  
  53.      * @Description: 依附到父布局上 
  54.      * @param viewGroup 
  55.      *            要依附在的父布局 
  56.      * @param titles 
  57.      *            底部显示的导航文字 
  58.      * @param viewPager 
  59.      *            绑定的ViewPager对象 
  60.      * @return void 
  61.      */  
  62.     public void attachToParent(ViewGroup viewGroup, String[] titles,  
  63.             ViewPager viewPager) {  
  64.   
  65.         this.viewPager = viewPager;  
  66.         titleCount = titles.length;  
  67.   
  68.         // 初始化主布局  
  69.         setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,  
  70.                 dip2px(HEIGHT_NAVIGATION_BAR + HEIGHT_INDICATOR)));  
  71.         setBackgroundColor(getResources().getColor(android.R.color.transparent));  
  72.         setOrientation(VERTICAL);  
  73.   
  74.         // 导航栏布局  
  75.         LinearLayout ll_navigation = new LinearLayout(context);  
  76.         ll_navigation.setLayoutParams(new LayoutParams(  
  77.                 LayoutParams.MATCH_PARENT, dip2px(HEIGHT_NAVIGATION_BAR)));  
  78.         ll_navigation.setBackgroundColor(getResources().getColor(  
  79.                 android.R.color.holo_blue_light));  
  80.         ll_navigation.setOrientation(HORIZONTAL);  
  81.   
  82.         // 生成导航按钮(TextView)  
  83.         for (int i = 0; i < titles.length; i++) {  
  84.   
  85.             TextView textView = new TextView(context);  
  86.             textView.setLayoutParams(new LayoutParams(0,  
  87.                     dip2px(HEIGHT_NAVIGATION_BAR), 1));  
  88.             textView.setText(titles[i]);  
  89.             textView.setGravity(Gravity.CENTER);  
  90.             textView.setTextSize(16);  
  91.             textView.setTextColor(getResources()  
  92.                     .getColor(android.R.color.white));  
  93.             textView.setId(i);  
  94.             textView.setOnClickListener(this);  
  95.             ll_navigation.addView(textView);  
  96.         }  
  97.         // 添加导航  
  98.         this.addView(ll_navigation);  
  99.   
  100.         // 指示器布局  
  101.         LinearLayout ll_indicator = new LinearLayout(context);  
  102.         ll_indicator.setLayoutParams(new LayoutParams(  
  103.                 LayoutParams.MATCH_PARENT, dip2px(HEIGHT_INDICATOR)));  
  104.         ll_indicator.setBackgroundColor(getResources().getColor(  
  105.                 android.R.color.holo_blue_light));  
  106.         ll_indicator.setOrientation(HORIZONTAL);  
  107.   
  108.         // 指示器  
  109.         ivBottomLine = new ImageView(context);  
  110.         ivBottomLine.setImageResource(android.R.color.holo_orange_light);  
  111.         ivBottomLine.setScaleType(ScaleType.MATRIX);  
  112.         ivBottomLine  
  113.                 .setLayoutParams(new LinearLayout.LayoutParams(  
  114.                         getScreenWidth(context) / titleCount,  
  115.                         dip2px(HEIGHT_INDICATOR)));  
  116.         ll_indicator.addView(ivBottomLine);  
  117.         // 添加指示器  
  118.         this.addView(ll_indicator);  
  119.   
  120.         viewGroup.addView(this);  
  121.         viewPager.setOnPageChangeListener(this);  
  122.   
  123.         // 初始化移动位置  
  124.         positions = new int[titleCount];  
  125.         positions[0] = 0;  
  126.         int distance = (int) (getScreenWidth(context) / titleCount);  
  127.         for (int i = 1; i < titleCount; i++) {  
  128.             positions[i] = distance * i;  
  129.         }  
  130.   
  131.     }  
  132.   
  133.     @Override  
  134.     public void onClick(View v) {  
  135.         viewPager.setCurrentItem(v.getId());  
  136.     }  
  137.   
  138.     @Override  
  139.     public void onPageScrollStateChanged(int arg0) {  
  140.   
  141.     }  
  142.   
  143.     @Override  
  144.     public void onPageScrolled(int position, float positionOffset,  
  145.             int positionOffsetPixels) {  
  146.   
  147.     }  
  148.   
  149.     @Override  
  150.     public void onPageSelected(int position) {  
  151.   
  152.         Animation animation = new TranslateAnimation(currIndex * positions[1],  
  153.                 positions[position], 00);  
  154.         currIndex = position;  
  155.         animation.setFillAfter(true);  
  156.         animation.setDuration(300);  
  157.         ivBottomLine.startAnimation(animation);  
  158.     }  
  159.   
  160.     private int dip2px(float dpValue) {  
  161.         final float scale = context.getResources().getDisplayMetrics().density;  
  162.         return (int) (dpValue * scale + 0.5f);  
  163.     }  
  164.   
  165.     // 获取屏幕宽度  
  166.     private int getScreenWidth(Context context) {  
  167.         DisplayMetrics dm = new DisplayMetrics();  
  168.         ((Activity) context).getWindowManager().getDefaultDisplay()  
  169.                 .getMetrics(dm);  
  170.         return dm.widthPixels;  
  171.     }  
  172. }  


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

    https://github.com/ZhaoKaiQiang/IndicatorNavigationBar


你可能感兴趣的:(带有指示器的自定义底部导航栏的实现)