abstract class Sizer extends FrameLayout {
    private static final String TAG = "V";

    private float[] points = new float[8];
    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();
    private TextPaint paint = new TextPaint();
    private Layout layout;
    private int action = MotionEvent.ACTION_UP;

    public Sizer(Context context) {
        super(context);
        addView(getMainView(context));
        paint.setTextSize(context.getResources().getDimensionPixelSize(android.R.dimen.app_icon_size) * 0.6f);
        paint.setColor(Color.LTGRAY);
        paint.setShadowLayer(1, 0, 1, Color.BLACK);
    }

    protected abstract View getMainView(Context context);

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        points[0] = points[4] = w * 0.5f;
        points[1] = points[5] = h * 0.5f;
        layout = new StaticLayout("drag view\nrotate & scale", paint, w, Layout.Alignment.ALIGN_CENTER, 1, 0, false);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            points[2] = event.getX();
            points[3] = event.getY();
            savedMatrix.set(matrix);
        } else {
            points[6] = event.getX();
            points[7] = event.getY();
            if (points[3] < getHeight() / 2) {
                matrix.setTranslate(points[6] - points[2], points[7] - points[3]);
            } else {
                matrix.setPolyToPoly(points, 0, points, 4, 2);
            }
            matrix.preConcat(savedMatrix);
            invalidate();
        }
        return true;
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();
        canvas.concat(matrix);
        super.dispatchDraw(canvas);
        canvas.restore();

        if (action == MotionEvent.ACTION_UP) {
            float dx = paint.getTextSize();
            float y = getHeight() * 0.5f;
            canvas.drawLine(dx, y, getWidth() - dx, y, paint);
            canvas.translate(0, y - layout.getHeight() * 0.5f);
            layout.draw(canvas);
        }
    }
}