パスを含むカスタム ビューをピンチしてズームしようとしています。パスはそれに応じてスケーリングする必要があります。
次のコードは、アプリがクラッシュして表示される臨界点にズームイン レベルが到達するまで正常に動作します。
A/libc: 致命的なシグナル 11 (SIGSEGV)、コード 2、tid 25828 の障害 addr 0xb88799c0 (RenderThread)
また、粉砕する前に次のように表示されます。
W/OpenGLRenderer: パスが大きすぎてテクスチャにレンダリングできません
public class TestView extends View implements ScaleGestureDetector.OnScaleGestureListener {
private String DEBUG_TAG = "TestView";
private ScaleGestureDetector mScaleDetector;
private Path mPath;
private Paint mPaint;
private float mScaleFactor = 1.f;
private float mScaleMax = 2f;
private float mScaleMin = 0.5f;
private Matrix mMatrix;
private boolean mScaling = false;
private PointF mScaleFocus = new PointF();
public TestView(Context context) {
super(context);
setupDrawing();
}
public TestView(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
}
public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupDrawing();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setupDrawing();
}
private void setupDrawing(){
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(0xFF660000);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(10);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mMatrix = new Matrix();
mScaleDetector = new ScaleGestureDetector(getContext(), this);
mPath = new Path();
int width = 100;
int start = 20;
mPath.moveTo(start,start);
mPath.lineTo(start + width, start);
mPath.lineTo(start + width, start + width);
mPath.lineTo(start,start+width);
mPath.close();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
mPath.transform(mMatrix);
canvas.drawPath(mPath, mPaint);
canvas.restore();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mScaleDetector.onTouchEvent(event);
if(mScaling) return true;
if (event.getPointerCount() > 1){
return true;
}
invalidate();
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor = detector.getScaleFactor();
mScaleFactor = Math.max(mScaleMin, Math.min(mScaleFactor, mScaleMax));
mScaleFocus.set(detector.getFocusX(), detector.getFocusY());
Log.d(DEBUG_TAG, "onScale: " + mScaleFactor);
mMatrix.setScale(mScaleFactor, mScaleFactor, mScaleFocus.x, mScaleFocus.y);
invalidate();
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
Log.d(DEBUG_TAG, "onScaleBegin: " + mScaleFactor);
mScaling = true;
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
Log.d(DEBUG_TAG, "onScaleEnd: " + mScaleFactor);
mScaling = false;
}
}
パスをスケーリングする代わりに、キャンバスをスケーリングしてみました。これは問題なく機能しましたが、ズームインするとパス ラインが歪んでしまい、これは望ましくない動作です。