带进度条的按钮

一、定义ProgressButton的自定义属性

在attrs文件中定义ProgressButton的基本属性:主要有进度条颜色、进度条的背景颜色、按钮正常和被点击状态时的颜色、按钮的边角半径和是否显示进度信息。

<declare-styleable name="progressbutton">
    <attr name="progressColor" format="color" />
    <attr name="progressBgColor" format="color" />
    <attr name="buttonNormalColor" format="color" />
    <attr name="buttonPressedColor" format="color" />
    <attr name="buttonCornerRadius" format="dimension"/>
    <attr name="showProgressNum" format="boolean"/>
</declare-styleable>

二、继承Button自定义ProgressButton

package com.cxmscb.cxm.progressbutton;

import Android.annotation.TargetApi; 
import android.content.Context; 
import android.content.res.TypedArray; 
import android.graphics.Canvas; 
import android.graphics.drawable.Drawable; 
import android.graphics.drawable.GradientDrawable; 
import android.graphics.drawable.StateListDrawable; 
import android.os.Build; 
import android.util.AttributeSet; 
import android.widget.Button;

/** 
* Created by cxm on 2016/9/7. 
*/ 
public class ProgressButton extends Button {

private int mProgress; //当前进度
private int mMaxProgress = 100; //最大进度:默认为100
private int mMinProgress = 0;//最小进度:默认为0
private GradientDrawable mProgressDrawable;// 加载进度时的进度颜色
private GradientDrawable mProgressDrawableBg;// 加载进度时的背景色
private StateListDrawable mNormalDrawable; // 按钮在不同状态的颜色效果
private boolean isShowProgress;  //是否展示进度
private boolean isFinish; // 结束状态
private boolean isStop;// 停止状态
private boolean isStart ; // 刚开始的状态
private OnStateListener onStateListener; //结束时的监听
private float cornerRadius; // 圆角半径



public ProgressButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
}

public ProgressButton(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context, attrs);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ProgressButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init(context, attrs);
}

private void init(Context context,AttributeSet attributeSet) {

    // 初始化按钮状态Drawable
    mNormalDrawable = new StateListDrawable();
    // 初始化进度条Drawable
    mProgressDrawable = (GradientDrawable)getResources().getDrawable(
            R.drawable.rect_progress).mutate();
    // 初始化进度条背景Drawable
    mProgressDrawableBg = (GradientDrawable)getResources().getDrawable(
            R.drawable.rect_progressbg).mutate();

    TypedArray attr =  context.obtainStyledAttributes(attributeSet, R.styleable.progressbutton);

    try {

        // 默认的圆角大小
        float defValue = getResources().getDimension(R.dimen.corner_radius);
        // 获取圆角大小
        cornerRadius = attr.getDimension(R.styleable.progressbutton_buttonCornerRadius, defValue);


        // 获取是否显示进度信息的属性
        isShowProgress = attr.getBoolean(R.styleable.progressbutton_showProgressNum,true);

        // 给按钮的状态Drawable添加被点击时的状态
        mNormalDrawable.addState(new int[]{android.R.attr.state_pressed},
                getPressedDrawable(attr));
        // 给按钮的状态Drawable添加其他时候的状态        
        mNormalDrawable.addState(new int[] { }, getNormalDrawable(attr));


        // 获取进度条颜色属性值
        int defaultProgressColor = getResources().getColor(R.color.purple_progress);
        int progressColor = attr.getColor(R.styleable.progressbutton_progressColor,defaultProgressColor);
        // 设置进度条Drawable的颜色
        mProgressDrawable.setColor(progressColor);

        // 获取进度条背景颜色属性值
        int defaultProgressBgColor = getResources().getColor(R.color.progress_bg);
        int progressBgColor = attr.getColor(R.styleable.progressbutton_progressBgColor,defaultProgressBgColor);
        // 设置进度条背景Drawable的颜色
        mProgressDrawableBg.setColor(progressBgColor);



    } finally {
        attr.recycle();
    }

    // 初始化状态
    isFinish = false;
    isStop = true;
    isStart = false;

    // 设置圆角
    mProgressDrawable.setCornerRadius(cornerRadius);
    mProgressDrawableBg.setCornerRadius(cornerRadius);
    // 设置按钮背景为状态Drawable
    setBackgroundCompat(mNormalDrawable);
}



@Override
protected void onDraw(Canvas canvas) {

    if (mProgress > mMinProgress && mProgress <= mMaxProgress && !isFinish) {

        // 更新进度:

        float scale = (float) getProgress() / (float) mMaxProgress;
        float indicatorWidth = (float) getMeasuredWidth() * scale;


        mProgressDrawable.setBounds(0, 0, (int) indicatorWidth, getMeasuredHeight());

        mProgressDrawable.draw(canvas);

        // 进度完成时回调方法,并更变状态
        if(mProgress==mMaxProgress) {
            setBackgroundCompat(mProgressDrawable);
            isFinish = true;
            if(onStateListener!=null) {
                onStateListener.onFinish();
            }

        }

    }

    super.onDraw(canvas);
}

