Android 滑动标题导航栏【转】

来自:http://blog.csdn.net/ywl5320/article/details/51866799

现在Android应用开发中因为功能比较多所以都喜欢用viewpager+fragment的方式加入更多的页面,而每每使用这种模式,标题栏导航也是必不可少的,因此又会重复写很多导航菜单的代码,程序猿都是很懒的,都想写少量的代码就把功能实现了,更何况这都是写重复的代码,不辞辛劳的程序猿就成了CV战士了哈哈。我也是很懒的,不想每次都重复写那些没用的代码,所以就把标题导航栏这块功能封装成了一个自定义的控件,使用起来就三两句代码搞定,是不是听着很爽 反正我是觉得爽了。废话不多说,先上示例图片,所谓有图有真相:

综合类型:

Android 滑动标题导航栏【转】_第1张图片

1、第一种类型(只有滑动导航条):

Android 滑动标题导航栏【转】_第2张图片

2、第二种类型(滑动导航条有背景色)

Android 滑动标题导航栏【转】_第3张图片

3、第三种类型(滑动导航条有边距)

Android 滑动标题导航栏【转】_第4张图片

4、第四种类型(选中标题栏文字变大)

Android 滑动标题导航栏【转】_第5张图片

5、第五中类型(标题栏直接具有分隔条)

Android 滑动标题导航栏【转】_第6张图片

以上这些效果的实现代码只有下面几句(核心语句,去除初始化和布局代码):

[java]  view plain  copy
 
  1. navitationLayout.setViewPager(this, titles, viewPager, R.color.color_333333, R.color.color_2581ff, 1616012true, R.color.color_333333, 1f, 15f, 15f);  
  2.         navitationLayout.setBgLine(this1, R.color.colorAccent);  
  3.         navitationLayout.setNavLine(this3, R.color.colorPrimary, 0);  


2、实现思路:

通过我们的需求不难发现,第一要生成标题栏的每个标题(TextView),然而标题又是横向排列的,所以自然就想到了我们的线性布局(LinearLayout),通过代码动态添加标题栏到LinearLayout中;最基本的就实现了,然后再看需求,我们还需要再底部添加导航条,因为导航条在底部,然后还具有背景色,所以我们用相对布局(RelativeLayout)来布局是比较好的,这样基本框架就可以了(父布局是相对布局,里面添加包含标题栏的线性布局,再在底部添加导航条背景布局,再在导航条背景上面添加导航条)。剩下的就是颜色,长款等细节问题的处理了。

3、功能逻辑代码

(1):标题栏

[java]  view plain  copy
 
  1. private void setTitles(Context context, String[] titles, final boolean smoothScroll)  
  2.     {  
  3.         this.textViews = new TextView[titles.length];  
  4.         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,LayoutParams.MATCH_PARENT);  
  5.         params.weight = 1;  
  6.         params.gravity = Gravity.CENTER;  
  7.         // 循环,根据标题栏动态生成TextView来显示标题,每个标题栏的宽度比例为1:1,其中的内容居中。  
  8.         for(int i = 0; i < titles.length; i++)  
  9.         {  
  10.             final int index = i;  
  11.             TextView textView = new TextView(context);  
  12.             textView.setText(titles[i]);  
  13.             textView.setGravity(Gravity.CENTER);  
  14.             textViews[i] = textView;  
  15.             textViews[i].setOnClickListener(new OnClickListener() {  
  16.                 @Override  
  17.                 public void onClick(View v) {  
  18.                     viewPager.setCurrentItem(index, smoothScroll);  
  19.                     if(onTitleClickListener != null)  
  20.                     {  
  21.                         onTitleClickListener.onTitleClick(v);  
  22.                     }  
  23.                 }  
  24.             });  
  25.             titleLayout.addView(textView, params);  
  26.         }  
  27.     }  
用代码根据导航标题数量动态添加标题控件,并为每个标题添加点击事件。

(2):设置导航条背景

[java]  view plain  copy
 
  1. /** 
  2.      * 设置导航背景色 
  3.      * @param context 
  4.      * @param height 
  5.      * @param color 
  6.      */  
  7.     public void setBgLine(Context context, int height, int color)  
  8.     {  
  9.         height = dip2px(context,height);  
  10.         LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, height);  
  11.         bgLine = new View(context);  
  12.         bgLine.setLayoutParams(layoutParams);  
  13.         bgLine.setBackgroundColor(context.getResources().getColor(color));  
  14.   
  15.         LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, height);  
  16.         lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);  
  17.         addView(bgLine, lp);  
  18.     }  

也是用代码为导航条添加背景view。

