有时会绘制自定义视图

时间:2017-03-24 17:01:56

标签: java android android-activity android-custom-view

我有自定义视图,有时会被绘制,有时候不会...这可以在多个手机上重现。

不知道为什么会发生这种情况..在GalleryGridElement(相对布局)的onMeasure调用期间调用setDimensions(),我在recyclelerview中将其用作gallery元素。

一个例子是..进入回收站视图库活动,循环进度视图就在那里..当你离开活动并回来时... onResume创建一个新的适配器并将其提供给回收站视图..但是圆形进度视图此时不显示:

public class CircularProgressView extends View {

private Paint mIndicatorColour;
private RectF mIndicatorRect;
private Paint mBackCircleColour;

private static final float START_ANGLE = -90;
private volatile float mStopAngle = 0;

private float mOutterCircleStrokeWidth = 20;
private float mInnerCircleStrokeWidth = 16;

private float mViewWidth = 0, mViewHeight = 0;
private volatile int mCurrentProgress = 0;

private ExecutorService mExecutorService;

public CircularProgressView(Context context) {
    super(context);
    setUp();
}

public CircularProgressView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setUp();
}

public CircularProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setUp();
}

private void setUp(){

    mIndicatorRect = new RectF(0,0,300,300);

    mIndicatorColour = new Paint();
    mIndicatorColour.setColor(Color.parseColor("#D62F85"));
    mIndicatorColour.setStyle(Paint.Style.STROKE);
    mIndicatorColour.setStrokeWidth(mInnerCircleStrokeWidth);
    mIndicatorColour.setAntiAlias(true);
    mIndicatorColour.setDither(true);
    mIndicatorColour.setStrokeJoin(Paint.Join.ROUND);
    mIndicatorColour.setStrokeCap(Paint.Cap.ROUND);

    mBackCircleColour = new Paint();
    mBackCircleColour.setColor(Color.WHITE);
    mBackCircleColour.setStyle(Paint.Style.STROKE);
    mBackCircleColour.setStrokeWidth(mOutterCircleStrokeWidth);
    mBackCircleColour.setAntiAlias(true);
    mBackCircleColour.setDither(true);
    mBackCircleColour.setStrokeJoin(Paint.Join.ROUND);
    mBackCircleColour.setStrokeCap(Paint.Cap.ROUND);

    mExecutorService = Executors.newSingleThreadExecutor();

}

public void setDimensions(float width, int scaleCircleThicknessValue){
    mViewHeight = width;
    mViewWidth = width;
    mIndicatorRect.left = mIndicatorRect.top = mOutterCircleStrokeWidth;
    mIndicatorRect.right = mIndicatorRect.bottom = width - mOutterCircleStrokeWidth;
    mIndicatorColour.setStrokeWidth(mInnerCircleStrokeWidth);
    mBackCircleColour.setStrokeWidth(mOutterCircleStrokeWidth);

    mInnerCircleStrokeWidth = (0.1f * scaleCircleThicknessValue) * width;
    mOutterCircleStrokeWidth = mInnerCircleStrokeWidth + 5;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int desiredWidth = Math.round(mViewWidth);
    int desiredHeight = Math.round(mViewHeight);

    int width;
    int height;

    //Measure Width
    if (widthMode == MeasureSpec.EXACTLY) {
        //Must be this size
        width = widthSize;
    } else if (widthMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        width = Math.min(desiredWidth, widthSize);
    } else {
        //Be whatever you want
        width = desiredWidth;
    }

    //Measure Height
    if (heightMode == MeasureSpec.EXACTLY) {
        //Must be this size
        height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        height = Math.min(desiredHeight, heightSize);
    } else {
        //Be whatever you want
        height = desiredHeight;
    }

    //Set values
    setMeasuredDimension(width, height);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.drawArc(mIndicatorRect, 0, 360, false, mBackCircleColour);
    canvas.drawArc(mIndicatorRect, START_ANGLE, mStopAngle, false, mIndicatorColour);
}

public synchronized void setProgress(final int progress) {

    if ((mCurrentProgress != progress) && (progress > 0)) {

        mCurrentProgress = progress;

        mExecutorService.submit(new Runnable() {
            @Override
            public void run() {

                final float currentAngle = mStopAngle;

                float newAngle = (360f * ((float) progress / 100f));

                float step = (Math.round(newAngle) - Math.round(currentAngle)) <= 1 ? 1 : (newAngle - currentAngle)/5f;

                if (step < 0.01) {
                    newAngle = 359;
                }

                for (float i = currentAngle; i < newAngle; i += step) {
                    try {
                        mStopAngle = i;
                        postInvalidate();
                        Thread.sleep(1000 / 60);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        });


    }
}

public float getProgress(){
    return (360f-mStopAngle) < 1f ? 1 : mStopAngle / 360f;
}


}

1 个答案:

答案 0 :(得分:0)

只是跟进这个问题,有人遇到了这个问题:

因为我在自定义视图中使用了回收器视图的自定义视图。 当我将视图持有者绑定到模型时,我确保完全重新渲染视图...即:

    mCircularProgressView.setVisibility(VISIBLE);
    mCircularProgressView.setDimensions(getWidth() * 0.82f, 1);
    mCircularProgressView.requestLayout();
    mCircularProgressView.postInvalidate();

这确保无论如何都可以绘制视图。