// 设置进度信息
public void setProgress(int progress) {

    if(!isFinish&&!isStop){
        mProgress = progress;
        if(isShowProgress) setText(mProgress + " %");
        // 设置背景
        setBackgroundCompat(mProgressDrawableBg);
        invalidate();
    }

}


// 获取进度
public int getProgress() {
    return mProgress;
}

// 设置为停止状态
public void setStop(boolean stop) {
    isStop = stop;
    invalidate();
}

public boolean isStop() {
    return isStop;
}

public boolean isFinish() {
    return isFinish;
}

// 切换状态:
public void toggle(){
    if(!isFinish&&isStart){
        if(isStop){
            setStop(false);
            onStateListener.onContinue();
        } else {
            setStop(true);
            onStateListener.onStop();
        }
    }else {
        setStop(false);
        isStart = true;
    }
}

// 设置按钮背景
private void setBackgroundCompat(Drawable drawable) {
    int pL = getPaddingLeft();
    int pT = getPaddingTop();
    int pR = getPaddingRight();
    int pB = getPaddingBottom();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        setBackground(drawable);
    } else {
        setBackgroundDrawable(drawable);
    }
    setPadding(pL, pT, pR, pB);
}


// 初始化状态
public void initState(){
    setBackgroundCompat(mNormalDrawable);
    isFinish = false;
    isStop = true;
    isStart = false;
    mProgress = 0;
}


// 获取状态Drawable的正常状态下的背景
private Drawable getNormalDrawable( TypedArray attr) {

    GradientDrawable drawableNormal =
            (GradientDrawable) getResources().getDrawable(R.drawable.rect_normal).mutate();// 修改时就不会影响其它drawable对象的状态
    drawableNormal.setCornerRadius(cornerRadius); // 设置圆角半径

    int defaultNormal =  getResources().getColor(R.color.blue_normal);
    int colorNormal =  attr.getColor(R.styleable.progressbutton_buttonNormalColor,defaultNormal);
    drawableNormal.setColor(colorNormal);//设置颜色

    return drawableNormal;
}

// 获取按钮被点击时的Drawable
private Drawable getPressedDrawable( TypedArray attr) {
    GradientDrawable drawablePressed =
            (GradientDrawable) getResources().getDrawable(R.drawable.rect_pressed).mutate();// 修改时就不会影响其它drawable对象的状态
    drawablePressed.setCornerRadius(cornerRadius);// 设置圆角半径

    int defaultPressed = getResources().getColor(R.color.blue_pressed);
    int colorPressed = attr.getColor(R.styleable.progressbutton_buttonPressedColor,defaultPressed);
    drawablePressed.setColor(colorPressed);//设置颜色

    return drawablePressed;
}

// 设置状态监听接口
interface OnStateListener{

    abstract void onFinish();
    abstract void onStop();
    abstract void onContinue();

}

public void setOnStateListener(OnStateListener onStateListener){
    this.onStateListener = onStateListener;
}

public void isShowProgressNum(boolean b){
    this.isShowProgress = b;
}

}

三、ProgressButton的使用示例:

public class MainActivity extends AppCompatActivity {

private ProgressButton progressButton;
private ProgressThread pt;
private Boolean isPause = false;



public Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        progressButton.setProgress(msg.arg1);
    }
};

private int z=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    progressButton = (ProgressButton) findViewById(R.id.pb);
    progressButton.setTag(0);
    progressButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // 防止开启多个异步线程
            if((Integer)progressButton.getTag()==0) {
                pt = new ProgressThread();
                pt.start();
                progressButton.setTag(1);
            }
            if(!progressButton.isFinish()){
                progressButton.toggle();
            }

        }
    });
    progressButton.setOnStateListener(new ProgressButton.OnStateListener() {
        @Override
        public void onFinish() {
            isPause = true;
            synchronized (this) {
                pt.interrupt();
            }
            progressButton.setText("完 成");
            // progressButton.initState();
            Toast.makeText(MainActivity.this,"Finish",Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onStop() {
            Log.i("zz","stop");
            progressButton.setText("继 续");
            isPause = true;
        }

        @Override
        public void onContinue() {
            Log.i("zz","continue");

            isPause = false;
        }
    });

}

public  class ProgressThread extends Thread{

    private int z = 0;
    @Override
    public void run() {
       while (true) {
           synchronized (this) {
               if (!isPause) {
                   z += 2;
                   Message msg = Message.obtain();
                   msg.arg1 = z;
                   handler.sendMessage(msg);
                   try {
                       Thread.sleep(100);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
           }
       }

        }
    }


@Override
protected void onDestroy() {
    super.onDestroy();
    handler.removeCallbacksAndMessages(null);
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值