Je veux mettre en œuvre la fonction de dessin à la main sur un ImageView
.Android: dessin à la main sur le dessus d'ImageView
C'est ma mise en page:
<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>
Je suis Multi-Touch Tracking in Android example pour la classe HandDrawingCanvasView
:
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);
}
}
}
Comme vous pouvez le voir, Je pourrais dessiner même en dehors de l'image (la zone bleue est t il ImageView
arrière-plan). Comment limiter la zone dessinable à seulement dans les limites de l'image?
J'ai essayé votre solution et la zone des limites est décalée comme vous pouvez le voir ici: https://imgur.com/a/d1IvO puis, après deux/trois fois de dessin, il y aura une exception dans ' InProgressPolylines.Add (id, polyline); ' – currarpickt
ah ok. vous obtenez déjà les événements tactiles dans le système de coordonnées local de la vue. Je mettrai à jour ma réponse. Je ne peux pas commenter sur le crash cependant, cela doit être quelque part dans votre code – cjurjiu
vérifier la nouvelle version du code, devrait être ok maintenant. la version précédente traduisait également les événements verticalement, en supposant que les événements se trouvaient dans le système de coordonnées de l'écran, afin de correspondre au système de coordonnées de la vue d'image. mais puisque votre onTouchEvent est de l'ImageView lui-même, cette traduction n'était pas nécessaire – cjurjiu