Android自定义Tab选项卡4行代码完成调用(Fragment+ViewPager组合)

来源:互联网 发布:js 拆分数组 编辑:程序博客网 时间:2024/05/16 10:28
一、前言
     恰逢周末刚好可以抽点时间整理项目中的自定义控件。这个星期打算先从tab选项卡入手,将以前用到的Fragment,ViewPager,ImageView,TextView,RelattiveLayout等控件组合起来,形成一个TabView的java类,暴露需要设置方法方便日后能够快速的调用。顺便分享出来,一起学习。

最终的效果图
二、Demo项目结构

核心文件是TabView.java和attrs.xml文件,其它都是次要的。只需要将sms.edward.per.myapplication包下的TabView文件和values文件夹下的attrs.xml文件复制到自己的工程项目即可使用。



三、TabView控件的使用方法
(1)4行核心代码调起Tab选项卡
[java] view plain copy
print?
  1. /** 
  2.  * description: 
  3.  * <p> 
  4.  * author:Edward 
  5.  * <p> 
  6.  * 2015/11/8 
  7.  */  
  8. public class one extends FragmentActivity {  
  9.   
  10.     @Override  
  11.     protected void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.one);  
  14.   
  15.         //调起Tab的核心代码如下  
  16.         String[] tabTitle = {"首页""我""搜索"};  
  17.         TabView tabView = (TabView) findViewById(R.id.tab_view);  
  18.         //设置tab标题  
  19.         tabView.setTabTitle(tabTitle);  
  20.         tabView.setFragments(this, getFragment(tabTitle));  
  21.     }  
  22.   
  23.     public Fragment[] getFragment(String[] tabTitle) {  
  24.         Fragment[] fragments = new Fragment[tabTitle.length];  
  25.         for (int i = 0; i < tabTitle.length; i++) {  
  26.             Fragment fragment = new MyFragment();  
  27.             Bundle bundle = new Bundle();  
  28.             //设置参数,传递给Fragment页面  
  29.             bundle.putString("my", String.valueOf(i + 1));  
  30.             fragment.setArguments(bundle);  
  31.             fragments[i] = fragment;  
  32.         }  
  33.         return fragments;  
  34.     }  
  35. }  

XML布局
[html] view plain copy
print?
  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:orientation="vertical">  
  6.   
  7.     <sms.edward.per.myapplication.TabView  
  8.         android:id="@+id/tab_view"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="wrap_content" />  
  11.   
  12. </LinearLayout>  

(2)显示图标和标题
[java] view plain copy
print?
  1. /** 
  2.  * description: 
  3.  * <p> 
  4.  * author:Edward 
  5.  * <p> 
  6.  * 2015/11/8 
  7.  */  
  8. public class two extends FragmentActivity {  
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.two);  
  13.   
  14.         int[] selectedTabImg = {R.mipmap.aty_main_home, R.mipmap.aty_main_centre, R.mipmap.ic_search_blue};  
  15.         int[] selectTabImg = {R.mipmap.aty_main_home_c, R.mipmap.aty_main_centre_c, R.mipmap.ic_search_black};  
  16.         String[] tabTitle = {"首页""我""搜索"};  
  17.         TabView tabView = (TabView) findViewById(R.id.tab_view);  
  18.         //设置tab标题  
  19.         tabView.setTabTitle(tabTitle);  
  20.         //设置没有被选中的图标状态  
  21.         tabView.setSelectTabImg(selectTabImg);  
  22.         //设置被选中的图标状态  
  23.         tabView.setSelectedTabImg(selectedTabImg);  
  24.         //此处的setFragments必须最后才调用,否则上面的设置都无效  
  25.         tabView.setFragments(this, getFragment(tabTitle));  
  26.     }  
  27.   
  28.     public Fragment[] getFragment(String[] tabTitle) {  
  29.         Fragment[] fragments = new Fragment[tabTitle.length];  
  30.         for (int i = 0; i < tabTitle.length; i++) {  
  31.             Fragment fragment = new MyFragment();  
  32.             Bundle bundle = new Bundle();  
  33.             //设置参数,传递给Fragment页面  
  34.             bundle.putString("my", String.valueOf(i + 1));  
  35.             fragment.setArguments(bundle);  
  36.             fragments[i] = fragment;  
  37.         }  
  38.         return fragments;  
  39.     }  
  40. }  

布局文件和(1)相同

(3)tab放在顶部,禁止滑动,隐藏图标
[java] view plain copy
print?
  1. /** 
  2.  * description: 
  3.  * <p> 
  4.  * author:Edward 
  5.  * <p> 
  6.  * 2015/11/8 
  7.  */  
  8. public class three extends FragmentActivity {  
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.three);  
  13.   
  14.         int[] selectedTabImg = {R.mipmap.aty_main_home, R.mipmap.aty_main_centre, R.mipmap.ic_search_blue};  
  15.         int[] selectTabImg = {R.mipmap.aty_main_home_c, R.mipmap.aty_main_centre_c, R.mipmap.ic_search_black};  
  16.         String[] tabTitle = {"首页""我""搜索"};  
  17.         TabView tabView = (TabView) findViewById(R.id.tab_view);  
  18.         //设置tab标题  
  19.         tabView.setTabTitle(tabTitle);  
  20.         //设置没有被选中的图标状态  
  21.         tabView.setSelectTabImg(selectTabImg);  
  22.         //设置被选中的图标状态  
  23.         tabView.setSelectedTabImg(selectedTabImg);  
  24.         //只显示标题,有三个可选址SHOW_TITLE,SHOW_ICON,SHOW_ICON_AND_TITLE  
  25.         tabView.setIsShowIconTitle(TabView.SHOW_TITLE);  
  26.         //设置tab到顶部,只有TabView.TAB_LOCATION_TOP,TabView.TAB_LOCATION_BOTTOM可选  
  27.         tabView.setTabLocation(TabView.TAB_LOCATION_TOP);  
  28.         //设置tab整个栏的高度  
  29.         tabView.setTabHeight(30);  
  30.         //禁止ViewPager滚动,true表示可滑动,false表示不可滑动  
  31.         tabView.setIsViewPagerScrollable(false);  
  32.         //此处的setFragments必须最后才调用,否则上面的设置都无效  
  33.         tabView.setFragments(this, getFragment(tabTitle));  
  34.     }  
  35.   
  36.     public Fragment[] getFragment(String[] tabTitle) {  
  37.         Fragment[] fragments = new Fragment[tabTitle.length];  
  38.         for (int i = 0; i < tabTitle.length; i++) {  
  39.             Fragment fragment = new MyFragment();  
  40.             Bundle bundle = new Bundle();  
  41.             //设置参数,传递给Fragment页面  
  42.             bundle.putString("my", String.valueOf(i + 1));  
  43.             fragment.setArguments(bundle);  
  44.             fragments[i] = fragment;  
  45.         }  
  46.         return fragments;  
  47.     }  
  48. }  

