#android #customview
Не могу разобраться, как можно реализовать циклическую прокрутку шкалы. Рисую ее в customview: public void onDraw(Canvas canvas){ startingPoint = mainPoint; counter = 0; for (int i = 1;; i++) { if (startingPoint > screenSize) { break; } if(i % 4 == 0) { size = scaleHeight / 4; counter = counter + 1; } else { if(i % 2 == 0) { size = scaleHeight / 8; } else { size = scaleHeight / 16; } } canvas.drawLine(startingPoint, endPoint - size, startingPoint, endPoint, rulerPaint); if (i % 4 == 0) { String c = Integer.toString(counter); canvas.drawText(c, startingPoint, endPoint - (size + 20), textPaint); } startingPoint = startingPoint + pxmm; } Ограничиваю ее до одиннадцати длинных делений: Но мне нужна бесконечная шкала: Допустим, можно убрать проверку значения counter в onDraw методе, но как это скажется на производительности? Даже если ставлю его значение 1000, уже заметны "подлагивания" при скроллинге. Вот мой onScroll: public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { mainPoint = mainPoint - distanceX; invalidate(); return true; } И onMeasure: protected void onMeasure(int w, int h) { DisplayMetrics metrics = new DisplayMetrics(); ((Activity)getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics); h = metrics.heightPixels / 5; w = metrics.widthPixels; setMeasuredDimension(w, h); scaleHeight = h; scaleWidth = w; screenSize = w; endPoint = h; midScreenPoint = w / 2; pxmm = screenSize / 28; } Каким образом реализуются подобные задачи?
Ответы
Ответ 1
Надо рисовать шкалу от начала экрана до его конца. Т.е. цикл должен быть не по шкале, а по ширине экрана. А в цикле уже вести счетчик по шкале, как только он достигнет 11, обнулять. Такой подход позволит легко рисовать и шкалу со смещением, просто присваиваете счетчику шкалы это смещение вначале и готово. Скроллинг будет не нужным.Ответ 2
В текущей реализации происходит следующее: mainPoint инициализируется нулем. в onScroll mainPoint изменяется на значение -distanceX, соответсвенно при скролле в положительное направление по оси X значение mainPoint будет уменьшатся. То есть в какой-то момент значение mainPoint будет предположим -1000. Но при этом значение, возвращаемое из getScrollX() будет как раз таки 1000, поскольку View будет проскроллено как раз на это значение. Метод onDraw считает, что координаты View следующие: (l, t, r, b) == (0, 0, getMeasuredWidth(), getMeasuredHeight()) и цикл в onDraw будет отрисовывать линейку от значения -1000 до getMeasuredWidth() каждый раз - из за этого и возникают лаги и подергивания. Чтобы их не было нужно отрисовывать линейку не от -1000, а от 0. Собственно видимо это и имел в виду Евгений. Как можно исправить: В onDraw получать значение из getScrollX()(либо брать тот же mainPoint) и рассчитывать метку линейки в нулевой координате. В моем примере с 1000 и значением pxmm предположим 24 получается, что в нулевой координате метки линейки будет 41,6(6). Соответственно метка линейки 41 и 41,5 будут за пределом видимости, а значение 42 как раз будет отрисовано со сдвигом 42 * 24 - 1000 = 8 пикселов от левого края экрана. Единственное что - надо отрисовывать немного не с нуля, а с отрицательного значения, потому что метка может быть за пределами экрана, а сама цифра может частично уже попадать на экран. В принципе, чтобы не особо заморачиваться, можно начинать отрисовывать со значения 41 * 24 - 1000 = -16 пикселов, то есть со сдвигом на одно деление линейки в левую сторону экрана.
Комментариев нет:
Отправить комментарий