Android程序之Indicator介绍

Indicator确实是个老梗了...

有重写HorizontalScrollView的,有重写LinearLayout。

这个是重写LinearLayout的哦,往LinearLayout里add   TextView用作tab标签,在LinearLayout底部画一个矩形当作指示器。

ViewPager滚动的时候用简单的小学加减乘除混合运算来机选这个矩形位置,然后滚动就好了



属性

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.   
  4.     <attr name="tab_color_normal" format="color" />  
  5.     <attr name="tab_color_light" format="color" />  
  6.     <attr name="cursor_color" format="color" />  
  7.     <attr name="cursor_height" format="dimension" />  
  8.   
  9.     <declare-styleable name="Indicator">  
  10.         <attr name="tab_color_normal" />  
  11.         <attr name="tab_color_light" />  
  12.         <attr name="cursor_color" />  
  13.         <attr name="cursor_height" />  
  14.     </declare-styleable>  
  15.   
  16. </resources>  

Indicator.java  关键的地方都谢了注释

[java]  view plain  copy
  1. package com.mingwei.indicator.view;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.annotation.TargetApi;  
  6. import android.content.Context;  
  7. import android.content.res.TypedArray;  
  8. import android.graphics.Canvas;  
  9. import android.graphics.Color;  
  10. import android.graphics.Paint;  
  11. import android.graphics.Paint.Style;  
  12. import android.graphics.Rect;  
  13. import android.os.Build;  
  14. import android.support.v4.view.ViewPager;  
  15. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  16. import android.util.AttributeSet;  
  17. import android.util.TypedValue;  
  18. import android.view.Gravity;  
  19. import android.view.View;  
  20. import android.view.View.OnClickListener;  
  21. import android.widget.HorizontalScrollView;  
  22. import android.widget.LinearLayout;  
  23. import android.widget.TextView;  
  24.   
  25. import com.mingwei.indicator.R;  
  26.   
  27. @TargetApi(Build.VERSION_CODES.HONEYCOMB)  
  28. public class Indicator extends LinearLayout implements OnClickListener, OnPageChangeListener {  
  29.     /** 
  30.      * 绘制时用的画笔 
  31.      */  
  32.     private Paint mPaint;  
  33.     /** 
  34.      * 默认颜色 
  35.      */  
  36.     private int mCursorColor;  
  37.     /** 
  38.      * 滚动的指示器的矩形范围 
  39.      */  
  40.     private Rect mRect = new Rect();  
  41.     /** 
  42.      * 滚动游标的绘制范围 
  43.      */  
  44.     private int mL, mR, mT, mB;  
  45.     /** 
  46.      * 最多可见的游标数 
  47.      */  
  48.     private int mVisiableTabCount = 4;  
  49.     /** 
  50.      * 游标高度 
  51.      */  
  52.     private int mCursorHeight = 6;  
  53.     /** 
  54.      * tab的宽度 
  55.      */  
  56.     private int mTabWidth;  
  57.     /** 
  58.      * 选中和非选中状态的标签文字颜色 
  59.      */  
  60.     private int mTabColorNormal;  
  61.     private int mTabColorLight;  
  62.     /** 
  63.      * 水平滚动的距离 
  64.      */  
  65.     private float mTranslationX;  
  66.     /** 
  67.      * 需要监听ViewPager动作来跟新游标 
  68.      */  
  69.     private ViewPager mViewPager;  
  70.   
  71.     public Indicator(Context context) {  
  72.         this(context, null);  
  73.     }  
  74.   
  75.     public Indicator(Context context, AttributeSet attrs) {  
  76.         this(context, attrs, 0);  
  77.     }  
  78.   
  79.     public Indicator(Context context, AttributeSet attrs, int defStyleAttr) {  
  80.         super(context, attrs, defStyleAttr);  
  81.         initAttr(context, attrs, defStyleAttr);  
  82.         mPaint = new Paint();  
  83.         mPaint.setColor(mCursorColor);  
  84.         mPaint.setAntiAlias(true);  
  85.         mPaint.setStyle(Style.FILL);  
  86.     }  
  87.   
  88.     private void initAttr(Context context, AttributeSet attrs, int defStyleAttr) {  
  89.         TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.Indicator);  
  90.         mTabColorNormal = array.getColor(R.styleable.Indicator_tab_color_normal, Color.BLACK);  
  91.         mTabColorLight = array.getColor(R.styleable.Indicator_tab_color_light, Color.WHITE);  
  92.         mCursorColor = array.getColor(R.styleable.Indicator_cursor_color, Color.BLACK);  
  93.         mCursorHeight = array.getDimensionPixelSize(R.styleable.Indicator_cursor_height, mCursorHeight);  
  94.         array.recycle();  
  95.     }  
  96.   
  97.     @Override  
  98.     protected void onFinishInflate() {  
  99.         super.onFinishInflate();  
  100.     }  
  101.   
  102.     @Override  
  103.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  104.         super.onSizeChanged(w, h, oldw, oldh);  
  105.           
  106.         int count = getChildCount();  
  107.         if (count == 0) {  
  108.             return;  
  109.         }  
  110.         mTabWidth = getWidth() / mVisiableTabCount;  
  111.         for (int i = 0; i < count; i++) {  
  112.             View view = getChildAt(i);  
  113.             LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();  
  114.             params.weight = 0;  
  115.             params.width = mTabWidth;  
  116.             params.height = getHeight() - mCursorHeight;  
  117.             view.setLayoutParams(params);  
  118.         }  
  119.         mL = 0;  
  120.         mT = getHeight() - mCursorHeight;  
  121.         mR = mTabWidth;  
  122.         mB = getHeight();  
  123.         mRect = new Rect(mL, mT, mR, mB);  
  124.     }  
  125.   
  126.     @Override  
  127.     protected void dispatchDraw(Canvas canvas) {  
  128.         super.dispatchDraw(canvas);  
  129.         canvas.save();  
  130.         canvas.translate(mTranslationX, 0);  
  131.         canvas.drawRect(mRect, mPaint);  
  132.         canvas.restore();  
  133.   
  134.     }  
  135.   
  136.     private void scroll(int position, float offset) {  
  137.         mTranslationX = getWidth() / mVisiableTabCount * (position + offset);  
  138.         /** 
  139.          * 当tab数大于可见数目的时候,整个容器滚动 
  140.          */  
  141.         if (getChildCount() > mVisiableTabCount && offset > 0 && (position >= mVisiableTabCount - 2)) {  
  142.             if (mVisiableTabCount != 1) {  
  143.                 /** 
  144.                  * 当tab等于可见数目不是倒数第二个时滚动容器,否则仍然滚动游标 
  145.                  */  
  146.                 if (position != getChildCount() - 2) {  
  147.                     scrollTo((position - (mVisiableTabCount - 2)) * mTabWidth + (int) (offset * mTabWidth), 0);  
  148.                 }  
  149.             } else {  
  150.                 scrollTo(position * mTabWidth + (int) (offset * mTabWidth), 0);  
  151.             }  
  152.         }  
  153.         invalidate();  
  154.   
  155.     }  
  156.   
  157.     public void setViewPager(ViewPager viewPager) {  
  158.         mViewPager = viewPager;  
  159.         mViewPager.setOnPageChangeListener(this);  
  160.     }  
  161.   
  162.     public void setTabs(String[] tabs) {  
  163.         removeAllViews();  
  164.         for (String t : tabs) {  
  165.             createChild(t);  
  166.         }  
  167.         TextView view = (TextView) getChildAt(0);  
  168.         view.setTextColor(mTabColorLight);  
  169.     }  
  170.   
  171.     public void setTabs(List<String> tabs) {  
  172.         removeAllViews();  
  173.         for (String t : tabs) {  
  174.             createChild(t);  
  175.         }  
  176.         TextView view = (TextView) getChildAt(0);  
  177.         view.setTextColor(mTabColorLight);  
  178.     }  
  179.   
  180.     private void setTabLight(int arg0) {  
  181.         int count = getChildCount();  
  182.         for (int i = 0; i < count; i++) {  
  183.             TextView view = (TextView) getChildAt(i);  
  184.             if (i == arg0) {  
  185.                 view.setTextColor(mTabColorLight);  
  186.             } else {  
  187.                 view.setTextColor(mTabColorNormal);  
  188.             }  
  189.         }  
  190.     }  
  191.   
  192.     /** 
  193.      * 创建子View 
  194.      *  
  195.      * @param text 
  196.      */  
  197.     private void createChild(String text) {  
  198.         TextView view = new TextView(getContext());  
  199.         view.setText(text);  
  200.         view.setGravity(Gravity.CENTER);  
  201.         view.setTextColor(mTabColorNormal);  
  202.         view.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);  
  203.         view.setOnClickListener(this);  
  204.         view.setTag(getChildCount());  
  205.         addView(view);  
  206.     }  
  207.   
  208.     @Override  
  209.     public void onPageScrollStateChanged(int arg0) {  
  210.   
  211.     }  
  212.   
  213.     @Override  
  214.     public void onPageScrolled(int arg0, float arg1, int arg2) {  
  215.         scroll(arg0, arg1);  
  216.     }  
  217.   
  218.     @Override  
  219.     public void onPageSelected(int arg0) {  
  220.         setTabLight(arg0);  
  221.     }  
  222.   
  223.     @Override  
  224.     public void onClick(View arg0) {  
  225.         int i = (Integer) arg0.getTag();  
  226.         mViewPager.setCurrentItem(i);  
  227.     }  
  228.   
  229. }  