布局文件和(1)相同

(4)设置tab的点击颜色
[java] view plain copy
print?
  1. /** 
  2.  * description: 
  3.  * <p> 
  4.  * author:Edward 
  5.  * <p> 
  6.  * 2015/11/8 
  7.  */  
  8. public class four extends FragmentActivity {  
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.four);  
  13.   
  14.         int[] selectedTabImg = {R.mipmap.aty_main_home, R.mipmap.aty_main_centre, R.mipmap.ic_search_blue};  
  15.         int[] selectTabImg = {R.mipmap.aty_main_home_c, R.mipmap.aty_main_centre_c, R.mipmap.ic_search_black};  
  16.         String[] tabTitle = {"首页""我""搜索"};  
  17.         TabView tabView = (TabView) findViewById(R.id.tab_view);  
  18.         //设置tab标题  
  19.         tabView.setTabTitle(tabTitle);  
  20.         //设置没有被选中的图标状态  
  21.         tabView.setSelectTabImg(selectTabImg);  
  22.         //设置被选中的图标状态  
  23.         tabView.setSelectedTabImg(selectedTabImg);  
  24.         //设置未选择tab的背景颜色  
  25.         tabView.setTabSelectBackgroundColorId(Color.parseColor("#DFEDDE"));  
  26.         //设置选择tab的背景颜色  
  27.         tabView.setTabSelectedBackgroundColorId(Color.parseColor("#0CAA60"));  
  28.         //设置未选择tab标题的颜色  
  29.         tabView.setSelectTextViewColorId(Color.parseColor("#858787"));  
  30.         //设置选择tab标题的颜色  
  31.         tabView.setSelectedTextViewColorId(Color.parseColor("#ffffff"));  
  32.         //此处的setFragments必须最后才调用,否则上面的设置都无效  
  33.         tabView.setFragments(this, getFragment(tabTitle));  
  34.     }  
  35.   
  36.     public Fragment[] getFragment(String[] tabTitle) {  
  37.         Fragment[] fragments = new Fragment[tabTitle.length];  
  38.         for (int i = 0; i < tabTitle.length; i++) {  
  39.             Fragment fragment = new MyFragment();  
  40.             Bundle bundle = new Bundle();  
  41.             //设置参数,传递给Fragment页面  
  42.             bundle.putString("my", String.valueOf(i + 1));  
  43.             fragment.setArguments(bundle);  
  44.             fragments[i] = fragment;  
  45.         }  
  46.         return fragments;  
  47.     }  
  48. }  

布局文件和(1)相同

(5)XML属性设置
[java] view plain copy
print?
  1. /** 
  2.  * description: 
  3.  * <p> 
  4.  * author:Edward 
  5.  * <p> 
  6.  * 2015/11/8 
  7.  */  
  8. public class five extends FragmentActivity {  
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         setContentView(R.layout.five);  
  13.   
  14.         int[] selectedTabImg = {R.mipmap.aty_main_home, R.mipmap.aty_main_centre, R.mipmap.ic_search_blue};  
  15.         int[] selectTabImg = {R.mipmap.aty_main_home_c, R.mipmap.aty_main_centre_c, R.mipmap.ic_search_black};  
  16.         String[] tabTitle = {"首页""我""搜索"};  
  17.         TabView tabView = (TabView) findViewById(R.id.tab_view);  
  18.         //设置tab标题  
  19.         tabView.setTabTitle(tabTitle);  
  20.         //设置没有被选中的图标状态  
  21.         tabView.setSelectTabImg(selectTabImg);  
  22.         //设置被选中的图标状态  
  23.         tabView.setSelectedTabImg(selectedTabImg);  
  24.         //此处的setFragments必须最后才调用,否则上面的设置都无效  
  25.         tabView.setFragments(this, getFragment(tabTitle));  
  26.     }  
  27.   
  28.     public Fragment[] getFragment(String[] tabTitle) {  
  29.         Fragment[] fragments = new Fragment[tabTitle.length];  
  30.         for (int i = 0; i < tabTitle.length; i++) {  
  31.             Fragment fragment = new MyFragment();  
  32.             Bundle bundle = new Bundle();  
  33.             //设置参数,传递给Fragment页面  
  34.             bundle.putString("my", String.valueOf(i + 1));  
  35.             fragment.setArguments(bundle);  
  36.             fragments[i] = fragment;  
  37.         }  
  38.         return fragments;  
  39.     }  
  40. }  

Xml布局代码
[html] view plain copy
print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:test="http://schemas.android.com/apk/res-auto"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical">  
  7.   
  8.     <sms.edward.per.myapplication.TabView  
  9.         android:id="@+id/tab_view"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         test:tv_Tab_Location="TAB_LOCATION_TOP"  
  13.         test:tv_Tab_Show_Cursor="true"  
  14.         test:tv_Tab_Transverse_Line_Height="2dp"  
  15.         test:tv_Tab_Show_Icon_Title="SHOW_ICON"  
  16.         test:tv_Tab_Selected_Background_Color="@color/red"  
  17.         test:tv_Tab_Title_Size="18dp"  
  18.         test:tv_Tab_Height="30dp"/>  
  19. </LinearLayout>  
