android - ListView中放Progress不显示进度
巴扎黑
巴扎黑 2017-04-17 17:08:38
0
4
726

在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);的时候不显示进度,请问是什么原因。急

巴扎黑
巴扎黑

모든 응답(4)
Peter_Zhu

ListView에 배치되지 않으면 원하는 애니메이션 효과가 정상적으로 실행될 수 있나요?

Peter_Zhu

이전에 이런 문제가 발생한 적이 있습니다. 나중에 이 문제는 ListView과 같은 컨트롤의 재사용 메커니즘과 관련이 있음이 밝혀졌지만 시스템의 Progress을 사용하는 데는 문제가 없으므로 사용자 정의 컨트롤의 불완전한 메소드 적용으로 인해 발생합니다. 당시 내 솔루션은 시스템에서 제공하는 컨트롤을 사용한 다음 속성을 추가하는 것이었습니다.
귀하의 컨트롤에 있는 코드는 컨트롤의 기본 내용인 onSaveInstanceState, onRestoreInstanceState, invalidate 등이 덮어쓰여지지 않은 것으로 확인됩니다.
제가 제공하는 해결책은 다음과 같습니다. 시스템 컨트롤이 요구 사항을 충족할 때 시스템 컨트롤을 사용합니다. (CircleProgressIndicator과 유사) 주요 기능을 재정의하여 사용해 보세요(여기에서는 위의 세 가지 기능이 모두 적용됩니다). 특히 invalidate);

처리됩니다.
大家讲道理

컨트롤을 맞춤설정할 때 onDraw()를 덮어쓰면 표시되는 이유는 무엇인가요? 또한 ListView의 getItem에 있는 View의 재사용 메커니즘을 고려하세요.

伊谢尔伦

onLayout 메소드를 추가해 볼 수 있습니다. onMeasure와 onLayout은 일반적으로 View를 맞춤설정할 때 함께 사용됩니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