自定义视图仅在XML预览

时间:2017-02-03 09:29:03

标签: android android-custom-view android-xml

我有一个自定义视图(圆圈),可在应用运行时正确呈现。但是,在XML预览窗格中查看时,视图未正确对齐。

以下是预览窗格的屏幕截图,其中对齐方式不正确。

enter image description here

以下是在正在运行的应用上绘制时具有正确对齐的相同视图的屏幕截图。

enter image description here

以下是定义自定义视图的代码 -

public class LinearTimerView extends View {

    private Paint arcPaint;
    private RectF rectF;

    private int initialColor;
    private int progressColor;
    private int circleRadiusInDp;

    // The point from where the color-fill animation will start.
    private int startingAngle = 270;

    // The point up-till which user wants the circle to be pre-filled.
    private float preFillAngle;

    public LinearTimerView(Context context,
                           AttributeSet attrs) {
        super(context, attrs);

        TypedArray typedArray = getContext().obtainStyledAttributes(attrs,
                R.styleable.LinearTimerView);

        // Retrieve the view attributes.
        this.circleRadiusInDp =
                (int) typedArray.getDimension(R.styleable.LinearTimerView_radius, 5);
        int strokeWidthInDp =
                (int) typedArray.getDimension(R.styleable.LinearTimerView_strokeWidth, 2);
        this.initialColor =
                typedArray.getColor(R.styleable.LinearTimerView_initialColor,
                        ContextCompat.getColor(getContext(), R.color.colorInitial));
        this.progressColor =
                typedArray.getColor(R.styleable.LinearTimerView_progressColor,
                        ContextCompat.getColor(getContext(), R.color.colorProgress));
        this.startingAngle =
                typedArray.getInt(R.styleable.LinearTimerView_startingPoint, 270);

        // Define the size of the circle.
        rectF = new RectF(
                (int) convertDpIntoPixel(strokeWidthInDp),
                (int) convertDpIntoPixel(strokeWidthInDp),
                (int) convertDpIntoPixel(circleRadiusInDp * 2)
                        + (int) convertDpIntoPixel(strokeWidthInDp),
                (int) convertDpIntoPixel(circleRadiusInDp * 2)
                        + (int) convertDpIntoPixel(strokeWidthInDp));

        arcPaint = new Paint();
        arcPaint.setAntiAlias(true);
        arcPaint.setStyle(Paint.Style.STROKE);
        arcPaint.setStrokeWidth((int) convertDpIntoPixel(strokeWidthInDp));

        typedArray.recycle();
    }

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

        try {
            // Grey Circle - This circle will be there by default.
            arcPaint.setColor(initialColor);
            canvas.drawCircle(rectF.centerX(), rectF.centerY(),
                    (int) convertDpIntoPixel(circleRadiusInDp), arcPaint);

            // Green Arc (Arc with 360 angle) - This circle will be animated as time progresses.
            arcPaint.setColor(progressColor);
            canvas.drawArc(rectF, startingAngle, preFillAngle, false, arcPaint);
        } catch (NullPointerException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Method to get the degrees up-till which the arc is already pre-filled.
     * @return
     */
    public float getPreFillAngle() {
        return preFillAngle;
    }

    public void setPreFillAngle(float preFillAngle) {
        this.preFillAngle = preFillAngle;
    }

    /**
     * Method to get the starting point of the angle
     * @return
     */
    public int getStartingPoint() {
        return startingAngle;
    }

    public void setStartingPoint(int startingPointInDegrees) {
        this.startingAngle = startingPointInDegrees;
    }

    /**
     * Method to convert DPs into Pixels.
     */
    private float convertDpIntoPixel(float dp) {
        float scale = getResources().getDisplayMetrics().density;
        return dp * scale + 0.5f;
    } }

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

原来我没有覆盖h onMeasure()方法。

我采用提示形式this回答并且能够解决问题。