四、自定义TabView控件的所有可设置方法
(1)java代码可设置的方法
[java] view plain copy
print?
  1. //设置tab标题  
  2. tabView.setTabTitle(tabTitle);  
  3. //设置没有被选中的图标状态  
  4. tabView.setSelectTabImg(selectTabImg);  
  5. //设置被选中的图标状态  
  6. tabView.setSelectedTabImg(selectedTabImg);  
  7. //设置图标与文本的间隔  
  8. tabView.setIconAndTextSpace(5);  
  9. //设置未选择tab的背景颜色  
  10. tabView.setTabSelectBackgroundColorId(Color.parseColor("#DFEDDE"));  
  11. //设置选择tab的背景颜色  
  12. tabView.setTabSelectedBackgroundColorId(Color.parseColor("#0CAA60"));  
  13. //设置未选择tab标题的颜色  
  14. tabView.setSelectTextViewColorId(Color.parseColor("#858787"));  
  15. //设置选择tab标题的颜色  
  16. tabView.setSelectedTextViewColorId(Color.parseColor("#ffffff"));  
  17. //设置图片的宽度和高度  
  18. tabView.setImgWidthAndHeight(3030);  
  19. //设置tab到顶部,有两个可选值TAB_LOCATION_TOP,TAB_LOCATION_BOTTOM  
  20. tabView.setTabLocation(TabView.TAB_LOCATION_TOP);  
  21. //是否显示游标  
  22. tabView.setIsShowCursor(true);  
  23. //设置游标颜色  
  24. tabView.setCursorBackgroundColorId(Color.RED);  
  25. //只显示标题,有三个可选址SHOW_TITLE,SHOW_ICON,SHOW_ICON_AND_TITLE  
  26. tabView.setIsShowIconTitle(TabView.SHOW_ICON_AND_TITLE);  
  27. //禁止ViewPager滚动,true表示可滑动,false表示不可滑动  
  28. tabView.setIsViewPagerScrollable(false);  
  29. //设置字体大小  
  30. tabView.setTextSize(12);  
  31. //设置tab整个栏的高度  
  32. tabView.setTabHeight(60);  
  33. //设置分割线颜色  
  34. tabView.setTabTransverseLineColor(Color.parseColor("#ffbdc0c3"));  
  35. //设置分割线高度  
  36. tabView.setTabTransverseLineHeight(3);  

五、源代码