(3):添加导航条

[java]  view plain  copy
 
  1. /** 
  2.      * 设置导航条颜色 
  3.      * @param context 
  4.      * @param height 
  5.      * @param color 
  6.      * @param currentPosition 
  7.      */  
  8.     public void setNavLine(Activity context, int height, int color, int currentPosition)  
  9.     {  
  10.         if(textViews != null)  
  11.         {  
  12.             navWidth = getScreenWidth(context) / textViews.length;  
  13.         }  
  14.         height = dip2px(context,height);  
  15.         System.out.println("width:" + navWidth);  
  16.   
  17.         LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, height);  
  18.         navLine = new View(context);  
  19.         navLine.setLayoutParams(layoutParams);  
  20.         navLine.setBackgroundColor(context.getResources().getColor(color));  
  21.   
  22.         LayoutParams lp = new LayoutParams(navWidth, height);  
  23.         lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);  
  24.         addView(navLine, lp);  
  25.         moveBar(navLine, navWidth, widOffset, currentPosition);  
  26.     }  
根据标题的数量计算导航条的宽度,然后设置导航条颜色和边距。

(4):移动导航条功能

[java]  view plain  copy
 
  1. private void moveBar(View bar, int width, float percent, int position) {  
  2.         RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) bar.getLayoutParams();  
  3.         int marginleft = (position) * width + (int) (width * percent);  
  4.         lp.width = width - widOffset * 2;  
  5.         lp.setMargins(marginleft + widOffset, 0, widOffset, 0);  
  6.         bar.requestLayout();  
  7.     }  
这个是结合viewpager的滑动事件的功能,根据滑动来定位导航条的位置。

(5)调用方法的设置

[java]  view plain  copy
 
  1. /** 
  2.      * 
  3.      * @param context 上下文 
  4.      * @param titles 标题栏 
  5.      * @param viewPager 
  6.      * @param unselectedcolor 未选中字体颜色 
  7.      * @param setectedcolor 选中字体颜色 
  8.      * @param txtUnselectedSize 未选中字体大小 
  9.      * @param txtSelectedSize 选中字体大小 
  10.      * @param currentPosition 当前viewpager的位置 
  11.      * @param widOffset 导航条的边距 
  12.      * @param smoothScroll 滑动类型 
  13.      */  
  14.     public void setViewPager(final Context context, String[] titles, ViewPager viewPager, final int unselectedcolor, final int setectedcolor, int txtUnselectedSize, final int txtSelectedSize, final int currentPosition, int widOffset, boolean smoothScroll)  
  15.     {  
  16.         this.viewPager = viewPager;  
  17.         this.txtUnselectedColor = unselectedcolor;  
  18.         this.txtSelectedColor = setectedcolor;  
  19.         this.txtUnselectedSize = txtUnselectedSize;  
  20.         this.txtSelectedSize = txtSelectedSize;  
  21.         this.widOffset = dip2px(context, widOffset);  
  22.   
  23.         viewPager.setCurrentItem(currentPosition);  
  24.         setTitles(context, titles, smoothScroll);  
  25.         setUnselectedTxtColor(context, unselectedcolor, txtUnselectedSize);  
  26.         setSelectedTxtColor(context, setectedcolor, txtSelectedSize, currentPosition);  
  27.         viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {  
  28.             @Override  
  29.             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
  30.                 moveBar(navLine, navWidth, positionOffset, position);  
  31.                 if(onNaPageChangeListener != null)  
  32.                 {  
  33.                     onNaPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);  
  34.                 }  
  35.             }  
  36.   
  37.             @Override  
  38.             public void onPageSelected(int position) {  
  39.                 setSelectedTxtColor(context, setectedcolor, txtSelectedSize, position);  
  40.                 if(onNaPageChangeListener != null)  
  41.                 {  
  42.                     onNaPageChangeListener.onPageSelected(position);  
  43.                 }  
  44.             }  
  45.   
  46.             @Override  
  47.             public void onPageScrollStateChanged(int state) {  
  48.                 if(onNaPageChangeListener != null)  
  49.                 {  
  50.                     onNaPageChangeListener.onPageScrollStateChanged(state);  
  51.                 }  
  52.             }  
  53.         });  
  54.     }  
这个方法就是设置各种颜色、大小和边距的方法,并且把viewpager的pagechange回调给使用者调用。


核心代码就是这样的了,其他两种类型类似,这里就不多说了,可以看源码哦。

完整项目源码下载地址:

1、CSDN:NavigationBar

2、Github:NavigationBar

欢迎各位使用和start

你可能感兴趣的:(Android)