android 实现自定Seekbar

Posted 踏雪羽翼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 实现自定Seekbar相关的知识,希望对你有一定的参考价值。

可实现左边跟中间滑动显示Seekbar

package com.android.myapplication;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

public class MyProgressView extends View 
    private final String TAG = "MyProgressView";
    private int mBitmapWidth;
    private int mBitmapHeight;
    private float mMoveX;
    private Paint mProgressPaint;
    private int mMax = 100;
    private int mProgress = 0;
    private Paint mBgPaint;
    private int mBgColor;
    private int mProgressColor;
    private int mSeekBarSize = 10;
    private int mPaddingSize = 10;
    private int mViewWidth = 0;
    private boolean isInitSetProgress = false;
    private int mTouchSlop;
    private float mDownX;
    private float mDownY;
    private boolean isInit = true;
    private Paint mThumbPaint;
    private int mThumbColor = Color.WHITE;
    private int mThumbSize = 20;
    private int mThumbTouchSize = 30;
    private boolean isTouch = false;
    private int mSize = 20;
    private boolean isCenter = false;


    private ISeekBarProgressClickListener mListener;

    public void setSeekBarProgressClickListener(ISeekBarProgressClickListener listener) 
        this.mListener = listener;
    

    public interface ISeekBarProgressClickListener 
        void onSeekBarStart(MyProgressView view, int progress);

        void onSeekBarChanged(MyProgressView view, int progress);

        void onSeekBarStop(MyProgressView view, int progress);
    

    public MyProgressView(Context context) 
        this(context, null);
    

    public MyProgressView(Context context, AttributeSet attrs) 
        this(context, attrs, 0);
    

    public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) 
        super(context, attrs, defStyleAttr);
        setWillNotDraw(false);

        mSize = dip2px(context, 8);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyCustomSeekBarView, defStyleAttr, 0);
        mProgress = (int) a.getDimension(R.styleable.MyCustomSeekBarView_MyCustomSeekBarThumbProgress, 0);
        mSeekBarSize = a.getDimensionPixelSize(R.styleable.MyCustomSeekBarView_MyCustomSeekBarSize, 10);
        mBgColor = a.getColor(R.styleable.MyCustomSeekBarView_MyCustomSeekBarBgColor, context.getResources().getColor(R.color.while_fifteen));
        mProgressColor = a.getColor(R.styleable.MyCustomSeekBarView_MyCustomSeekBarProgressColor, Color.WHITE);
        mThumbSize = a.getDimensionPixelSize(R.styleable.MyCustomSeekBarView_MyCustomSeekBarThumbSize, mSize);
        mThumbTouchSize = a.getDimensionPixelSize(R.styleable.MyCustomSeekBarView_MyCustomSeekBarThumbTouchSize, mSize) + 3;
        mThumbColor = a.getColor(R.styleable.MyCustomSeekBarView_MyCustomSeekBarThumbColor, Color.WHITE);
        //  int thumbIcon = a.getResourceId(R.styleable.MyCustomSeekBarView_MyCustomSeekBarThumbIcon, R.drawable.ic_launcher_background);
        //Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), thumbIcon);

        a.recycle();
        init(context);
    

    private void init(Context context) 

        mPaddingSize = context.getResources().getDimensionPixelSize(R.dimen.simpleEditor_text_progress_padding_size);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

        mProgressPaint = new Paint();
        mProgressPaint.setColor(mProgressColor);
        mProgressPaint.setStyle(Paint.Style.STROKE);
        mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
        mProgressPaint.setStrokeJoin(Paint.Join.ROUND);
        mProgressPaint.setStrokeWidth(mSeekBarSize);
        mProgressPaint.setAntiAlias(true);

        mBgPaint = new Paint();
        mBgPaint.setColor(mBgColor);
        mBgPaint.setStyle(Paint.Style.STROKE);
        mBgPaint.setStrokeCap(Paint.Cap.ROUND);
        mBgPaint.setStrokeJoin(Paint.Join.ROUND);
        mBgPaint.setStrokeWidth(mSeekBarSize);
        mBgPaint.setAntiAlias(true);

        mThumbPaint = new Paint();
        mThumbPaint.setColor(mThumbColor);
        mThumbPaint.setStyle(Paint.Style.FILL);
        mThumbPaint.setStrokeCap(Paint.Cap.ROUND);
        mThumbPaint.setStrokeJoin(Paint.Join.ROUND);
        mThumbPaint.setStrokeWidth(mSeekBarSize);
        mThumbPaint.setAntiAlias(true);
    

    protected void onSizeChanged(int w, int h, int oldw, int oldh) 
        super.onSizeChanged(h, w, oldh, oldw);
        mViewWidth = w;
        if (isInit) 
            isInit = false;
            if (isCenter) 
                mMoveX = 0;
             else 
                mMoveX = w / 2;
            

        
        if (isInitSetProgress) 
            setProgress(mProgress);
        

    

    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);

        int width = resolveSize(dip2px(getContext(), 200), widthMeasureSpec);
        int height = dip2px(getContext(), 25);
        setMeasuredDimension(width, height);

    

    protected void onDraw(Canvas canvas) 
        super.onDraw(canvas);
        float height = getHeight() / 2;
        canvas.save();
        canvas.drawLine(0 + getPaddingLeft() + mPaddingSize, height, mViewWidth - getPaddingRight() - mPaddingSize, height, mBgPaint);

        if (!isCenter) 
            float currentX = mMoveX;
            canvas.drawLine(getPaddingLeft() + mPaddingSize, height, currentX, height, mProgressPaint);
            if (isTouch) 
                canvas.drawCircle(currentX, height, mThumbTouchSize, mThumbPaint);
             else 
                canvas.drawCircle(currentX, height, mThumbSize, mThumbPaint);
            

         else 
            canvas.drawLine(mViewWidth / 2, height, mMoveX, height, mProgressPaint);
            if (isTouch) 
                canvas.drawCircle(mMoveX  , height - mBitmapHeight / 2, mThumbTouchSize, mThumbPaint);
             else 
                canvas.drawCircle(mMoveX  , height - mBitmapHeight / 2, mThumbSize, mThumbPaint);
            
        

        canvas.restore();
    

    @Override
    public boolean dispatchTouchEvent(MotionEvent e) 
        try 
            getParent().requestDisallowInterceptTouchEvent(true);

         catch (Exception ex) 
        
        return super.dispatchTouchEvent(e);
    

    @Override
    public boolean onTouchEvent(MotionEvent event) 
        int action = event.getAction();
        switch (action) 
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);
                isTouch = true;
                mDownX = event.getX();
                mDownY = event.getY();
                mMoveX = event.getX();
                if (!isCenter) 
                    calculationProgressLeft();
                 else 
                    calculationProgress();
                
                if (mListener != null) 
                    mListener.onSeekBarStart(this, mProgress);
                
                break;
            case MotionEvent.ACTION_MOVE:
                isTouch = true;
                float diffX = event.getX() - mDownX;
                float diffY = event.getY() - mDownY;
                if ((Math.abs(diffX) > mTouchSlop
                        || Math.abs(diffY) > mTouchSlop)) 
                    mMoveX = event.getX();
                    if (!isCenter) 
                        calculationProgressLeft();
                     else 
                        calculationProgress();
                    
                    if (mListener != null) 
                        mListener.onSeekBarChanged(this, mProgress);
                    
                

                break;
            case MotionEvent.ACTION_UP:
                isTouch = false;
                mMoveX = event.getX();
                if (!isCenter) 
                    calculationProgressLeft();
                 else 
                    calculationProgress();
                
                if (mListener != null) 
                    mListener.onSeekBarChanged(this, mProgress);
                    mListener.onSeekBarStop(this, mProgress);
                
                break;
        
        invalidate();
        return true;
    

    private void calculationProgress() 
        int width = getWidth() / 2;
        int maxMoveSize = getWidth() - mPaddingSize - getPaddingLeft();
        if (mMoveX > maxMoveSize) 
            mMoveX = maxMoveSize;
        

        if (mMoveX < mPaddingSize) 
            mMoveX = mPaddingSize;
        

        if (mMoveX >= width) 
            mProgress = (int) (mMax * ((mMoveX - width) / (maxMoveSize - width)));
         else 
            int max = width - mPaddingSize;
            mProgress = (int) (mMax * (((mMoveX - mPaddingSize) - max) / max));
        

        if (mProgress > mMax) 
            mProgress = mMax;
        
        if (mProgress < -mMax) 
            mProgress = -mMax;
        
    

    private void calculationProgressLeft() 
        int maxMoveSize = getWidth() - mPaddingSize - getPaddingLeft();
        if (mMoveX >= maxMoveSize) 
            mMoveX = maxMoveSize;
        
        if (mMoveX <= mPaddingSize) 
            mMoveX = mPaddingSize;
        
        mProgress = (int) ((mMoveX - mPaddingSize) / (maxMoveSize - mPaddingSize) * mMax);
    


    public int getMax() 
        return mMax;
    

    public void setMax(int max) 
        this.mMax = max;
        invalidate();
    

    public float getProgress() 
        return mProgress;
    

    public void setProgress(int progress) 
        this.mProgress = progress;
        if (mViewWidth != 0) 
            int width;
            if (!isCenter) 
                int maxMoveSize = mViewWidth - mPaddingSize - getPaddingLeft();
                mMoveX = progress * (maxMoveSize - mPaddingSize) / mMax + mPaddingSize;
             else 
                width = mViewWidth / 2;
                int maxMoveSize = mViewWidth - mPaddingSize - getPaddingLeft();
                if (mProgress >= 0) 
                    mMoveX = (progress * (maxMoveSize - width) / mMax) + width;
                 else 
                    int max = width - mPaddingSize;
                    mMoveX = ((progress * 1f / mMax) * max) + max + mPaddingSize;
                
            

            isInitSetProgress = false;
         else 
            isInitSetProgress = true;
        
        invalidate();
    

    public int getBgColor() 
        return mBgColor;
    

    public void setBgColor(int bgColor) 
        this.mBgColor = bgColor;
        mBgPaint.setColor(mBgColor);
        invalidate();
    

    public int get() 
        return mThumbColor;
    

    public void setThumbColor(int thumbColor) 
        this.mThumbColor = thumbColor;
        mThumbPaint.setColor(thumbColor);
        invalidate();
    

    public int getProgressColor() 
        return mProgressColor;
    

    public void setProgressColor(int progressColor) 
        this.mProgressColor = progressColor;
        mProgressPaint.setColor(progressColor);
        invalidate();
    

    public int getSeekBarSize() 
        return mSeekBarSize;
    

    public void setSeekBarSize(int seekBarSize) 
        this.mSeekBarSize = seekBarSize;
    


    public boolean isCenter() 
        return isCenter;
    

    public void setCenter(boolean center) 
        isCenter = center;
    

    public int dip2px(Context context, float dipValue) 
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    

