首页 > ListView中放Progress不显示进度

ListView中放Progress不显示进度

在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等控件的重用机制相关,而使用系统的Progress就没有问题,所以就是说自定义控件的方法覆盖不完整造成的。我当时的解决方式是使用系统提供的控件再添加属性做的。
我看你的控件里代码都是控件的基本内容,像是onSaveInstanceStateonRestoreInstanceStateinvalidate都没有覆写。
我给你的解决方案是:在系统控件满足要求时使用系统控件;使用第三方控件(类似于CircleProgressIndicator);覆写主要函数试一试(这里将上述三个函数都处理一下,特别是invalidate);


自定义控件时,复写一下onDraw(),没有画出来,怎么会显示?还有要考虑一下ListView中getItem中View的复用机制。


你可以试一下加上onLayout方法,onMeasure和onLayout在自定义View时一般一起用。


如果不放在ListView中,是否能正常执行你要的动画效果?

【热门文章】
【热门文章】