Android Tab切换表格,如图:


1.横向:



2.竖向:




xml:布局

    <com.example.momo.myconcept.view.SegmentControl xmlns:segmentcontrol="http://schemas.android.com/apk/res-auto"        android:id="@+id/segment_control"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="13sp"        segmentcontrol:colors="#0099CC"        segmentcontrol:cornerRadius="6dp"        segmentcontrol:direction="horizon"        segmentcontrol:gaps="10dp"        segmentcontrol:horizonGap="20dp"        segmentcontrol:texts="语文|数学|外语/>


attrs.xml:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="SegmentControl">        <attr name="cornerRadius" format="dimension|reference" />        <attr name="colors" format="color|reference" />        <attr name="texts" format="string|reference" />        <attr name="android:textSize" />        <attr name="direction" format="enum">            <enum name="horizon" value="0" />            <enum name="vertical" value="1" />        </attr>        <attr name="gaps" format="dimension|reference" />        <attr name="horizonGap" format="dimension|reference" />        <attr name="verticalGap" format="dimension|reference" />    </declare-styleable></resources>


java:

package com.example.momo.myconcept.view;import android.content.Context;import android.content.res.ColorStateList;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.os.Build;import android.util.AttributeSet;import android.util.TypedValue;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import com.example.momo.myconcept.R;public class SegmentControl extends View {    private String[] mTexts;    private Rect[] mCacheBounds;    private Rect[] mTextBounds;    private RadiusDrawable mBackgroundDrawable;    private RadiusDrawable mSelectedDrawable;    private int mCurrentIndex;    private int mTouchSlop;    private boolean inTapRegion;    private float mStartX;    private float mStartY;    private float mCurrentX;    private float mCurrentY;    private int mHorizonGap;    private int mVerticalGap;    private int mCenterX;    private int mCenterY;    private int mChildrenWidth;    private int mChildrenHeight;    private int mSingleChildWidth;    private int mSingleChildHeight;    private Paint mPaint;    public enum Direction{        HORIZON(0), VERTICAL(1);        int mV;        private Direction(int v){            mV = v;        }    }    private Direction mDirection;    private int mTextSize;    private ColorStateList mColors;    private int mCornerRadius;    public interface OnSegmentControlClickListener{        public void onSegmentControlClick(int index);    }    private OnSegmentControlClickListener mOnSegmentControlClickListener;    public SegmentControl(Context context){        this(context, null);    }    public SegmentControl(Context context,AttributeSet attrs){        this(context, attrs, 0);    }    public SegmentControl(Context context, AttributeSet attrs, int defStyle){        super(context, attrs, defStyle);        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SegmentControl);        String textArray = ta.getString(R.styleable.SegmentControl_texts);        if(textArray != null){            mTexts = textArray.split("\\|");        }        mTextSize = ta.getDimensionPixelSize(R.styleable.SegmentControl_android_textSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14, context.getResources().getDisplayMetrics()));        mColors = ta.getColorStateList(R.styleable.SegmentControl_colors);        mCornerRadius = ta.getDimensionPixelSize(R.styleable.SegmentControl_cornerRadius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, context.getResources().getDisplayMetrics()));        mDirection = Direction.values()[ta.getInt(R.styleable.SegmentControl_direction, 0)];        mHorizonGap = ta.getDimensionPixelSize(R.styleable.SegmentControl_horizonGap, 0);        mVerticalGap = ta.getDimensionPixelSize(R.styleable.SegmentControl_verticalGap, 0);        int gap = ta.getDimensionPixelSize(R.styleable.SegmentControl_gaps, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, context.getResources().getDisplayMetrics()));        if(mHorizonGap == 0) mHorizonGap = gap;        if(mVerticalGap == 0) mVerticalGap = gap;        ta.recycle();        mBackgroundDrawable = new RadiusDrawable(mCornerRadius, true, 0);        mBackgroundDrawable.setStrokeWidth(2);        if(mColors == null){            mColors = new ColorStateList(new int[][]{{}}, new int[]{0xFF0099CC});        }        mBackgroundDrawable.setStrokeColor(mColors.getDefaultColor());        if(Build.VERSION.SDK_INT < 16){            setBackgroundDrawable(mBackgroundDrawable);        }else{            setBackground(mBackgroundDrawable);        }        mSelectedDrawable = new RadiusDrawable(mCornerRadius, false, mColors.getDefaultColor());        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setTextSize(mTextSize);        mPaint.setColor(mColors.getDefaultColor());        //here's the tricky thing, when you doing a click detect on a capacitive touch screen,        //sometimes the touch points of touchDown and touchUp are different(it's call slop) even when you didn't actually move your finger,        //so we set a distance limit for the distance of this two touch points to create a better user experience;        int touchSlop = 0;        if(context == null){            touchSlop = ViewConfiguration.getTouchSlop();        }else{            final ViewConfiguration config = ViewConfiguration.get(context);            touchSlop = config.getScaledTouchSlop();        }        mTouchSlop = touchSlop * touchSlop;        inTapRegion = false;    }    public void setOnSegmentControlClickListener(OnSegmentControlClickListener onSegmentControlClickListener){        mOnSegmentControlClickListener = onSegmentControlClickListener;    }    public OnSegmentControlClickListener getOnSegmentControlClicklistener(){        return mOnSegmentControlClickListener;    }    public void setText(String... texts){        mTexts = texts;        if(mTexts != null){            requestLayout();        }    }    public void setColors(ColorStateList colors){        mColors = colors;        if(mBackgroundDrawable != null){            mBackgroundDrawable.setStrokeColor(colors.getDefaultColor());        }        if(mSelectedDrawable != null){            mSelectedDrawable.setColor(colors.getDefaultColor());        }        mPaint.setColor(colors.getDefaultColor());        invalidate();    }    public void setCornerRadius(int cornerRadius){        mCornerRadius = cornerRadius;        if(mBackgroundDrawable != null){            mBackgroundDrawable.setRadius(cornerRadius);        }        invalidate();    }    public void setDirection(Direction direction){        Direction tDirection = mDirection;        mDirection = direction;        if(tDirection != direction){            requestLayout();            invalidate();        }    }    public void setTextSize(int textSize){        setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);    }    public void setTextSize(int unit, int textSize){        mPaint.setTextSize((int) (TypedValue.applyDimension(unit, textSize, getContext().getResources().getDisplayMetrics())));        if(textSize != mTextSize){            mTextSize = textSize;            requestLayout();        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int width = 0;        int height = 0;        if(mTexts != null && mTexts.length > 0){            if(mCacheBounds == null || mCacheBounds.length != mTexts.length){                mCacheBounds = new Rect[mTexts.length];            }            if(mTextBounds == null || mTextBounds.length != mTexts.length){                mTextBounds = new Rect[mTexts.length];            }            for(int i = 0; i < mTexts.length; i++){                String text = mTexts[i];                if(text != null){                    if(mTextBounds[i] == null) mTextBounds[i] = new Rect();                    mPaint.getTextBounds(text, 0, text.length(), mTextBounds[i]);                    if(mSingleChildWidth < mTextBounds[i].width() + mHorizonGap * 2) mSingleChildWidth = mTextBounds[i].width() + mHorizonGap * 2;                    if(mSingleChildHeight < mTextBounds[i].height() + mVerticalGap * 2) mSingleChildHeight = mTextBounds[i].height() + mVerticalGap * 2;                }            }            for(int i = 0; i < mTexts.length; i++){                if (mCacheBounds[i] == null) mCacheBounds[i] = new Rect();                if(mDirection == Direction.HORIZON){                    mCacheBounds[i].left = i * mSingleChildWidth;                    mCacheBounds[i].top = 0;                }else{                    mCacheBounds[i].left = 0;                    mCacheBounds[i].top = i * mSingleChildHeight;                }                mCacheBounds[i].right = mCacheBounds[i].left + mSingleChildWidth;                mCacheBounds[i].bottom = mCacheBounds[i].top + mSingleChildHeight;            }            switch(widthMode){                case MeasureSpec.AT_MOST:                    if(mDirection == Direction.HORIZON){                        if(widthSize <= mSingleChildWidth * mTexts.length){                            mSingleChildWidth = widthSize / mTexts.length;                            width = widthSize;                        }else{                            width = mSingleChildWidth * mTexts.length;                        }                    }else{                        width = widthSize <= mSingleChildWidth ? widthSize : mSingleChildWidth;                    }                    break;                case MeasureSpec.EXACTLY:                    width = widthSize;                    break;                case MeasureSpec.UNSPECIFIED:                    if(mDirection == Direction.HORIZON){                        width = mSingleChildWidth * mTexts.length;                    }else{                        width = widthSize <= mSingleChildWidth ? widthSize : mSingleChildWidth;                    }                    break;            }            switch(heightMode){                case MeasureSpec.AT_MOST:                    if(mDirection == Direction.VERTICAL){                        if(heightSize <= mSingleChildHeight * mTexts.length){                            mSingleChildHeight = heightSize / mTexts.length;                            height = heightSize;                        }else{                            height = mSingleChildHeight * mTexts.length;                        }                    }else{                        height = heightSize <= mSingleChildHeight ? heightSize : mSingleChildHeight;                    }                    break;                case MeasureSpec.EXACTLY:                    height = heightSize;                    break;                case MeasureSpec.UNSPECIFIED:                    if(mDirection == Direction.VERTICAL){                        height = mSingleChildHeight * mTexts.length;                    }else{                        height = heightSize <= mSingleChildHeight ? heightSize : mSingleChildHeight;                    }                    break;            }            mChildrenWidth = mDirection == Direction.HORIZON ? mSingleChildWidth * mTexts.length : mSingleChildWidth;            mChildrenHeight = mDirection == Direction.VERTICAL ? mSingleChildHeight * mTexts.length : mSingleChildHeight;        }else{            width = widthMode == MeasureSpec.UNSPECIFIED ? 0 : widthSize;            height = heightMode == MeasureSpec.UNSPECIFIED ? 0 : heightSize;        }        mCenterX = width / 2;        mCenterY = height / 2;        setMeasuredDimension(width, height);    }    @Override    public boolean onTouchEvent(MotionEvent event){        switch(event.getAction() & MotionEvent.ACTION_MASK){            case MotionEvent.ACTION_DOWN:                inTapRegion = true;                mStartX = event.getX();                mStartY = event.getY();                break;            case MotionEvent.ACTION_MOVE:                mCurrentX = event.getX();                mCurrentY = event.getY();                int dx = (int) (mCurrentX - mStartX);                int dy = (int) (mCurrentY - mStartY);                int distance = dx * dx + dy * dy;                if(distance > mTouchSlop){                    inTapRegion = false;                }                break;            case MotionEvent.ACTION_UP:                if(inTapRegion){                    int index = 0;                    if(mDirection == Direction.HORIZON){                        index = (int) (mStartX / mSingleChildWidth);                    }else{                        index = (int) (mStartY / mSingleChildHeight);                    }                    if(mOnSegmentControlClickListener != null) mOnSegmentControlClickListener.onSegmentControlClick(index);                    mCurrentIndex = index;                    invalidate();                }                break;        }        return true;    }    public void setSelectedIndex(int index){        mCurrentIndex = index;        invalidate();    }    @Override    public void onDraw(Canvas canvas){        super.onDraw(canvas);        if(mTexts != null && mTexts.length > 0){            for(int i = 0; i < mTexts.length; i++){                //draw separate lines                if(i < mTexts.length - 1){                    mPaint.setColor(mColors.getDefaultColor());                    if(mDirection == Direction.HORIZON){                        canvas.drawLine(mCacheBounds[i].right, 0, mCacheBounds[i].right, getHeight(), mPaint);                    }else{                        canvas.drawLine(mCacheBounds[i].left, mSingleChildHeight * (i + 1), mCacheBounds[i].right, mSingleChildHeight * (i + 1), mPaint);                    }                }                //draw selected drawable                if(i == mCurrentIndex && mSelectedDrawable != null){                    int topLeftRadius = 0;                    int topRightRadius = 0;                    int bottomLeftRadius = 0;                    int bottomRightRadius = 0;                    if(mDirection == Direction.HORIZON){                        if(i == 0){                            topLeftRadius = mCornerRadius;                            bottomLeftRadius = mCornerRadius;                        }else if(i == mTexts.length - 1){                            topRightRadius = mCornerRadius;                            bottomRightRadius = mCornerRadius;                        }                    }else{                        if(i == 0){                            topLeftRadius = mCornerRadius;                            topRightRadius = mCornerRadius;                        }else if(i == mTexts.length - 1){                            bottomLeftRadius = mCornerRadius;                            bottomRightRadius = mCornerRadius;                        }                    }                    mSelectedDrawable.setRadiuses(topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);                    mSelectedDrawable.setBounds(mCacheBounds[i]);                    mSelectedDrawable.draw(canvas);                    mPaint.setColor(0xFFFFFFFF);                }else{                    mPaint.setColor(mColors.getDefaultColor());                }                //draw texts                canvas.drawText(mTexts[i], mCacheBounds[i].left + (mSingleChildWidth - mTextBounds[i].width()) / 2, mCacheBounds[i].top + ((mSingleChildHeight + mTextBounds[i].height()) / 2), mPaint);            }        }    }}



