zoukankan      html  css  js  c++  java
  • android tab选项卡的使用

     项目做完了,写写博客,在项目中遇到的一些问题,或者是自己觉得很不错的东西。这一篇主要是想和大家分享一下我在项目中封装的一个东西,就是tab选项卡。先看看效果图:

    我在网上看了很多有关选项卡的demo,可是发现都不太符合我的需求,万恶的产品经理想做的效果是选项卡中的文字有多长,文字下方的线就显示多长,无奈之下,自己写了。由于项目中很多地方都有用这个东东,所以我就封装了这一个,先看看代码。

    这是封装的代码:

    public class ViewPagerIndicator extends HorizontalScrollView implements
    OnPageChangeListener, OnClickListener {

    private RelativeLayout[] tabArr;// tab数组
    private String[] tabTexts;// tab标题数组
    private int[] tabTextWidthArr;// tab标题宽度数组

    private int currTabPosition;// 当前选中的tab
    private float fromTransX;// 游标在启动动画之前的X轴坐标
    private int tabSpacing;// tab之间的间距
    private int cursorPadding;// tab默认和cursor长度一样
    private int mTextColor = getResources().getColor(R.color.gray_666666);
    private float mTextSize = 13;
    private int tabLength;// tab个数
    private int diviceWidth;// 设备宽度px
    private float fromScaleX = 1.0f;
    private int baseCursorWidth;// 初始化的游标宽度, 缩放动画每次以此为标准
    private Boolean autoArrange = true;
    private Boolean isPageFirstScrolled = true;
    private int unSelectTextColor = getResources().getColor(R.color.gray_999999); //设置选中字体的颜色
    private int selectTextColor = getResources().getColor(R.color.blue_45a7ff); //设置未选中字体的颜色


    private Context mContext;
    private ViewPager mViewPager;
    private LinearLayout tabLy;// tab的横向线性布局
    private ImageView cursor;// 游标
    private Handler handler = new Handler();
    View line;


    public ViewPagerIndicator(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    init();
    }

    public ViewPagerIndicator(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
    init();
    }

    public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
    init();
    }

    /**
    * 初始化基本布局
    */
    private void init() {
    // TODO Auto-generated method stub
    mContext = getContext();
    diviceWidth = DensityUtil.getDisplayWidth((Activity) mContext);
    // 设置属性
    this.setBackgroundColor(getResources().getColor(R.color.white));
    this.setHorizontalScrollBarEnabled(false);// 去掉滚动条
    this.setVisibility(View.GONE);
    // 加载ScrollView的内容布局
    View v = View.inflate(mContext, R.layout.viewpager_indicator_layout, null);
    tabLy = (LinearLayout) v.findViewById(R.id.main_tab);// Tab布局
    cursor = (ImageView) v.findViewById(R.id.main_cursor);// 游标

    line = v.findViewById(R.id.line); //获得中间那条线
    this.addView(v);
    }


    public void setLinevisibility(boolean isShow) {
    line.setVisibility(isShow ? View.VISIBLE : View.GONE);
    }

    /**
    * 设置参数.
    *
    * @param tabSpacing tab间距
    * @param cursorPadding 游标向左右延伸的距离, 默认为0, 也即和tab文本一样长
    * @param viewPager 设置ViewPager
    * @param tabTexts tab内容数组
    * @param autoArrange 当tab长度不足屏幕宽度时, 是否自动进行摆列, 默认为true
    */
    public void setParams(int tabSpacing, int cursorPadding, String[] tabTexts,
    ViewPager viewPager, Boolean autoArrange) {
    if (tabTexts == null || tabTexts.length < 1) {
    return;
    }
    this.tabSpacing = tabSpacing;
    this.cursorPadding = cursorPadding;
    this.tabTexts = tabTexts;
    this.mViewPager = viewPager;
    this.autoArrange = autoArrange;

    this.setVisibility(View.VISIBLE);
    initTabSpacing();
    initTabs();
    initCursor();
    onPageSelected(currTabPosition);// 初始化tab样式和动画
    if (mViewPager != null) {
    mViewPager.setOnPageChangeListener(this);
    }
    }

    /**
    * 确定tab间隙长度
    */
    private void initTabSpacing() {
    // TODO Auto-generated method stub
    tabLength = tabTexts.length;
    int tabTextsWidth = 0;// tab文本总长度
    TextView tv = new TextView(mContext);
    tabTextWidthArr = new int[tabLength];
    for (int i = 0; i < tabLength; i++) {
    tv.setTextSize(mTextSize);
    tabTextWidthArr[i] = (int) tv.getPaint().measureText(tabTexts[i]);
    tabTextsWidth += tabTextWidthArr[i];
    }
    int scrollViewWidth = tabTextsWidth + tabLength * tabSpacing;
    // 默认, tab(包括间隙)总长度小于屏幕宽度时, 重新计算间距, 让各个tab均匀填满scrollview
    if (autoArrange && scrollViewWidth < diviceWidth) {
    tabSpacing = (diviceWidth - tabTextsWidth) / tabLength;
    }
    }

    /**
    * 初始化Tab
    */
    private void initTabs() {
    tabLy.removeAllViews();
    tabArr = new RelativeLayout[tabLength];
    TextView tabTextView = null;
    for (int i = 0; i < tabLength; i++) {
    // 初始化tabArr
    LinearLayout.LayoutParams tabParam = new LinearLayout.LayoutParams(
    tabTextWidthArr[i] + tabSpacing, LayoutParams.MATCH_PARENT);
    tabArr[i] = (RelativeLayout) View.inflate(mContext,
    R.layout.viewpager_indicator_tab, null);
    tabArr[i].setLayoutParams(tabParam);
    tabArr[i].setTag(i);
    tabArr[i].setOnClickListener(this);
    // 初始化tabTextViewArr
    tabTextView = (TextView) tabArr[i].findViewById(R.id.tab_tv);
    tabTextView.setTextSize(mTextSize);
    tabTextView.setTextColor(mTextColor);
    tabTextView.setText(tabTexts[i]);
    // 添加子tab
    tabLy.addView(tabArr[i], i);
    }
    }

    @Override
    public void onClick(View v) {
    int i = (Integer) v.getTag();
    setTabClick(i);
    }

    /**
    * 设置当前Tab点击时事件
    *
    * @param position
    */
    private void setTabClick(int position) {
    // 如果点击的为当前的Tab,则滚回到顶部, 否则切换
    if (position == currTabPosition) {

    } else {
    mViewPager.setCurrentItem(position);
    }
    }

    /**
    * 初始化cursor长度
    */
    private void initCursor() {
    // TODO Auto-generated method stub
    baseCursorWidth = tabTextWidthArr[currTabPosition] + cursorPadding;
    RelativeLayout.LayoutParams cursorLp = (RelativeLayout.LayoutParams) cursor
    .getLayoutParams();
    cursorLp.width = baseCursorWidth;
    cursor.setLayoutParams(cursorLp);
    }

    @Override
    public void onPageScrollStateChanged(int arg0) {
    }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
    }

    @Override
    public void onPageSelected(final int position) {
    // TODO Auto-generated method stub
    currTabPosition = position;
    setTabStyle(position);// 改变tab字体颜色
    handler.post(new Runnable() {

    @Override
    public void run() {
    setTabAnimation(position);
    }
    });
    }


    /**
    * 设置未选中tab字体的颜色
    */
    public void setUnSelectTextColor(int UnSelectTextColor) {
    this.unSelectTextColor = UnSelectTextColor;
    }

    /**
    * 设置选中tab字体的颜色
    */
    public void setSelectTextColor(int selectTextColor) {
    this.selectTextColor = selectTextColor;
    }

    /**
    * 设置tab字体的大小
    */
    public void setTextSize(int textSize){
    this.mTextSize = textSize;
    }


    /**
    * 设置选中项背景和字体颜色
    *
    * @param position
    */
    private void setTabStyle(int position) {
    // 还原Tab的背景和字体颜色
    for (int i = 0; i < tabLength; i++) {
    ((TextView) tabArr[i].getChildAt(0)).setTextColor(unSelectTextColor);
    }
    // 改变 选中文本的颜色, 同时红点消失
    ((TextView) tabArr[position].getChildAt(0)).setTextColor(selectTextColor);
    }

    /**
    * 设置tab的动画
    *
    * @param position
    */
    private void setTabAnimation(final int position) {
    // 选中的tab中心位置到scrollview最左边位置的距离
    int offset = 0;
    for (int i = 0; i < position; i++) {
    offset += tabTextWidthArr[i] + tabSpacing;
    }
    offset += (tabTextWidthArr[position] + tabSpacing) / 2;
    // tab滚动到居中位置
    int scrollOffset = offset - diviceWidth / 2 <= 0 ? 0 : offset
    - diviceWidth / 2;
    smoothScrollTo(scrollOffset, 0);

    // 移动动画
    offset -= (tabTextWidthArr[0] / 2 + cursorPadding / 2);

    Animation translateAnim = new TranslateAnimation(isPageFirstScrolled ? offset : fromTransX, offset, 0,
    0);
    fromTransX = offset;
    isPageFirstScrolled = false;

    // 缩放动画, 以初始化的cursor为缩放参考
    offset = tabTextWidthArr[currTabPosition] + cursorPadding;
    float toScaleX = (float) offset / (float) baseCursorWidth;
    Animation scaleAnim = new ScaleAnimation(fromScaleX, toScaleX, 1.0f,
    1.0f, Animation.RELATIVE_TO_SELF, 0.5f,
    Animation.RELATIVE_TO_SELF, 0.5f);// 中间为缩放中心
    fromScaleX = toScaleX;

    // 将两个动画添加进集合, 同时执行
    AnimationSet anim = new AnimationSet(true);
    anim.addAnimation(scaleAnim); // 注意: 先添加缩放动画, 否则会出问题, 原因不知
    anim.addAnimation(translateAnim);
    anim.setDuration(300);
    anim.setFillAfter(true);
    cursor.startAnimation(anim); // 开始动画
    }


    }




    viewpager_indicator_layout文件:
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
    android:id="@+id/line"
    android:layout_width="1px"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    android:background="@color/gray_cccccc"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp"
    android:visibility="gone"
    />


    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <LinearLayout
    android:id="@+id/main_tab"
    android:layout_width="wrap_content"
    android:layout_height="0dip"
    android:layout_weight="1"
    android:gravity="center_vertical"
    android:orientation="horizontal" />

    <View
    android:layout_width="match_parent"
    android:layout_height="1px"
    android:background="@color/gray_cccccc" />
    </LinearLayout>

    <ImageView
    android:id="@+id/main_cursor"
    android:layout_width="wrap_content"
    android:layout_height="2dip"
    android:layout_alignParentBottom="true"
    android:scaleType="matrix"
    android:src="@drawable/youdan_cursor_bg" />

    </RelativeLayout>












    然后在布局文件中用:

    <com.manqian.mqlibrary.view.ViewPagerIndicator
    android:id="@+id/horizontal_scrollview"
    android:layout_width="match_parent"
    android:layout_height="47dp" />

    <android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

    这里我的说一下,
    com.manqian.mqlibrary.view.ViewPagerIndicator  这个是你把这个封装的文件放在项目的路径,这个是我的路径,有的同学就会直接复制过去,发现报错,要会灵活一点。
    好了,我先说说一下我的思路,大家可以看到,我封装的时候继承了什么吧,对的,就是这个horizontalscrollview,这个是水平的scrollview,也就是说是它可以使得tab可以水平滑动,还有我实现了几个监听器,通过监听器中的几个方法,从中配合来实现这个功能,具体的,我在代码上注释的比较清楚了。希望对大家有用。
    
    


  • 相关阅读:
    代码校验工具 SublimeLinter 的安装与使用
    java中写sql语句的小小细节
    搭建Hexo博客并部署到Github
    更改npm全局模块和cache默认安装位置
    笔记本连接老式显示器(VGA线+HDMI接口)
    用JSON-server模拟REST API
    使用 Feed43
    Coding.net+Myeclipse 2014 Git配置
    line-height 属性
    border-style 属性
  • 原文地址:https://www.cnblogs.com/huangjialin/p/6007217.html
Copyright © 2011-2022 走看看