(1)TabView.java源代码
为了减少XML文件的依赖,没有用XML文件来设置布局,基本上都是使用代码的方式来设置。所以代码量可能有点多。
[java] view plain copy
print?
  1. package sms.edward.per.myapplication;  
  2.   
  3. import android.content.Context;  
  4. import android.content.res.TypedArray;  
  5. import android.graphics.Color;  
  6. import android.support.v4.app.Fragment;  
  7. import android.support.v4.app.FragmentActivity;  
  8. import android.support.v4.app.FragmentManager;  
  9. import android.support.v4.app.FragmentPagerAdapter;  
  10. import android.support.v4.view.ViewPager;  
  11. import android.util.AttributeSet;  
  12. import android.util.DisplayMetrics;  
  13. import android.util.Log;  
  14. import android.util.TypedValue;  
  15. import android.view.Gravity;  
  16. import android.view.MotionEvent;  
  17. import android.view.View;  
  18. import android.view.ViewGroup;  
  19. import android.view.animation.Animation;  
  20. import android.view.animation.TranslateAnimation;  
  21. import android.widget.ImageView;  
  22. import android.widget.LinearLayout;  
  23. import android.widget.RelativeLayout;  
  24. import android.widget.TextView;  
  25.   
  26.   
  27. /** 
  28.  * 此Demo博客地址:http://blog.csdn.net/u012814441/article/details/49720899 
  29.  * <p> 
  30.  * description:Tab页面选项卡(Fragment+VierPager) 
  31.  * <p> 
  32.  * author:Edward 
  33.  * <p> 
  34.  * 2014/8/27 
  35.  */  
  36. public class TabView extends RelativeLayout {  
  37.     //同时显示图标和标题  
  38.     public static final int SHOW_ICON_AND_TITLE = 30;  
  39.     //只显示图标  
  40.     public static final int SHOW_ICON = 31;  
  41.     //只显示标题  
  42.     public static final int SHOW_TITLE = 32;  
  43.     //tab放在底部  
  44.     public static final int TAB_LOCATION_BOTTOM = 1;  
  45.     //tab放在顶部  
  46.     public static final int TAB_LOCATION_TOP = 2;  
  47.   
  48.     private RelativeLayout[] relativeLayouts;  
  49.     private ImageView[] imageViews;  
  50.     private TextView[] textViews;  
  51.     private Fragment[] fragments;  
  52.     private Context mContext;  
  53.     private ForbidSlideViewPager viewPager;  
  54.     private FragmentActivity fragmentActivity;  
  55.     //游标  
  56.     private View cursorImg;  
  57.     //标题  
  58.     private String[] tabTitle;  
  59.     //未点击图标  
  60.     private int[] selectTabImg;  
  61.     //已点击图标  
  62.     private int[] selectedTabImg;  
  63.     //标记旧的页面下标  
  64.     private int oldPageIndex = 0;  
  65.     //viewpager布局参数  
  66.     private LayoutParams viewPagerLayoutParams;  
  67.     //tab容器布局参数  
  68.     private LayoutParams lineTabContainerLayoutParams;  
  69.     //icon的布局参数  
  70.     private LayoutParams iconLayoutParams;  
  71.     //标题布局参数  
  72.     private LayoutParams textViewLayoutParams;  
  73.     //横线布局参数  
  74.     private LayoutParams horizontalLineLayoutParams;  
  75.     //默认字体大小为14dp  
  76.     private int textSize = 14;  
  77.     //设置图片的宽度和高度,默认为25dp  
  78.     private int imgWidth = 25, imgHeight = 25;  
  79.     //Tab的高度  
  80.     private int tabHeight = 60;  
  81.     //tab横线颜色,默认为浅蓝色  
  82.     private int tabTransverseLineColor = Color.parseColor("#ffbdc0c3");  
  83.     //tab横线高度,默认为1  
  84.     private int tabTransverseLineHeight = 1;  
  85.     //文本的颜色,默认为黑色  
  86.     private int selectTextViewColorId = Color.parseColor("#000000");  
  87.     //选中文本的颜色,默认为浅蓝色  
  88.     private int selectedTextViewColorId = Color.parseColor("#31b2f7");  
  89.     //是否显示Iicon或title,默认为两个都显示  
  90.     private int isShowIconTitle = 30;  
  91.     //tab未点击的背景颜色  
  92.     private int tabSelectBackgroundColorId = Color.parseColor("#e8ebee");  
  93.     //tab已点击的背景颜色  
  94.     private int tabSelectedBackgroundColorId = Color.parseColor("#EBF5FB");  
  95.     //图标与文本的间距,默认为5dp  
  96.     private int iconAndTextSpace = 5;  
  97.     //偏移量,默认为0  
  98.     private int offset = 0;  
  99.     //是否显示游标,默认为不显示  
  100.     private boolean isShowCursor = false;  
  101.     //ViewPager是否可滚动,默认为可滚动  
  102.     private boolean isViewPagerScrollable = true;  
  103.     //tab横线控件  
  104.     private View horizontalLine;  
  105.     //tab容器  
  106.     private LinearLayout lineTabContainer;  
  107.     //创建LinearLayout用来包裹图片和文本。  
  108.     private LinearLayout lineVerticalImgTxt;  
  109.     //tab的位置,默认为底部  
  110.     private int tabLocation = 1;  
  111.   
  112.   
  113.     //设置是否显示icon和标题  
  114.     public void setIsShowIconTitle(int isShowIconTitle) {  
  115.         this.isShowIconTitle = isShowIconTitle;  
  116.         //检查用户传入的值是否在指定的范围之内。如果不在指定范围,则默认初始值  
  117.         switch (isShowIconTitle) {  
  118.             case SHOW_ICON_AND_TITLE:  
  119.                 break;  
  120.             case SHOW_ICON:  
  121.                 break;  
  122.             case SHOW_TITLE:  
  123.                 break;  
  124.             default:  
  125.                 //默认为同时显示图标和标题  
  126.                 this.isShowIconTitle = 30;  
  127.                 break;  
  128.         }  
  129.     }  
  130.   
  131.     //设置Tab位置  
  132.     public void setTabLocation(int tabLocation) {  
  133.         this.tabLocation = tabLocation;  
  134.   
  135.     }  
  136.   
  137.     //设置ViewPager滚动  
  138.     public void setIsViewPagerScrollable(boolean isViewPagerScrollable) {  
  139.         this.isViewPagerScrollable = isViewPagerScrollable;  
  140.     }  
  141.   
  142.     //设置显示游标  
  143.     public void setIsShowCursor(boolean isShowCursor) {  
  144.         this.isShowCursor = isShowCursor;  
  145.     }  
  146.   
  147.     //游标颜色  
  148.     private int cursorBackgroundColorId = Color.parseColor("#31b2f7");  
  149.   
  150.     //设置游标颜色  
  151.     public void setCursorBackgroundColorId(int cursorBackgroundColorId) {  
  152.         this.cursorBackgroundColorId = cursorBackgroundColorId;  
  153.     }  
  154.   
  155.     //设置间距  
  156.     public void setIconAndTextSpace(int iconAndTextSpace) {  
  157.         this.iconAndTextSpace = iconAndTextSpace;  
  158.     }  
  159.   
  160.     //设置未点击的背景颜色  
  161.     public void setTabSelectBackgroundColorId(int tabSelectBackgroundColorId) {  
  162.         this.tabSelectBackgroundColorId = tabSelectBackgroundColorId;  
  163.     }  
  164.   
  165.     //设置已点击的背景颜色  
  166.     public void setTabSelectedBackgroundColorId(int tabSelectedBackgroundColorId) {  
  167.         this.tabSelectedBackgroundColorId = tabSelectedBackgroundColorId;  
  168.     }  
  169.   
  170.     //设置文本颜色  
  171.     public void setSelectTextViewColorId(int selectTextViewColorId) {  
  172.         this.selectTextViewColorId = selectTextViewColorId;  
  173.     }  
  174.   
  175.     //设置选中文本颜色  
  176.     public void setSelectedTextViewColorId(int selectedTextViewColorId) {  
  177.         this.selectedTextViewColorId = selectedTextViewColorId;  
  178.     }  
  179.   
  180.     //设置横线高度  
  181.     public void setTabTransverseLineHeight(int tabTransverseLineHeight) {  
  182.         this.tabTransverseLineHeight = tabTransverseLineHeight;  
  183.     }  
  184.   
  185.     //设置横线颜色  
  186.     public void setTabTransverseLineColor(int tabTransverseLineColor) {  
  187.         this.tabTransverseLineColor = tabTransverseLineColor;  
  188.     }  
  189.   
  190.     //设置tab的高度  
  191.     public void setTabHeight(int tabHeight) {  
  192.         this.tabHeight = tabHeight;  
  193.     }  
  194.   
  195.     //设置图片宽度和高度  
  196.     public void setImgWidthAndHeight(int imgWidth, int imgHeight) {  
  197.         this.imgWidth = imgWidth;  
  198.         this.imgHeight = imgHeight;  
  199.     }  
  200.   
  201.     //设置按下图标,必须实现  
  202.     public void setSelectedTabImg(int[] selectedTabImg) {  
  203.         this.selectedTabImg = selectedTabImg;  
  204.     }  
  205.   
  206.     //设置原始图标,,必须实现  
  207.     public void setSelectTabImg(int[] selectTabImg) {  
  208.         this.selectTabImg = selectTabImg;  
  209.     }  
  210.   
  211.     //设置标题,必须实现  
  212.     public void setTabTitle(String[] tabTitle) {  
  213.         this.tabTitle = tabTitle;  
  214.     }  
  215.   
  216.     //设置页面,必须实现  
  217.     public void setFragments(FragmentActivity fragmentActivity, Fragment[] fragments) {  
  218.         this.fragments = fragments;  
  219.         this.fragmentActivity = fragmentActivity;  
  220.         //初始化布局  
  221.         initView();  
  222.         //初始化第一个Tab背景  
  223.         setImgAndFont(0, selectedTextViewColorId, tabSelectedBackgroundColorId, false);  
  224.     }  
  225.   
  226.     //设置字体大小  
  227.     public void setTextSize(int textSize) {  
  228.         this.textSize = textSize;  
  229.   
  230.         invalidate();  
  231.     }  
  232.   
  233.     /** 
  234.      * 构造方法 
  235.      * 
  236.      * @param context 
  237.      */  
  238.     public TabView(Context context) {  
  239.         this(context, null);  
  240.     }  
  241.   
  242.     /** 
  243.      * 构造方法 
  244.      * 
  245.      * @param context 
  246.      * @param attrs 
  247.      */  
  248.     public TabView(Context context, AttributeSet attrs) {  
  249.         this(context, attrs, 0);  
  250.     }  
  251.   
  252.     /** 
  253.      * 构造方法 
  254.      * 
  255.      * @param context 
  256.      * @param attrs 
  257.      * @param defStyleAttr 
  258.      */  
  259.     public TabView(Context context, AttributeSet attrs, int defStyleAttr) {  
  260.         super(context, attrs, defStyleAttr);  
  261.         mContext = context;  
  262.   
  263.         TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.TabView);  
  264.   
  265.   
  266.         textSize = typedArray.getDimensionPixelSize(R.styleable.TabView_tv_Tab_Title_Size, 14);  
  267.         tabHeight = typedArray.getDimensionPixelSize(R.styleable.TabView_tv_Tab_Height, 60);  
  268.         selectTextViewColorId = typedArray.getColor(R.styleable.TabView_tv_Tab_Select_TextView_Color, Color.parseColor("#000000"));  
  269.         selectedTextViewColorId = typedArray.getColor(R.styleable.TabView_tv_Tab_Selected_TextView_Color, Color.parseColor("#31b2f7"));  
  270.         tabLocation = typedArray.getInt(R.styleable.TabView_tv_Tab_Location, TAB_LOCATION_BOTTOM);  
  271.         //处理用户输入的数值,如果不在指定范围之内,则默认TAB_LOCATION_BOTTOM  
  272.         switch (tabLocation) {  
  273.             case TAB_LOCATION_BOTTOM:  
  274.                 break;  
  275.             case TAB_LOCATION_TOP:  
  276.                 break;  
  277.             default:  
  278.                 tabLocation = TAB_LOCATION_BOTTOM;  
  279.                 break;  
  280.         }  
  281.         isShowIconTitle = typedArray.getInt(R.styleable.TabView_tv_Tab_Show_Icon_Title, SHOW_ICON_AND_TITLE);  
  282.         //处理用户输入的数值,如果不在指定范围之内,默认SHOW_ICON_AND_TITLE  
  283.         switch (isShowIconTitle) {  
  284.             case SHOW_ICON_AND_TITLE:  
  285.                 break;  
  286.             case SHOW_TITLE:  
  287.                 break;  
  288.             case SHOW_ICON:  
  289.                 break;  
  290.             default:  
  291.                 tabLocation = SHOW_ICON_AND_TITLE;  
  292.                 break;  
  293.         }  
  294.         //默认允许ViewPager滑动  
  295.         isViewPagerScrollable = typedArray.getBoolean(R.styleable.TabView_tv_ViewPage_Scrollable, true);  
  296.         isShowCursor = typedArray.getBoolean(R.styleable.TabView_tv_Tab_Show_Cursor, false);  
  297.         cursorBackgroundColorId = typedArray.getColor(R.styleable.TabView_tv_Tab_Show_Cursor_Color, Color.parseColor("#31b2f7"));  
  298.         tabSelectBackgroundColorId = typedArray.getColor(R.styleable.TabView_tv_Tab_Select_Background_Color, Color.parseColor("#e8ebee"));  
  299.         tabSelectedBackgroundColorId = typedArray.getColor(R.styleable.TabView_tv_Tab_Selected_Background_Color, Color.parseColor("#EBF5FB"));  
  300.         imgWidth = typedArray.getDimensionPixelSize(R.styleable.TabView_tv_Tab_Img_Width, 25);  
  301.         imgHeight = typedArray.getDimensionPixelSize(R.styleable.TabView_tv_Tab_Img_Height, 25);  
  302.         tabTransverseLineColor = typedArray.getColor(R.styleable.TabView_tv_Tab_Transverse_Line_Color, Color.parseColor("#ffbdc0c3"));  
  303.         tabTransverseLineHeight = typedArray.getDimensionPixelSize(R.styleable.TabView_tv_Tab_Transverse_Line_Height, 1);  
  304.         iconAndTextSpace = typedArray.getDimensionPixelSize(R.styleable.TabView_tv_Tab_Icon_Title_Space, 5);  
  305.         typedArray.recycle();  
  306.     }  
  307.   
  308.     /** 
  309.      * 适配器 
  310.      */  
  311.     public class TabViewFragmentPagerAdapter extends FragmentPagerAdapter {  
  312.         private Fragment[] fragments;  
  313.   
  314.         public TabViewFragmentPagerAdapter(FragmentManager fm, Fragment[] fragments) {  
  315.             super(fm);  
  316.             this.fragments = fragments;  
  317.         }  
  318.   
  319.         @Override  
  320.         public Fragment getItem(int position) {  
  321.             return fragments[position];  
  322.         }  
  323.   
  324.         @Override  
  325.         public int getCount() {  
  326.             return fragments.length;  
  327.         }  
  328.     }  
  329.   
  330.   
  331.     /** 
  332.      * ViewPager监听器 
  333.      */  
  334.     public class ViewPagerOnPagerChangeListener implements ViewPager.OnPageChangeListener {  
  335.   
  336.         @Override  
  337.         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
  338.   
  339.         }  
  340.   
  341.         @Override  
  342.         public void onPageSelected(int position) {  
  343.             //如果有显示游标就显示游标的移动动画  
  344.             if (isShowCursor) {  
  345.                 Animation animation = new TranslateAnimation(oldPageIndex * offset, position * offset, 00);  
  346.                 animation.setFillAfter(true);  
  347.                 animation.setDuration(100);  
  348.                 cursorImg.setAnimation(animation);  
  349.             }  
  350.             changePage(position);  
  351.         }  
  352.   
  353.         @Override  
  354.         public void onPageScrollStateChanged(int state) {  
  355.   
  356.         }  
  357.     }  
  358.   
  359.     /** 
  360.      * 设置ViewPager控件 
  361.      */  
  362.     public void setViewPagerWidget() {  
  363.         //设置FrameLayout控件  
  364.         viewPager = new ForbidSlideViewPager(mContext);  
  365.         //默认到第一页  
  366.         viewPager.setCurrentItem(0);  
  367.         //设置ViewPager是否可滚动  
  368.         viewPager.setIsScrollable(isViewPagerScrollable);  
  369.   
  370.         viewPager.setAdapter(new TabViewFragmentPagerAdapter(fragmentActivity.getSupportFragmentManager(), fragments));  
  371.         viewPager.addOnPageChangeListener(new ViewPagerOnPagerChangeListener());  
  372.         //设置ID为5  
  373.         viewPager.setId(Integer.valueOf(5));  
  374.         viewPagerLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);  
  375.         //将此控件放在横线上面。  
  376. //        viewPagerLayoutParams.addRule(RelativeLayout.ABOVE, 2);  
  377.         viewPager.setLayoutParams(viewPagerLayoutParams);  
  378.         addView(viewPager);  
  379.     }  
  380.   
  381.     /** 
  382.      * 设置lineTabContainer控件 
  383.      */  
  384.     public void sheLineTabContainerWidget() {  
  385.         //lineTabContainer容器  
  386.         lineTabContainer = new LinearLayout(mContext);  
  387.         //水平布局  
  388.         lineTabContainer.setOrientation(LinearLayout.HORIZONTAL);  
  389.         //设置Tab容器的高度  
  390.         lineTabContainerLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, NumberValueChangeDp(tabHeight));  
  391.         //将这个控件的ID设置为1  
  392.         lineTabContainer.setId(Integer.valueOf(1));  
  393.         //将LinearLayout放置于父控件的底部  
  394. //        lineTabContainerLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);  
  395.         lineTabContainer.setLayoutParams(lineTabContainerLayoutParams);  
  396.   
  397.         addView(lineTabContainer);  
  398.     }  
  399.   
  400.   
  401.     /** 
  402.      * 初始化布局 
  403.      */  
  404.     public void initView() {  
  405.         //设置ViewPager控件  
  406.         setViewPagerWidget();  
  407.         //设置lineTabContainer控件  
  408.         sheLineTabContainerWidget();  
  409.         //设置横线  
  410.         setHorizontalLine();  
  411.         //创建游标  
  412.         createCursor();  
  413.   
  414.         //初始化数组  
  415.         relativeLayouts = new RelativeLayout[tabTitle.length];  
  416.         imageViews = new ImageView[tabTitle.length];  
  417.         textViews = new TextView[tabTitle.length];  
  418.         //注意此处,设置每个RelativeLayout比重为1  
  419.         LinearLayout.LayoutParams tabRelaLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);  
  420.   
  421.         //根据外面传进来的数据进行布局  
  422.         for (int i = 0; i < tabTitle.length; i++) {  
  423.             //设置RelativeLayout布局  
  424.             RelativeLayout rela = new RelativeLayout(mContext);  
  425.             rela.setOnClickListener(new ClickListener(i));  
  426.             //设置没有选中的背景颜色  
  427.             rela.setBackgroundColor(tabSelectBackgroundColorId);  
  428.             //设置内部控件垂直,水平布局(注意不能使用RelativeLayout.CENTER_VERTICAL)  
  429.             rela.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);  
  430.             lineTabContainer.addView(rela, tabRelaLayoutParams);  
  431.   
  432.             lineVerticalImgTxt = new LinearLayout(mContext);  
  433.             lineVerticalImgTxt.setOrientation(LinearLayout.VERTICAL);  
  434.             //设置垂直方向布局。  
  435.             lineVerticalImgTxt.setGravity(Gravity.CENTER_HORIZONTAL);  
  436.   
  437.             if (selectTabImg != null && selectTabImg.length > 0) {  
  438.                 //设置图片  
  439.                 ImageView imgViewIcon = new ImageView(mContext);  
  440.                 //默认为不显示  
  441.                 imgViewIcon.setVisibility(View.GONE);  
  442.                 if (isShowIconTitle == SHOW_ICON_AND_TITLE) {  
  443.                     imgViewIcon.setVisibility(View.VISIBLE);  
  444.                 } else if (isShowIconTitle == SHOW_ICON) {  
  445.                     imgViewIcon.setVisibility(View.VISIBLE);  
  446.                 }  
  447. //                imgViewIcon.setVisibility(isHideIcon ? View.GONE : View.VISIBLE);  
  448.                 imgViewIcon.setBackgroundResource(selectTabImg[i]);  
  449.                 iconLayoutParams = new LayoutParams(NumberValueChangeDp(imgWidth), NumberValueChangeDp(imgHeight));  
  450.   
  451.                 //将图片添加到lineVerticalImgTxt  
  452.                 lineVerticalImgTxt.addView(imgViewIcon, iconLayoutParams);  
  453.                 imageViews[i] = imgViewIcon;  
  454.             }  
  455.   
  456.             //设置tab标题  
  457.             TextView tabTitle = new TextView(mContext);  
  458.             //默认为不显示  
  459.             tabTitle.setVisibility(View.GONE);  
  460.             if (isShowIconTitle == SHOW_ICON_AND_TITLE) {  
  461.                 tabTitle.setVisibility(View.VISIBLE);  
  462.             } else if (isShowIconTitle == SHOW_TITLE) {  
  463.                 tabTitle.setVisibility(View.VISIBLE);  
  464.             }  
  465.             //判断tab标题是否应该隐藏  
  466. //            tabTitle.setVisibility(isHideText ? View.GONE : View.VISIBLE);  
  467.             tabTitle.setPadding(0, iconAndTextSpace, 00);  
  468.             tabTitle.setText(this.tabTitle[i]);  
  469.             //设置字体大小  
  470.             tabTitle.setTextSize(textSize);  
  471.             //如果是第一个选项,则将这个选项的tab标题,设置为选中的颜色  
  472.             tabTitle.setTextColor(i == 0 ? selectedTextViewColorId : selectTextViewColorId);  
  473.             textViewLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  474.             tabTitle.setLayoutParams(textViewLayoutParams);  
  475.             lineVerticalImgTxt.addView(tabTitle);  
  476.   
  477.             //设置布局参数  
  478.             LayoutParams tabRela = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);  
  479.             rela.addView(lineVerticalImgTxt, tabRela);  
  480.   
  481.             relativeLayouts[i] = rela;  
  482.             textViews[i] = tabTitle;  
  483.         }  
  484.   
  485.         //设置布局的排列顺序  
  486.         if (tabLocation == TAB_LOCATION_BOTTOM) {  
  487.             viewPagerLayoutParams.addRule(RelativeLayout.ABOVE, 2);  
  488.             lineTabContainerLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);  
  489.             horizontalLineLayoutParams.addRule(RelativeLayout.ABOVE, 1);  
  490.         } else if (tabLocation == TAB_LOCATION_TOP) {  
  491.             lineTabContainerLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);  
  492.             horizontalLineLayoutParams.addRule(RelativeLayout.BELOW, 1);  
  493.             viewPagerLayoutParams.addRule(RelativeLayout.BELOW, 2);  
  494.         } else {  
  495.             Log.e("----------->""设置setTabLocation方法错误!只能是TAB_LOCATION_BOTTOM,TAB_LOCATION_TOP二选一");  
  496.         }  
  497.     }  
  498.   
  499.     /** 
  500.      * 设置横线 
  501.      */  
  502.     public void setHorizontalLine() {  
  503.         //设置横线  
  504.         horizontalLine = new View(mContext);  
  505.         //设置Tab横线颜色  
  506.         horizontalLine.setBackgroundColor(tabTransverseLineColor);  
  507.         //设置Tab横线的高度  
  508.         horizontalLineLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, NumberValueChangeDp(tabTransverseLineHeight));  
  509.         horizontalLine.setLayoutParams(horizontalLineLayoutParams);  
  510.         //将这个横线的位置放的1控件的上面  
  511. //        horizontalLineLayoutParams.addRule(RelativeLayout.ABOVE, 1);  
  512.         //将这个控件ID设置为2  
  513.         horizontalLine.setId(Integer.valueOf(2));  
  514.         addView(horizontalLine);  
  515.   
  516.     }  
  517.   
  518.     /** 
  519.      * 创建游标 
  520.      */  
  521.     public void createCursor() {  
  522.         //是否显示游标  
  523.         if (isShowCursor) {  
  524.             DisplayMetrics displayMetrics = new DisplayMetrics();  
  525.             fragmentActivity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);  
  526.             //获取屏幕宽度  
  527.             int screenWidth = displayMetrics.widthPixels;  
  528.             //得到每个tab的宽度(屏幕宽度除以tab总数)  
  529.             offset = screenWidth / tabTitle.length;  
  530.   
  531.             //设置下标  
  532.             cursorImg = new View(mContext);  
  533.             cursorImg.setBackgroundColor(cursorBackgroundColorId);  
  534.             LayoutParams cursorLayoutParams = new LayoutParams(offset, NumberValueChangeDp(tabTransverseLineHeight));  
  535.             cursorImg.setLayoutParams(cursorLayoutParams);  
  536.   
  537.             if (tabLocation == TAB_LOCATION_BOTTOM) {  
  538.                 cursorLayoutParams.addRule(RelativeLayout.BELOW, 5);  
  539.             } else if (tabLocation == TAB_LOCATION_TOP) {  
  540.                 cursorLayoutParams.addRule(RelativeLayout.BELOW, 1);  
  541.             } else {  
  542.                 Log.e("----------->""设置setTabLocation方法错误!只能是TAB_LOCATION_BOTTOM,TAB_LOCATION_TOP二选一");  
  543.             }  
  544.             addView(cursorImg);  
  545.         }  
  546.     }  
  547.   
  548.     /** 
  549.      * 点击事件 
  550.      */  
  551.     public class ClickListener implements OnClickListener {  
  552.         public int index;  
  553.   
  554.         public ClickListener(int index) {  
  555.             this.index = index;  
  556.         }  
  557.   
  558.         @Override  
  559.         public void onClick(View view) {  
  560.             changePage(index);  
  561.         }  
  562.     }  
  563.   
  564.     /** 
  565.      * 跳转页面 
  566.      * 
  567.      * @param currentPage 
  568.      */  
  569.     public void changePage(int currentPage) {  
  570.         if (oldPageIndex != currentPage) {  
  571.             //跳转页面  
  572.             viewPager.setCurrentItem(currentPage);  
  573.             //将Tab设置为原来的颜色  
  574.             setImgAndFont(oldPageIndex, selectTextViewColorId, tabSelectBackgroundColorId, true);  
  575.             //设置新的Tab颜色  
  576.             setImgAndFont(currentPage, selectedTextViewColorId, tabSelectedBackgroundColorId, false);  
  577.             oldPageIndex = currentPage;  
  578.         }  
  579.     }  
  580.   
  581.     /** 
  582.      * 设置底部图片和字体颜色 
  583.      * 
  584.      * @param index 
  585.      * @param textColorId     文本颜色 
  586.      * @param isPressStateImg 是否处于被点击状态 
  587.      */  
  588.     public void setImgAndFont(int index, int textColorId, int tabBackgroundColorId, boolean isPressStateImg) {  
  589.         if (isPressStateImg) {  
  590.             if (selectTabImg != null && selectTabImg.length > 0) {  
  591.                 //设置下一个Tab的背景图片  
  592.                 imageViews[index].setBackgroundResource(selectTabImg[index]);  
  593.             }  
  594.         } else {  
  595.             if ((selectTabImg != null && selectTabImg.length > 0) && (selectedTabImg != null && selectedTabImg.length > 0)) {  
  596.                 //设置下一个Tab的背景图片  
  597.                 imageViews[index].setBackgroundResource(selectedTabImg[index]);  
  598.             }  
  599.         }  
  600.         relativeLayouts[index].setBackgroundColor(tabBackgroundColorId);  
  601.         //设置下一个Tab的字体颜色  
  602.         textViews[index].setTextColor(textColorId);  
  603.     }  
  604.   
  605.     /** 
  606.      * 将数值转换为相应的DP值 
  607.      * 
  608.      * @param value 
  609.      * @return 
  610.      */  
  611.     public int NumberValueChangeDp(int value) {  
  612.         return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, getResources().getDisplayMetrics());  
  613.     }  
  614.   
  615.     /** 
  616.      * 重写ViewPager,禁止ViewPager滑动 
  617.      */  
  618.     public class ForbidSlideViewPager extends ViewPager {  
  619.         //是否可滚动  
  620.         private boolean isScrollable = true;  
  621.   
  622.         public ForbidSlideViewPager(Context context) {  
  623.             this(context, null);  
  624.         }  
  625.   
  626.         public ForbidSlideViewPager(Context context, AttributeSet attrs) {  
  627.             super(context, attrs);  
  628.         }  
  629.   
  630.         @Override  
  631.         public boolean onTouchEvent(MotionEvent ev) {  
  632.             if (!isScrollable) {  
  633.                 return true;  
  634.             }  
  635.             return super.onTouchEvent(ev);  
  636.         }  
  637.   
  638.         @Override  
  639.         public boolean onInterceptTouchEvent(MotionEvent ev) {  
  640.             return super.onInterceptTouchEvent(ev);  
  641.         }  
  642.   
  643.         //设置ViewPager是否可滑动  
  644.         public void setIsScrollable(boolean isScrollable) {  
  645.             this.isScrollable = isScrollable;  
  646.         }  
  647.     }  
  648. }  

