在ListView中我每个Item都放了一个自己定义的progress,代码如下:
public class LProgressBar extends View {
private final int DEFAULT_HEIGHT = dp2px(10);
private static final int DEFAULT_REACHED_COLOR = 0xFFE66059;
private static final int DEFAULT_UNREACHED_COLOR = 0xFF7A9B5B;
private static final int DEFAULT_ANIMATE_DURATION = 1000;
private static final int DEFAULT_MAX_VALUE = 100;
private static final int DEFAULT_PROGRESS = 0;
private static final Boolean DEBUG = false;
private int mHeight;
private int mRealWidth;
private int mReachedColor;
private int mUnreachedColor;
private int mDuration;
private float mProgress;
private int mMaxValue;
private boolean debug;
private Paint mUnreachedPaint;
private Paint mReachedPaint;
public LProgressBar(Context context) {
this(context, null);
}
public LProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
obtainStyledAttributes(attrs);
reset();
}
private void obtainStyledAttributes(AttributeSet attrs) {
final TypedArray attr = getContext().obtainStyledAttributes(attrs, R.styleable.LProgressBar);
mHeight = (int) attr.getDimension(R.styleable.LProgressBar_ruman_height, DEFAULT_HEIGHT);
mReachedColor = attr.getColor(R.styleable.LProgressBar_ruman_reached_color, DEFAULT_REACHED_COLOR);
mUnreachedColor = attr.getColor(R.styleable.LProgressBar_ruman_unreached_color, DEFAULT_UNREACHED_COLOR);
debug = attr.getBoolean(R.styleable.LProgressBar_ruman_debug, DEBUG);
mDuration = (int) attr.getDimension(R.styleable.LProgressBar_ruman_duration, DEFAULT_ANIMATE_DURATION);
mProgress = (float) attr.getFloat(R.styleable.LProgressBar_ruman_progress, DEFAULT_PROGRESS);
mMaxValue = (int) attr.getDimension(R.styleable.LProgressBar_ruman_maxvalue, DEFAULT_MAX_VALUE);
attr.recycle();
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = 100;
if (widthMode == MeasureSpec.AT_MOST)
width = Math.min(widthSize, 100);
}
if (heightMode == MeasureSpec.EXACTLY)
height = heightSize;
else {
height = mHeight;
if (heightMode == MeasureSpec.AT_MOST)
height = Math.min(heightSize, mHeight);
}
setMeasuredDimension(width, height);
mRealWidth = getMeasuredWidth();
}
@Override
protected synchronized void onDraw(Canvas canvas) {
canvas.drawLine(0, 0, mRealWidth, 0, mUnreachedPaint);
canvas.drawLine(0, 0, mProgress, 0, mReachedPaint);
}
private void reset() {
initUnreachedPaint();
initReachedPaint();
}
private void initUnreachedPaint() {
mUnreachedPaint = new Paint();
mUnreachedPaint.setColor(mUnreachedColor);
mUnreachedPaint.setStrokeWidth(dp2px(mHeight));
}
private void initReachedPaint() {
mReachedPaint = new Paint();
mReachedPaint.setColor(mReachedColor);
mReachedPaint.setStrokeWidth(dp2px(mHeight));
}
public synchronized void setProgress(float progress) {
float radio = (float) progress * 1.0f / mMaxValue * 1.0f;
mProgress = (float) mRealWidth * radio * 1.0f;
invalidate();
// startProgressAnim();
}
private void startProgressAnim() {
ValueAnimator animator = ValueAnimator.ofFloat(0, mProgress);
animator.setDuration(mDuration);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
mProgress = value;
invalidate();
}
});
animator.start();
}
/**
* dp2px
*
* @param dpValue dp
* @return px
*/
private int dp2px(int dpValue) {
return (int) getContext().getResources().getDisplayMetrics().density * dpValue;
}
我在adapter中getView()
方法中去lProgressBar.setProgress(50.0f);
的时候不显示进度,请问是什么原因。急
ListViewに配置しない場合、希望のアニメーション効果は正常に実行できますか?
私は以前にこの問題に遭遇したことがあります。その後、この問題は
が処理されます。ListView
などのコントロールの再利用メカニズムに関連していることが判明しましたが、システムのProgress
の使用には問題がないため、カスタム コントロールのメソッド カバレッジが不完全であることが原因でした。当時の私の解決策は、システムが提供するコントロールを使用し、プロパティを追加することでした。コントロール内のコードはコントロールの基本的な内容であり、
onSaveInstanceState
、onRestoreInstanceState
、invalidate
などは上書きされません。私が提案する解決策は、システム コントロールが要件を満たしている場合はシステム コントロールを使用することです。(
CircleProgressIndicator
と同様) メイン関数をオーバーライドして試してください。特にinvalidate
);コントロールをカスタマイズするときに、onDraw() を上書きします。描画されていない場合、なぜ表示されますか? ListView の getItem における View の再利用メカニズムも考慮してください。
onLayout メソッドを追加してみてください。onMeasure と onLayout は通常、View をカスタマイズするときに一緒に使用されます。