Пользовательский вид не отображается - PullRequest
0 голосов
/ 06 мая 2018

Это моя первая попытка создания пользовательских видов в Android. Тем не менее, я, кажется, что-то пропустил и не знаю, как отладить проблему. Я написал собственный вид для рисования диаграммы в Android с их значениями ниже столбцов. Мой метод onDraw в коде выглядит следующим образом:

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    if (mBars == null) {
        return
    }
    canvas.save()
    val rectBaseLine = measuredHeight * FRACTIONAL_MAX_BAR_HEIGHT + convertDpToPixel(TOP_MARGIN_FOR_BAR, context);
    canvas.translate(0f, rectBaseLine.toFloat())

    mBars.forEach {
        canvas.drawRoundRect(it.mRect,
                BAR_CORNER_RADIUS, BAR_CORNER_RADIUS,
                mapToPaints.getValue(it.paintType))

        var textWidth = textPaint.measureText(it.num.toString())

        canvas.drawText(it.num.toString(),
                it.mRect.left + (it.mRect.right - it.mRect.left) / 2 - textWidth / 2,
                convertSpToPixel(TEXT_SIZE, context) + convertDpToPixel(DISTANCE_BW_TEXT_N_BAR, context),
                mapToTextPaints.getValue(it.paintType))
    }

    canvas.restore()
}

fun prepareBarsArr(arr: IntArray) {
    val max = arr.max();
    val viewHeight = measuredHeight
    val rectHeight = measuredHeight * FRACTIONAL_MAX_BAR_HEIGHT /*- ( convertSpToPixel(TEXT_SIZE, context) +  convertDpToPixel(DISTANCE_BW_TEXT_N_BAR, context))*/;
    val width = measuredWidth
    widthPerBar = (width - INTER_BAR_GAP * (arr.size - 1)) / arr.size

    var currentX = -widthPerBar - INTER_BAR_GAP
    mBars = Array<BarDetails>(arr.size, {
        val desiredHeight = arr[it] * rectHeight / max!!
        currentX += widthPerBar + INTER_BAR_GAP
        val mRect = RectF(currentX.toFloat(), 0f, (currentX + widthPerBar).toFloat(), (-desiredHeight).toFloat());
        BarDetails(mRect, arr[it], STATEPAINTS.NORMAL)
    });


    invalidate()
}

mBars хранит информацию, связанную с Bar, например: объект Rect, числовое значение (которое помогает определить высоту бара), используемую краску и т. Д.

Проблема в том, что этот код отлично работает на эмуляторе, но на моем устройстве (с использованием Lenovo Zuk Z2 Plus) он не рисует столбцы. Я проверил несколько постов и попробовал разные комбинации с hardwareAccelerated = "true / false" и drawRoundRect / drawRect и т. д. Была только 1 комбинация, в которой столбцы отображались на моем устройстве, что было, когда hardwareAccelerated было ложно, и я использовал drawRect. Однако, когда я использую RoundedRect, столбцы не отображаются. Не знаю, относится ли это к конкретной проблеме, так как у меня есть только 1 устройство для тестирования. В любом случае, некоторые пункты о том, как отладить это, были бы полезны.

1 Ответ

0 голосов
/ 09 мая 2018

Решено это, переписав логику для создания баров. В рассматриваемом коде я использовал для перевода холста, а затем рисовал бары / Rect снизу вверх. Я просто изменил вычисления, чтобы создать Rect с Top в верхней части Rect и Bottom в rectHeight. Ниже приведен модифицированный код, который отображает даже RoundedRect. У меня есть андроид: hardwareAccelerated = "false" в моем файле манифеста. Кроме того, раньше я занимался сохранением и восстановлением, что сейчас не требуется, поскольку перевод canvas не сделан.

fun prepareBarsArr(arr: IntArray) {
    val max = arr.max();
    val viewHeight = measuredHeight
    val rectHeight = measuredHeight * FRACTIONAL_MAX_BAR_HEIGHT /*- ( convertSpToPixel(TEXT_SIZE, context) +  convertDpToPixel(DISTANCE_BW_TEXT_N_BAR, context))*/;
    val width = measuredWidth
    widthPerBar = (width - INTER_BAR_GAP * (arr.size + 1)) / arr.size

    var currentX = INTER_BAR_GAP
    mBars = Array<BarDetails>(arr.size, {
        val desiredHeight = arr[it] * rectHeight / max!!
        val mRect = RectF(currentX.toFloat(),
                rectHeight - desiredHeight,
                (currentX + widthPerBar).toFloat(),
                (rectHeight).toFloat()
        );
        currentX += widthPerBar + INTER_BAR_GAP
        BarDetails(mRect, arr[it], STATEPAINTS.NORMAL)
    });


    invalidate()
}

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    if (mBars == null) {
        return
    }

    /*val rectBaseLine = measuredHeight * FRACTIONAL_MAX_BAR_HEIGHT + convertDpToPixel(TOP_MARGIN_FOR_BAR, context);*/ /*- ( convertSpToPixel(TEXT_SIZE, context) +  convertDpToPixel(DISTANCE_BW_TEXT_N_BAR, context))*/;
    /*canvas.translate(0f, rectBaseLine.toFloat())*/

    mBars.forEach {
        canvas.drawRoundRect(it.mRect,
                BAR_CORNER_RADIUS, BAR_CORNER_RADIUS,
                mapToPaints.getValue(it.paintType))

        var textWidth = textPaint.measureText(it.num.toString())

        canvas.drawText(it.num.toString(),
                it.mRect.left + (it.mRect.right - it.mRect.left) / 2 - textWidth / 2,
                convertSpToPixel(TEXT_SIZE, context) + convertDpToPixel(DISTANCE_BW_TEXT_N_BAR, context) + it.mRect.bottom,
                mapToTextPaints.getValue(it.paintType))
    }
}

Если кто-то хотел бы добавить, я был бы признателен за обоснование этого. Что-то не так с переводом холста или с сохранением и восстановлением? Я не знаю, почему он работал нормально на эмуляторе, а не на устройстве.

...