#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 пикселов, то есть со сдвигом на одно деление линейки в левую сторону экрана.
Комментариев нет:
Отправить комментарий