XML使用

[html]  view plain  copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <com.mingwei.indicator.view.Indicator  
  8.         xmlns:ming="http://schemas.android.com/apk/res-auto"  
  9.         android:id="@+id/indicator"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="45dp"  
  12.         android:orientation="horizontal"  
  13.         ming:cursor_color="@color/indicator_color"  
  14.         ming:cursor_height="3dp"  
  15.         ming:tab_color_light="@color/tab_color_checked"  
  16.         ming:tab_color_normal="@color/tab_color_normal" >  
  17.     </com.mingwei.indicator.view.Indicator>  
  18.   
  19.     <android.support.v4.view.ViewPager  
  20.         android:id="@+id/viewpager"  
  21.         android:layout_width="match_parent"  
  22.         android:layout_height="match_parent" >  
  23.     </android.support.v4.view.ViewPager>  
  24.   
  25. </LinearLayout>  


MainActivity

[java]  view plain  copy
  1. package com.mingwei.indicator;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Arrays;  
  5. import java.util.List;  
  6.   
  7. import android.os.Bundle;  
  8. import android.support.v4.app.Fragment;  
  9. import android.support.v4.app.FragmentActivity;  
  10. import android.support.v4.app.FragmentPagerAdapter;  
  11. import android.support.v4.view.ViewPager;  
  12. import android.view.Menu;  
  13. import android.view.MenuItem;  
  14.   
  15. import com.mingwei.indicator.view.Indicator;  
  16.   
  17. public class MainActivity extends FragmentActivity {  
  18.   
  19.     private ViewPager mViewPager;  
  20.   
  21.     private List<Fragment> mFragments = new ArrayList<Fragment>();  
  22.   
  23.     private FragmentPagerAdapter mAdapter;  
  24.   
  25.     private List<String> mStrings = Arrays.asList("标签1""标签2""标签3""标签4""标签5");  
  26.   
  27.     private Indicator mIndicator;  
  28.   
  29.     @Override  
  30.     protected void onCreate(Bundle savedInstanceState) {  
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.activity_main);  
  33.         initView();  
  34.     }  
  35.   
  36.     private void initView() {  
  37.   
  38.         for (String tabs : mStrings) {  
  39.             SimpleFragment fragment = SimpleFragment.newInstance(tabs);  
  40.             mFragments.add(fragment);  
  41.         }  
  42.         mViewPager = (ViewPager) findViewById(R.id.viewpager);  
  43.         mIndicator = (Indicator) findViewById(R.id.indicator);  
  44.         mIndicator.setTabs(mStrings);  
  45.         mIndicator.setViewPager(mViewPager);  
  46.         mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {  
  47.   
  48.             @Override  
  49.             public int getCount() {  
  50.                 return mFragments.size();  
  51.             }  
  52.   
  53.             @Override  
  54.             public Fragment getItem(int position) {  
  55.                 return mFragments.get(position);  
  56.             }  
  57.         };  
  58.         mViewPager.setAdapter(mAdapter);  
  59.   
  60.     }  
  61.   
  62.     @Override  
  63.     public boolean onCreateOptionsMenu(Menu menu) {  
  64.         // Inflate the menu; this adds items to the action bar if it is present.  
  65.         getMenuInflater().inflate(R.menu.main, menu);  
  66.         return true;  
  67.     }  
  68.   
  69.     @Override  
  70.     public boolean onOptionsItemSelected(MenuItem item) {  
  71.         // Handle action bar item clicks here. The action bar will  
  72.         // automatically handle clicks on the Home/Up button, so long  
  73.         // as you specify a parent activity in AndroidManifest.xml.  
  74.         int id = item.getItemId();  
  75.         if (id == R.id.action_settings) {  
  76.             return true;  
  77.         }  
  78.         return super.onOptionsItemSelected(item);  
  79.     }  
  80. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值