(2)attr.xml文件源代码
[html] view plain copy
print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <declare-styleable name="TabView">  
  4.         <!--tab栏的高度-->  
  5.         <attr name="tv_Tab_Height" format="dimension" />  
  6.         <!--点击前,点击后标题的颜色-->  
  7.         <attr name="tv_Tab_Select_Title_Color" format="color" />  
  8.         <attr name="tv_Tab_Selected_Title_Color" format="color" />  
  9.         <!--标题的大小-->  
  10.         <attr name="tv_Tab_Title_Size" format="dimension" />  
  11.         <!--图标的宽度和高度-->  
  12.         <attr name="tv_Tab_Img_Width" format="dimension" />  
  13.         <attr name="tv_Tab_Img_Height" format="dimension" />  
  14.         <!--tab横线的高度-->  
  15.         <attr name="tv_Tab_Transverse_Line_Height" format="dimension" />  
  16.         <!--tab横线的颜色-->  
  17.         <attr name="tv_Tab_Transverse_Line_Color" format="color" />  
  18.         <!--图标和标题之间的间距-->  
  19.         <attr name="tv_Tab_Icon_Title_Space" format="dimension" />  
  20.         <!--是否显示游标-->  
  21.         <attr name="tv_Tab_Show_Cursor" format="boolean" />  
  22.         <!--游标的颜色-->  
  23.         <attr name="tv_Tab_Show_Cursor_Color" format="color" />  
  24.         <!--tab的显示位置,只能选择TAB_LOCATION_TOP或者TAB_LOCATION_BOTTOM-->  
  25.         <attr name="tv_Tab_Location" format="integer">  
  26.             <flag name="TAB_LOCATION_TOP" value="2" />  
  27.             <flag name="TAB_LOCATION_BOTTOM" value="1" />  
  28.         </attr>  
  29.         <!--显示图标和标题或者只显示图标或者只显示标题-->  
  30.         <attr name="tv_Tab_Show_Icon_Title" format="integer">  
  31.             <flag name="SHOW_ICON_AND_TITLE" value="30" />  
  32.             <flag name="SHOW_ICON" value="31" />  
  33.             <flag name="SHOW_TITLE" value="32" />  
  34.         </attr>  
  35.         <!--是否可滚动-->  
  36.         <attr name="tv_ViewPage_Scrollable" format="boolean" />  
  37.         <!--tab点击前,点击后的颜色-->  
  38.         <attr name="tv_Tab_Select_Background_Color" format="color" />  
  39.         <attr name="tv_Tab_Selected_Background_Color" format="color" />  
  40.         <!--设置字体点击前,点击后的颜色-->  
  41.         <attr name="tv_Tab_Select_TextView_Color" format="color" />  
  42.         <attr name="tv_Tab_Selected_TextView_Color" format="color" />  
  43.     </declare-styleable>  
  44. </resources>  



六、结束
感谢各位^_^
源代码请戳这里Android自定义Tab选项卡4行代码完成调用(Fragment+ViewPager组合)

0 0
原创粉丝点击