Я написал собственное представление, которое рисует график, и заставляю его перерисовывать, используя invalidate каждые 20 мс.Очень редко, через некоторое время приложение перестает отвечать на входные данные.График будет продолжать рисоваться, и кнопки будут переключаться на нажатие при нажатии, но они не будут вызывать метод onclick.На этом этапе, если я выйду из приложения, я не смогу открыть его снова, пока не убью его.
Я предполагаю, что это из-за перерисовки, потому что уменьшение таймера перерисовки до каждых 100 мс делает этопроблема исчезла (по крайней мере, из моих тестов), но, делая ее быстрее (10 мс), она становится более устойчивой.
Кажется, я ничего не могу найти в Интернете, и приложение не падает, поэтому я не получаю никакой ошибки в Android studio
Код для розыгрыша
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(data.size() == 0) {
DrawNoData(canvas);
return;
}
int width = getWidth();
int height = getHeight();
int elWidth = (width - offset * 2) / data.size();
int outline = 2;
Iterator<Point> iterator = data.iterator();
int i = 0;
DecimalFormat df = new DecimalFormat("#0.#");
textPaint.setTextAlign(Paint.Align.CENTER);
if(data.size()>20) {
textPaint.setTextSize(20);
} else {
textPaint.setTextSize(40);
}
while(iterator.hasNext()){
Point next = iterator.next();
int penX = offset + i * elWidth + elWidth/2;
int penY = lerp(offset, height - offset, maxY == 0? 1 : 1 - next.y / maxY);
canvas.drawRect(penX - elWidth/3, penY, penX + elWidth/3, height - offset, outlinePaint);
canvas.drawRect(penX - elWidth/3 + outline, penY + outline, penX + elWidth/3 - outline, height - offset - outline, paint);
//Draw text
Rect bounds = new Rect();
String text = df.format(next.x);
textPaint.getTextBounds(text, 0, text.length(), bounds);
int yPos = height - offset + bounds.height() * 2;
canvas.drawText(text, penX, yPos, textPaint);
i++;
}
DrawAxis(canvas);
lerpData();
}
private void DrawNoData(Canvas canvas) {
DrawAxis(canvas);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTextSize(50);
int xPos = (getWidth() / 2);
int yPos = (int) ((getHeight() / 2) - ((textPaint.descent() + textPaint.ascent()) / 2)) ;
canvas.drawText("Not enough data", xPos, yPos, textPaint);
}
private void DrawAxis(Canvas canvas) {
DecimalFormat df = new DecimalFormat("#0.#");
int nbLines = (int)(maxY / div);
textPaint.setTextAlign(Paint.Align.RIGHT);
if(nbLines>20) {
textPaint.setTextSize(20);
} else {
textPaint.setTextSize(40);
}
for(int i = 0; i < nbLines; i++){
Rect bounds = new Rect();
String text = df.format(maxY - i * div);
textPaint.getTextBounds(text, 0, text.length(), bounds);
int xPos = offset - 20;
int yPos = offset + (getHeight() - 2*offset) * i/nbLines - 5 ; // - bounds.height()
canvas.drawText(text, xPos, yPos, textPaint);
canvas.drawLine(0, offset + (getHeight() - 2*offset) * i/nbLines , getWidth(), offset + (getHeight() - 2*offset) * i/nbLines, gridPaint);
}
//canvas.drawLine(0, 0, getWidth(), 0, gridPaint);
//canvas.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1, gridPaint);
//Draw axis
canvas.drawLine(offset, offset, offset, getHeight() - offset, axisPaint);
canvas.drawLine(offset, getHeight() - offset, getWidth() - offset, getHeight() - offset, axisPaint);
//Draw Y axis arrows
Path path = new Path();
path.moveTo(offset, offset);
path.lineTo(offset + 10, offset);
path.lineTo(offset, offset - 20);;
path.lineTo(offset - 10, offset);
path.lineTo(offset, offset);
path.close();
canvas.drawPath(path, axisPaint);
//Draw X axis arrows
path = new Path();
path.moveTo(getWidth() - offset, getHeight() - offset);
path.lineTo(getWidth() - offset, getHeight() - offset + 10);
path.lineTo(getWidth() - offset + 20, getHeight() - offset);;
path.lineTo(getWidth() - offset, getHeight() - offset - 10);
path.lineTo(getWidth() - offset, getHeight() - offset);
path.close();
canvas.drawPath(path, axisPaint);
}
Код для инициализации
private void init(@Nullable AttributeSet attrs) {
data = new ArrayList<>();
target = new ArrayList<>();
paint = new Paint();
paint.setColor(Color.BLUE);
outlinePaint = new Paint();
outlinePaint.setColor(Color.BLACK);
gridPaint = new Paint();
gridPaint.setColor(Color.LTGRAY);
axisPaint = new Paint();
axisPaint.setColor(Color.DKGRAY);
textPaint = new Paint();
textPaint.setColor(Color.GRAY);
tick = false;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run(){
invalidate();
}
},0,10);
}
Вот видео о том, как это происходит