Помогите решить мою проблему, пожалуйста. Поиск в Google не дает результатов.
У меня есть собственный SurfaceView, на холсте которого через отдельный поток я рисую различные формы и текст. Этот SurfaceView обернут в пользовательский FrameLayout, который реализует масштабирование пинч для ребенка. Так что при зуме качество рисунков теряется, хотя, если вы используете обычный вид с холстом, все в порядке. TextureView имеет ту же проблему. Я бы хотел использовать обычный вид, но мне нужно постоянно перерисовывать холст.
У кого-нибудь есть мысли?
Например, я рисую сетку с числами:
PixelGridSurfaceView
public class PixelGridSurfaceView extends SurfaceView
implements SurfaceHolder.Callback {
private DrawThread drawThreadSV;
private float pixelRadius = 0;
private int numColumns = 90, numRows = 90;
public PixelGridSurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
}
public PixelGridSurfaceView (Context context, AttributeSet attributeSet) {
super(context, attributeSet);
getHolder().addCallback(this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Add padding to maximum width calculation.
final int desiredWidth = Math.round(getPaddingLeft() + getPaddingRight());
final int desiredHeight = Math.round(getPaddingTop() +
getPaddingBottom());
// Reconcile size that this view wants to be with the size the parent will let it be.
final int measuredWidth = reconcileSize(desiredWidth, widthMeasureSpec);
final int measuredHeight = reconcileSize(desiredHeight, heightMeasureSpec);
// calculate best pixel size
float cellWidth = (float) measuredWidth / numColumns;
float cellHeight = (float) measuredHeight / numRows;
pixelRadius = cellHeight < cellWidth ? cellHeight : cellWidth;
pixelRadius = (float) Math.floor(pixelRadius);
// Store the final measured dimensions.
setMeasuredDimension((int) pixelRadius * numColumns, measuredHeight);
}
private int reconcileSize(int contentSize, int measureSpec) {
final int mode = MeasureSpec.getMode(measureSpec);
final int specSize = MeasureSpec.getSize(measureSpec);
switch (mode) {
case MeasureSpec.EXACTLY:
return specSize;
case MeasureSpec.AT_MOST:
if (contentSize < specSize) {
return contentSize;
} else {
return specSize;
}
case MeasureSpec.UNSPECIFIED:
default:
return contentSize;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
drawThreadSV = new DrawThread(new SurfaceViewHolder(getHolder()));
drawThreadSV.setPixelRadius(getContext(), pixelRadius);
drawThreadSV.setNumRowsColumns(numColumns, numRows);
drawThreadSV.setRunning(true);
drawThreadSV.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
drawThreadSV.setRunning(false);
while(retry) {
try {
drawThreadSV.join();
retry = false;
}
catch (InterruptedException e) {
}
}
}
}
DrawThread
public class DrawThread extends Thread {
private boolean running = false;
private ISurfaceHolder surfaceHolder;
private int numColumns, numRows;
private Paint linePaint, cellsPaint;
private TextPaint fontPaint;
private float pixelRadius = 0;
private float baselineX, baselineY;
private String number = "4";
DrawThread(ISurfaceHolder surfaceHolder) {
this.surfaceHolder = surfaceHolder;
linePaint = new Paint();
cellsPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
fontPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
linePaint.setColor(Color.BLACK);
cellsPaint.setColor(Color.WHITE);
linePaint.setStyle(Paint.Style.STROKE);
}
void setPixelRadius(Context context, float pixelRadius) {
this.pixelRadius = pixelRadius;
fontPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, pixelRadius / 2.5f, context.getResources().getDisplayMetrics()));
}
void setNumRowsColumns(int numColumns, int numRows) {
this.numColumns = numColumns;
this.numRows = numRows;
}
void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
Canvas canvas;
while (running) {
canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
if (canvas == null)
continue;
drawPath(canvas);
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
private void drawPath(Canvas canvas) {
canvas.drawColor(Color.WHITE);
for (int i = 0; i < numColumns; i++) {
for (int j = 0; j < numRows; j++) {
drawPixel(canvas, cellsPaint, i, j);
}
}
for (int i = 0; i < numColumns; i++) {
for (int j = 0; j < numRows; j++) {
numberSizeAndPosition(i, j);
drawPixel(canvas, linePaint, i, j);
canvas.drawText(number, baselineX, baselineY, fontPaint);
}
}
}
private void drawPixel(Canvas canvas, Paint paint, int i, int j) {
canvas.drawRect(i * pixelRadius, j * pixelRadius,
(i + 1) * pixelRadius, (j + 1) * pixelRadius,
paint);
}
private void numberSizeAndPosition(int i, int j) {
float centerX = (i * pixelRadius) + pixelRadius / 2.0f;
float centerY = (j * pixelRadius) + pixelRadius / 2.0f;
Rect bounds = new Rect();
fontPaint.getTextBounds(number, 0, number.length(), bounds);
float textWidth = bounds.width();
float textHeight = bounds.height();
baselineY = centerY + textHeight * 0.5f;
baselineX = centerX - textWidth * 0.5f;
}
}
coloring.xml
...
<ZoomLayout
android:id="@+id/zoomLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:scrollbars="vertical|horizontal"
android:background="@color/colorWhite"
app:hasClickableChildren="true"
app:horizontalPanEnabled="true"
app:maxZoom="9.0"
app:maxZoomType="zoom"
app:minZoom="1.0"
app:minZoomType="zoom"
app:overPinchable="false"
app:overScrollHorizontal="false"
app:overScrollVertical="false"
app:verticalPanEnabled="true"
app:zoomEnabled="true">
<PixelGridSurfaceView
android:id="@+id/gridSurfaceView"
android:layout_width="1000dp"
android:layout_height="1000dp"
android:layout_centerInParent="true"/>
</ZoomLayout>
...
С увеличением, низкое качество