0
我想在ImageView
之上實現手繪功能。Android:在ImageView頂部繪製手形
這是我的佈局:
<android.support.constraint.ConstraintLayout
android:id="@+id/constraintLayoutEditImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<RelativeLayout
android:id="@+id/relativeLayoutEditImage"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginRight="0dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
app:layout_constraintBottom_toTopOf="@+id/constraintLayoutEditImageToolbar">
<ImageView
android:id="@+id/imageViewEditImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/light_blue" />
<mobileclient.Droid.HandDrawingCanvasView
android:id="@+id/canvasViewEditImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"/>
</RelativeLayout>
<android.support.constraint.ConstraintLayout
........> //this is the toolbar, etc
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
我遵循了HandDrawingCanvasView
類Multi-Touch Tracking in Android example:
public class HandDrawingCanvasView: View
{
// Two collections for storing polylines
Dictionary<int, HandDrawingPolyline> InProgressPolylines = new Dictionary<int, HandDrawingPolyline>();
List<HandDrawingPolyline> CompletedPolylines = new List<HandDrawingPolyline>();
Paint paint = new Paint(PaintFlags.AntiAlias);
public HandDrawingCanvasView(Context context) : base(context)
{
Initialize();
}
public HandDrawingCanvasView(Context context, IAttributeSet attrs) :
base(context, attrs)
{
Initialize();
}
void Initialize()
{
}
// External interface accessed from MainActivity
public Color StrokeColor { set; get; } = Color.Red;
public float StrokeWidth { set; get; } = 2;
public void ClearAll()
{
CompletedPolylines.Clear();
Invalidate();
}
// Overrides
public override bool OnTouchEvent(MotionEvent args)
{
// Get the pointer index
int pointerIndex = args.ActionIndex;
// Get the id to identify a finger over the course of its progress
int id = args.GetPointerId(pointerIndex);
// Use ActionMasked here rather than Action to reduce the number of possibilities
switch (args.ActionMasked)
{
case MotionEventActions.Down:
case MotionEventActions.PointerDown:
// Create a Polyline, set the initial point, and store it
HandDrawingPolyline polyline = new HandDrawingPolyline
{
Color = StrokeColor,
StrokeWidth = StrokeWidth
};
polyline.Path.MoveTo(args.GetX(pointerIndex),
args.GetY(pointerIndex));
InProgressPolylines.Add(id, polyline);
break;
case MotionEventActions.Move:
// Multiple Move events are bundled, so handle them differently
for (pointerIndex = 0; pointerIndex < args.PointerCount; pointerIndex++)
{
id = args.GetPointerId(pointerIndex);
InProgressPolylines[id].Path.LineTo(args.GetX(pointerIndex),
args.GetY(pointerIndex));
}
break;
case MotionEventActions.Up:
case MotionEventActions.Pointer1Up:
InProgressPolylines[id].Path.LineTo(args.GetX(pointerIndex),
args.GetY(pointerIndex));
// Transfer the in-progress polyline to a completed polyline
CompletedPolylines.Add(InProgressPolylines[id]);
InProgressPolylines.Remove(id);
break;
case MotionEventActions.Cancel:
InProgressPolylines.Remove(id);
break;
}
// Invalidate to update the view
Invalidate();
// Request continued touch input
return true;
}
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
// Clear canvas to white
paint.SetStyle(Paint.Style.Fill);
paint.Color = Color.Transparent;
canvas.DrawPaint(paint);
// Draw strokes
paint.SetStyle(Paint.Style.Stroke);
paint.StrokeCap = Paint.Cap.Round;
paint.StrokeJoin = Paint.Join.Round;
// Draw the completed polylines
foreach (HandDrawingPolyline polyline in CompletedPolylines)
{
paint.Color = polyline.Color;
paint.StrokeWidth = polyline.StrokeWidth;
canvas.DrawPath(polyline.Path, paint);
}
// Draw the in-progress polylines
foreach (HandDrawingPolyline polyline in InProgressPolylines.Values)
{
paint.Color = polyline.Color;
paint.StrokeWidth = polyline.StrokeWidth;
canvas.DrawPath(polyline.Path, paint);
}
}
}
正如你可以看到,我甚至可以在圖像外面畫圖(藍色區域是t他ImageView
背景)。如何限制可繪製區域只在圖片的邊界內?
我已經試過您的解決方案和邊界區域轉移,你可以在這裏看到:https://imgur.com/a/d1IvO 然後,經過二/三次繪製,將有'異常InProgressPolylines.Add(id,polyline);' – currarpickt
啊好的。您已經在視圖的本地座標系中獲取了觸摸事件。我會更新我的答案。我不能評論崩潰,但必須在你的代碼 – cjurjiu
檢查新版本的代碼,應該現在確定。以前的版本也垂直翻譯事件,假設事件在屏幕的座標系中,以匹配圖像視圖的座標系統。但由於你的onTouchEvent是ImageView本身的,所以這個翻譯沒有必要 – cjurjiu