用法 MainActivity:

public class MainActivity extends Activity  {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        SegmentControl segmentControl = (SegmentControl)findViewById(R.id.segment_control);        segmentControl.setSelectedIndex(1);        segmentControl.setOnSegmentControlClickListener(new SegmentControl.OnSegmentControlClickListener() {            @Override            public void onSegmentControlClick(int index) {                Toast.makeText(MainActivity.this,"this "+index,Toast.LENGTH_LONG).show();            }        });    }}



参考:Git:SHSegmentControl

程序代码参考:点击打开链接



更多相关文章

  1. android 横向ListView 横向列表
  2. Android Studio第六期 - 横向GridView
  3. Android 自定义View 横向翻页
  4. Android Application - No window title, Full screen, Landscap
  5. 改变Android屏幕默认启动方向为横向
  6. android 横向,竖向滚动Gridveiw
  7. Android日志系统分析之日志设备驱动程序代码阅读
  8. 跑马灯(横向滚动)
  9. Android 自定义RadioButton样式 RadioGroup横向排列并分行

随机推荐

  1. Android中的悬浮对话框和即点即关对话框
  2. android Looper、Handler和MessageQueue
  3. 推荐10个Android开源项目
  4. android opencv 前置摄像头
  5. Android的TextView
  6. Android 使用TextView实现跑马灯效果
  7. Android中插件开发篇之----应用换肤原理
  8. Android 设置dialog背景全透明无边框
  9. Android ELF文件PLT和GOT
  10. Android触摸事件传递机制