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

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

巴扎黑
巴扎黑

reply all(4)
Peter_Zhu

If it is not placed in ListView, can the animation effect you want be executed normally?

Peter_Zhu

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

大家讲道理

When customizing a control, overwrite onDraw(). If it is not drawn, why is it displayed? Also consider the reuse mechanism of View in getItem in ListView.

伊谢尔伦

You can try adding the onLayout method. onMeasure and onLayout are generally used together when customizing View.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!