Canvas не отображает все нарисованные детали в пользовательском представлении?

Я работаю над представление для android-приложения, аналогичного аналоговому коду образца датчика, доступному из внимание робот.

запуск кода из указанного сайта, я вижу это на своем экране:

(Motorola Droid, 2.2.3), (Эмулятор, 4.0.3)

has an arrow

(Xoom, 4.0.3) (другой телефон, 4.0.3)

does not have an arrow

рук не хватает!

в вызовы рисования выполняются (я вижу их в logcat), но элементы canvas, которые рисуют вызовы, невидимы.

Это не зависит от уровня API, хотя; если я импортирую его правильно в проект, он будет отображаться, когда я запускаю его на Xoom.

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

Что происходит? Как может один и тот же код производить такие разные результаты на разных устройствах?

7 ответов


таким образом, ключевым ключом к моей тайне, казалось, было то, что он работал на эмуляторе, но не на аппаратных устройствах.

Аппаратной Визуализации

Я просмотрел страницу аппаратного рендеринга на веб-сайте разработчика Android, но, по-видимому, недостаточно близко.

http://developer.android.com/guide/topics/graphics/hardware-accel.html

хотя в нем упоминается, что API доступны начиная с версии 11, он не говорит, что аппаратный рендеринг включен для всех приложений по умолчанию, начиная с уровня API 14 (ICS).

что это значит для нас?

почти все быстрее; за исключением немногих вещей, которые не работают.

я умудрился нарушить два из них, не осознавая этого:

  • холст.DrawTextOnPath()
  • краски.setShadowLayer ()

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

в моем случае, холст.DrawTextOnPath (), казалось, работал просто отлично.

но когда Android заметил, что краска, которую я использовал на руке, имела теневой слой, она молча проигнорировала его.

как узнать, ускорено ли мое представление?

из ссылки на документацию выше:

существует два разных способа проверить, является ли приложение аппаратным ускорением:

  • вид.isHardwareAccelerated () возвращает true, если представление подключено к аппаратному ускоренному окну.
  • холст.isHardwareAccelerated () возвращает true, если холст аппаратно ускорен

Если вы должны сделать эту проверку в коде чертежа, используйте Canvas.isHardwareAccelerated() Вместо >из Вид.isHardwareAccelerated (), когда это возможно. Когда представление присоединено к окну аппаратное >ускоренное, его можно нарисовать с помощью не аппаратного ускоренного холста. Это > происходит, например, при рисовании представления в растровое изображение для целей кэширования.

в моем случае, похоже, произошло обратное. Пользовательский вид регистрирует, что он не аппаратно ускорен; однако холст сообщает, что он аппаратно ускорен.

способы и Крепления

самое простое исправление-заставить пользовательский вид выполнять рендеринг программного обеспечения. В документации это может быть выполнено с помощью:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

кроме того, вы можете удалить оскорбительные операции и включить аппаратный рендеринг.

учитесь на моем несчастье. Удачи всем.


Я поместил его в init () и работал нормально после этого.

    private void init() {
    setLayerType(myView.LAYER_TYPE_SOFTWARE, null);
    ....
}

Орел, где именно вы называете эту линию? Я называю его после инициализации:

    tachometer = (CustomRoundInstrument) theFragment.findViewById(R.id.tachometer);
    tachometer.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Thatdoes не работает, хотя, я должен назвать это в другом месте?

помощь приветствуется!


С myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); предложение я могу видеть руку. Но у меня все еще проблема: я вижу масштаб только с 0 написанным! Как на картинке, так и два нуля strage из схемы: (GALAXY NEXUS 4.2.1)

enter image description here

мой метод drawScale (), как в Примере:

 private void drawScale(Canvas canvas) {
        canvas.drawOval(scaleRect, scalePaint);

        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        for (int i = 0; i < totalNicks; ++i) {
            float y1 = scaleRect.top;
            float y2 = y1 - 0.020f;

            canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);


            if ((i % 5) == 0) {
                int value = nickToDegree(i);

                if ((value >= minDegrees) && (value <= maxDegrees)) {
                    String valueString = Integer.toString(value);
                    canvas.drawText(valueString, 0.5f, y2 - 0.015f, scalePaint);

                }
            }

            canvas.rotate(degreesPerNick, 0.5f, 0.5f);


        }
        canvas.restore();

    }

в моем случае я сделал так:

 AnalogView bar = (AnalogView) findViewById(R.id.AnalogBar);
    bar.setLayerType(bar.LAYER_TYPE_SOFTWARE, null);
if (value_list.size()>0)   bar.SetData(Double.parseDouble(value_list.get(value_list.size()-1)));

где SetData в AnalogView является

public  void SetData(double data) {
    setHandTarget((float)data);
  invalidate();
}

На Galaxy S4 Android 4.4.2

TYPE_TEMPERATURE осуждается

использовать

TYPE_AMBIENT_TEMPERATURE


для тех, у кого есть проблемы с масштабированием текста в инициализации, сделайте следующее:

scalePaint.setLinearText (true);