Элемент, нарисованный в пользовательском представлении onDraw (), продолжает исчезать - PullRequest
0 голосов
/ 07 ноября 2019

Я рисую 3 вещи в своем собственном представлении в методе onDraw (): вектор, который можно нарисовать, простая линия и треугольник (из 4 точек и контура). Этот пользовательский вид отображается на вкладке.

Если я проведу пальцем, чтобы перейти на другую вкладку, я увижу, что система вызывает onDraw (). Когда я возвращаюсь на вкладку с моим пользовательским видом, векторная и простая линии все еще видны, но треугольник исчез. Если я теперь проведу пальцем по другой вкладке, onDraw () снова запустится и вернется на вкладку с пользовательским представлением, все элементы (включая треугольник) теперь будут видны. Это исчезновение / появление продолжает происходить, когда я провожу взад-вперед. Почему мой треугольник исчезает?

ОБНОВЛЕНИЕ 1 (хакерское исправление): Я попытался поэкспериментировать и заметил, что когда я перемещаю свое создание объекта Path треугольника из моего метода init () и помещаю его непосредственно в onDraw () метод - тогда все хорошо работает, ничего не пропадает. Но теперь я получаю предупреждение «Избегать выделения объектов во время рисования», так как я создаю этот объект в onDraw ();

ОБНОВЛЕНИЕ 2 (лучше исправить?): После дополнительных экспериментов,это определенно Путь, вызывающий эту проблему. Другое решение этой проблемы, которое не вызывает предупреждение «Избегать выделения объектов во время рисования»: сохраните создание пути в init () и удалите строку кода «myPath.setFillType (Path.FillType.EVEN_ODD)». Это решает мою проблему, но я понятия не имею, почему.

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        // Co-ordinates
        int width = getWidth();
        int halfWidth = width/2;
        int left = 0;
        int top = 0;
        int centreX = left + halfWidth;
        int centreY = top + halfWidth;
        int baseSize = Math.round((float)(halfWidth * 0.05));

        // Vector drawable - always draws fine!
        myVectorDrawable.setBounds(left, top, left + width, top + width);
        myVectorDrawable.draw(canvas);         

        // Simple line - always draws fine! 
        canvas.drawLine(left, top, 20, 20, paint);

        // Triangle - sometimes visible, sometimes disappears!
        Point myTriangleBottomMiddle = new Point(centreX, centreY);
        Point myTriangleBottomLeft = new Point(centreX, centreY + baseSize);
        Point myTriangleBottomRight = new Point(centreX, centreY - baseSize);
        Point myTriangleTopMiddle = new Point(centreX + halfWidth, centreY);
        myPath.moveTo(myTriangleBottomMiddle.x, myTriangleBottomMiddle.y);
        myPath.lineTo(myTriangleBottomLeft.x, mTriangleBottomLeft.y);
        myPath.lineTo(myTriangleTopMiddle.x, myTriangleTopMiddle.y);
        myPath.lineTo(myTriangleBottomRight.x, myTriangleBottomRight.y);
        mPath.close();
        canvas.drawPath(myPath, myPaint);

   }

Ниже кода, где я настраивал вещи, чтобы не обременять метод onDraw ().

private void init() {

    // Vector drawable
    myVectorDrawable = r.getDrawable(R.drawable.gauge_dial);

    // Triangle path - ** THIS BEING HERE SEEMS TO BE THE PROBLEM **
    myPath = new Path();
    myPath.setFillType(Path.FillType.EVEN_ODD);

    // Triangle Paint
    myPaint = new Paint();
    myPaint.setColor(r.getColor(R.color.black));
    myPaint.setStrokeWidth(2);
    myPaint.setAntiAlias(true);
    myPaint.setStyle(Paint.Style.FILL);

    // Simple line paint
    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
}

1 Ответ

1 голос
/ 09 ноября 2019

Добавить вызов метода reset () для пути.

    // Triangle - sometimes visible, sometimes disappears!
    Point myTriangleBottomMiddle = new Point(centreX, centreY);
    Point myTriangleBottomLeft = new Point(centreX, centreY + baseSize);
    Point myTriangleBottomRight = new Point(centreX, centreY - baseSize);
    Point myTriangleTopMiddle = new Point(centreX + halfWidth, centreY);
    myPath.reset();
    myPath.moveTo(myTriangleBottomMiddle.x, myTriangleBottomMiddle.y);
    myPath.lineTo(myTriangleBottomLeft.x, mTriangleBottomLeft.y);
    myPath.lineTo(myTriangleTopMiddle.x, myTriangleTopMiddle.y);
    myPath.lineTo(myTriangleBottomRight.x, myTriangleBottomRight.y);
    mPath.close();
    canvas.drawPath(myPath, myPaint);

Кроме того, я бы порекомендовал помещать вектор для рисования в отдельное представление, чтобы он не перерисовывался каждый раз, когда вам нужно анимировать треугольник (при условии, что этобудет анимированным циферблатом).

...