我想构建一个自定义进度音频播放器。像facebook一样。
对此和GradientDrawables使用csutom Linearview。我在Ondraw函数上填写进度。
public class wavPlayerView extends LinearLayout {
private float mCornerRadius = 0;
private float mProgressMargin = 0;
private int progressColor;
private boolean mFinish;
private int mProgress=0;
private int mMaxProgress = 100;
private int mMinProgress = 0;
private GradientDrawable mDrawableLayout;
private GradientDrawable mDrawableProgressBackground;
private GradientDrawable mDrawableProgress;
private Context mContext;
private wavPlayer mWavPlayer;
private ImageView wavPlayerButton;
private TextView wavPlayerDuration;
public wavPlayerView(Context context) {
super(context);
initialize(context,null);
}
public wavPlayerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initialize(context,attrs);
}
public wavPlayerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context,attrs);
}
/**
*
* @param context
* @param attrs
*/
private void initialize(Context context, AttributeSet attrs) {
mContext=context;
LayoutInflater.from(context).inflate(R.layout.wav_player_layout, this);
setOrientation(VERTICAL);
//get elements
wavPlayerButton = (ImageView) findViewById(R.id.wavPlayerBtn);
wavPlayerDuration=(TextView) findViewById(R.id.wavDuration);
//Progress background drawable
mDrawableProgressBackground = new GradientDrawable();
//Progress drawable
mDrawableProgress = new GradientDrawable();
//Normal drawable
mDrawableLayout = new GradientDrawable();
//Get default normal color
int defaultButtonColor = context.getResources().getColor(R.color.wite);
//Get default progress color
int defaultProgressColor = context.getResources().getColor(R.color.blue);
//Get default progress background color
int defaultBackColor = context.getResources().getColor(R.color.blue);
TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.ProgressLayout);
try {
mProgressMargin = attr.getDimension(R.styleable.ProgressLayout_progressMargin, mProgressMargin);
mCornerRadius = attr.getDimension(R.styleable.ProgressLayout_cornerRadius, mCornerRadius);
//Get custom normal color
int layoutColor = attr.getColor(R.styleable.ProgressLayout_layoutColor, defaultButtonColor);
//Set normal color
mDrawableLayout.setColor(layoutColor);
//Get custom progress background color
int progressBackColor = attr.getColor(R.styleable.ProgressLayout_progressBackColor, defaultBackColor);
//Set progress background drawable color
mDrawableProgressBackground.setColor(progressBackColor);
//Get custom progress color
progressColor = attr.getColor(R.styleable.ProgressLayout_progressColor, defaultProgressColor);
//Set progress drawable color
mDrawableProgress.setColor(progressColor);
//Get default progress
mProgress = attr.getInteger(R.styleable.ProgressLayout_progress, mProgress);
//Get minimum progress
mMinProgress = attr.getInteger(R.styleable.ProgressLayout_minProgress, mMinProgress);
//Get maximize progress
mMaxProgress = attr.getInteger(R.styleable.ProgressLayout_maxProgress, mMaxProgress);
} finally {
attr.recycle();
}
//Set corner radius
mDrawableLayout.setCornerRadius(mCornerRadius);
mDrawableProgressBackground.setCornerRadius(mCornerRadius);
setBackgroundDrawable(mDrawableLayout);
mFinish = false;
}
@Override
protected void onDraw(Canvas canvas) {
if (mProgress > mMinProgress && mProgress <= mMaxProgress && !mFinish) {
//Calculate the width of progress
float progressWidth =
(float) getMeasuredWidth() * ((float) (mProgress - mMinProgress) / mMaxProgress - mMinProgress);
if(progressWidth >= (getMeasuredWidth()-mCornerRadius)){
mDrawableProgress.setCornerRadii(new float[]{mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius,mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius});
} else{
mDrawableProgress.setCornerRadii(new float[]{mCornerRadius, mCornerRadius, 0, 0, 0, 0, mCornerRadius, mCornerRadius});
}
//Set rect of progress
mDrawableProgress.setBounds(0,0,
(int) (progressWidth),(int)getMeasuredHeight());
//Draw progress
mDrawableProgress.draw(canvas);
if (mProgress == mMaxProgress) {
setBackgroundDrawable(mDrawableLayout);
mFinish = true;
}
}
super.onDraw(canvas);
}
/**
* Set current progress
*/
public void setProgress(int progress) {
if (!mFinish) {
mProgress = progress;
setBackgroundDrawable(mDrawableProgressBackground);
invalidate();
}
}
public void setMaxProgress(int maxProgress) {
mMaxProgress = maxProgress;
}
public void setMinProgress(int minProgress) {
mMinProgress = minProgress;
}
public void reset() {
mFinish = false;
mProgress = mMinProgress;
}
public wavPlayer getmWavPlayer() {
return mWavPlayer;
}
}
问题出在linearLayout的圆角上。当我绘制进度时,rect不在布局之内,当它离开角落时进入内部。
答案 0 :(得分:1)
我使用以下数学公式解决了问题:
[
[
这是新代码:
@Override
protected void onDraw(Canvas canvas) {
if (mProgress > mMinProgress && mProgress <= mMaxProgress && !mFinish) {
//Calculate the width of progress
float progressWidth =
(float) getMeasuredWidth() * ((float) (mProgress - mMinProgress) / mMaxProgress - mMinProgress);
if(progressWidth >= (getMeasuredWidth()-mCornerRadius)){
float diff=progressWidth-((getMeasuredWidth()-mCornerRadius));
mDrawableProgress.setBounds(0,0,
(int) (progressWidth),(int)getMeasuredHeight());
mDrawableProgress.setCornerRadii(new float[]{mCornerRadius, mCornerRadius,diff,diff,diff, diff, mCornerRadius, mCornerRadius});
//Draw progress
mDrawableProgress.draw(canvas);
} else{
if(progressWidth<mCornerRadius){
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(progressColor);
double a=2* Math.sqrt(progressWidth*((2*mCornerRadius)-progressWidth));
float rectTop=(float)(getMeasuredHeight()-a)/2;
RectF rect=new RectF(0,rectTop,2*progressWidth,(float)(rectTop+a));
canvas.drawArc(rect,90,180,true,paint);
}else{
//Set rect of progress
mDrawableProgress.setBounds(0,0,
(int) (progressWidth),(int)getMeasuredHeight());
mDrawableProgress.setCornerRadii(new float[]{mCornerRadius, mCornerRadius, 0, 0, 0, 0, mCornerRadius, mCornerRadius});
//Draw progress
mDrawableProgress.draw(canvas);
}
}
if (mProgress == mMaxProgress) {
// setBackgroundDrawable(mDrawableLayout);
mFinish = true;
}
}
super.onDraw(canvas);
}
这里是结果: