Canvas не отображает все нарисованные детали в пользовательском представлении?
Я работаю над представление для android-приложения, аналогичного аналоговому коду образца датчика, доступному из внимание робот.
запуск кода из указанного сайта, я вижу это на своем экране:
(Motorola Droid, 2.2.3), (Эмулятор, 4.0.3)
(Xoom, 4.0.3) (другой телефон, 4.0.3)
рук не хватает!
в вызовы рисования выполняются (я вижу их в 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)
мой метод 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();
}
для тех, у кого есть проблемы с масштабированием текста в инициализации, сделайте следующее:
scalePaint.setLinearText (true);