attrs

<declare-styleable name="MyCustomSeekBarView">
        <attr name="MyCustomSeekBarProgressColor" format="color" />
        <attr name="MyCustomSeekBarSize" format="dimension|integer" />
        <attr name="MyCustomSeekBarBgColor" format="color" />
        <attr name="MyCustomSeekBarThumbProgress" format="dimension|integer" />
        <attr name="MyCustomSeekBarProgressMax" format="dimension|integer" />
        <attr name="MyCustomSeekBarThumbIcon" format="reference" />
        <attr name="MyCustomSeekBarThumbSize" format="dimension|integer"/>
        <attr name="MyCustomSeekBarThumbColor" format="dimension|integer"/>
        <attr name="MyCustomSeekBarThumbTouchSize" format="dimension|integer"/>
    </declare-styleable>

 

以上是关于android 实现自定Seekbar的主要内容,如果未能解决你的问题,请参考以下文章

android 实现自定Seekbar

Android : SeekBar 实现图片旋转缩放

Android技术分享| 自定义View实现使用更方便的SeekBar

Android技术分享| 自定义View实现使用更方便的SeekBar

android 怎么实现类似SeekBar的单向调节改成双向调节范围

[Android] Android 定时任务实现的三种方法(以SeekBar的进度自动实现为例)