Intereting Posts
Android ADB: имитировать недавнее нажатие клавиши приложения Как создать простой-xml-аннотированный объект java из схемы xsd Сообщение об ошибке при установке приложения – УСТАНАВЛИВАЕТСЯ НЕ СООТВЕТСТВУЕТ ABIS Цветовая гамма и артефакты с градиентами, несмотря на использование RGBA_8888 во всем мире Android ClassNotFoundException: не нашел класс на пути IAB подписали данные без заказов в нем Уникальный идентификатор Android-устройства Как добавить значок значка / счетчик приложений на устройства Sony Xperia? Почему ListView и RecyclerView focusableInTouchMode? Android Device Monitor File Explorer не работает с эмулятором, работающим с API 24+ Как Android интерпретирует ключевое слово @null в макетах? Android: два Spinner onItemSelected () Настройка Drawable в качестве цвета текста вызывает исключение. Значение цвета должно начинаться с # Android RecyclerView с CardView – показать карты в стеке (не список) Растровые изображения ALPHA_8 и getPixel

Эффективный onDraw of ArrayList

У меня есть пользовательский вид, на котором я рисую ArrayList of Coordinates (который представляет собой пользовательский класс, содержащий только положение x и y). Поскольку в ArrayList добавляются все больше координат, рисунок заметно замедляется. Мне было интересно, есть ли более эффективный способ рисовать этот ArrayList или, альтернативно, если я могу просто добавить добавленный один Координат (потому что ArrayList меняет только одну координату между вызовами, чтобы сделать недействительным).

Вот соответствующие фрагменты кода:

public class CustomDraw extends View { // member variables public void updateLine() { // grab new coordinates for each measure if(measure1.isEmpty()) { measure1.add(new Coordinate(0, 0)); } else { Coordinate last_coord = measure1.get(measure1.size() - 1); // calculations for south, north, east, and west if(south && east) { measure1.add(new Coordinate(last_coord.x + 3, last_coord.y + 3)); } else if(south && west) { measure1.add(new Coordinate(last_coord.x - 3, last_coord.y + 3)); } else if(north && east) { measure1.add(new Coordinate(last_coord.x + 3, last_coord.y - 3)); } else if(north && west) { measure1.add(new Coordinate(last_coord.x - 3, last_coord.y - 3)); } } if(draw) { dh.sleep(10); } } @Override public void onDraw(Canvas c) { super.onDraw(c); Paint p = new Paint(); p.setStyle(Paint.Style.FILL); p.setColor(Color.WHITE); c.drawPaint(p); p.setColor(Color.BLACK); switch(mSelected) { case Constants.MEASURE_1: for(int i = 0; i < measure1.size(); i++) { Coordinate coord = measure1.get(i); Log.d("MAAV", "drawing coord.x, coord.y: " + (coord.x) + ", " + (coord.y)); c.drawRect(coord.x, coord.y, coord.x + 3, coord.y + 3, p); } break; } } class DrawHandler extends Handler { @Override public void handleMessage(Message msg) { CustomDraw.this.updateLine(); CustomDraw.this.invalidate(); } public void sleep(long delayMillis) { this.removeMessages(0); sendMessageDelayed(obtainMessage(0), delayMillis); } } } 

Спасибо за любую помощь!

Вы объявляете coord каждой итерации цикла. Вам не нужно это делать, и выделение памяти для объектов может быть дорогостоящим. Переместите это за пределы цикла и просто повторно используйте объект. Также попробуйте прокомментировать вызовы журнала или зарегистрировать только каждый 10-й элемент.

 Coordinate coord; for(int i = 0; i < measure1.size(); i++) { coord = measure1.get(i) if (i%10==0) Log.d("MAAV", "drawing coord.x, coord.y: " + (coord.x) + ", " + (coord.y)); c.drawRect(coord.x, coord.y, coord.x + 3, coord.y + 3, p); } 

Если эти обновления не улучшают производительность, достаточно рассмотреть возможность использования OpenGL ES для создания чертежа.

За исключением улучшения, предложенного Slayton, также может быть целесообразно использовать HashSet вместо ArrayList. Таким образом, вы не сможете добавлять дубликаты координат. Я не знаю, делаете ли вы это, но если вы это улучшите, это уменьшит итерации.

Если вы решите сделать это, вам необходимо реализовать метод equals для вашего класса Coordinate, который, я уверен, вы знаете. Или вы также можете использовать класс Java-Point, если ваша координата просто удерживает позиции x и y.

Мой подход состоял бы в том, чтобы нарисовать ваш холст в растровом изображении (или, возможно, использовать расширение ImageView и использовать backgroundDrawable) на каждом onDraw. Добавьте поле в свой класс, чтобы сохранить последнюю новую координату, а затем в последующих onDraws, получить растровое изображение и добавить только новую координату. Чтобы сбросить настройки, просто установите фоновое растровое изображение снова (или используйте View.setBackground так, как вы сейчас). Я не тестировал это, и он мог использовать некоторые улучшения, но, надеюсь, он дает вам эту идею и будет суперэффективным, если, как вы говорите, вы добавляете только одну координату за раз.

 public class CustomDraw extends View { public Bitmap backgroundBitmap; public Coordinate newCoordinate; ... ... @Override public void onDraw(Canvas c) { // no super.onDraw as we are drawing everything Canvas backgroundCanvas = new Canvas(backgroundBitmap); ... ... // draw new co-ordinate to the background bitmap if (newCoordinate != null ){ drawCoordinate(backgroundCanvas, newCoordinate); newCoordinate = null; } // draw the background bitmap to the view's canvas c.drawBitmap(backgroundBitmap, null, null); ... ... }