I ported an Android class to Xamarin. This class is for zooming in and dragging different imageViews. The only problem is that i can't create a relativelayout to position the imageviews with android:layout_toLeftOf etc. (The images appear on top of eachother when i don't use a relativelayout)
When i create a relativelayout, put the imageviews in it (with addview) and add the relativelayout itself with addView, the first image is missing, even in the beginning. I also tried creating the relativelayout and imageviews in xml but this doesn't work either...
public class TouchContainer: FrameLayout, View.IOnTouchListener
{
private static Bitmap.Config DEFAULT_COLOR_DEPTH = Bitmap.Config.Argb8888;
private static String TAG = "TouchContainer";
private List<ImageView> items;
public TouchContainer(Context ctx, IAttributeSet attrs): base(ctx,attrs)
{
Console.WriteLine("init touchcontainer");
InitializeViews(); // initialize some sample Bitmaps
}
protected void InitializeViews()
{
ImageView.ScaleType scaleType = ImageView.ScaleType.Matrix;
items = new List<ImageView>();
ImageView iv = new ImageView (Context);
iv.SetImageDrawable (Resources.GetDrawable (Resource.Drawable.parkZoomOut3));
iv.SetScaleType (scaleType);
iv.SetOnTouchListener (this);
items.Add(iv);
iv.Id=7654;
ImageView iv2 = new ImageView (Context);
RelativeLayout.LayoutParams lparams = new RelativeLayout.LayoutParams(
LayoutParams.WrapContent, LayoutParams.WrapContent);
lparams.AddRule(LayoutRules.RightOf, iv.Id);
//ImageView iv2=GetChildAt(0).FindViewById<ImageView> (Resource.Id.ivRight);
iv2.SetImageDrawable (Resources.GetDrawable (Resource.Drawable.logo_home));
iv2.SetScaleType (scaleType);
iv2.SetOnTouchListener (this);
items.Add(iv2);
AddView (iv);
AddView (iv2);
matrix.PostScale(0.5f, 0.5f, 550, 400);
transformImages(matrix);
}
protected void transformImages(Matrix matrix)
{
foreach (ImageView image in items)
{
image.ImageMatrix=matrix;
}
}
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
// states
static int NONE = 0;
static int DRAG = 1;
static int ZOOM = 2;
int mode = NONE;
static int CLICK = 3;
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
public bool OnTouch(View v, MotionEvent e)
{
Console.WriteLine ("touched");
switch (e.Action) {
case MotionEventActions.Down:
Console.WriteLine ("down");
savedMatrix.Set(matrix);
start.Set(e.GetX(), e.GetY());
mode = DRAG;
break;
case MotionEventActions.Pointer2Down:
Console.WriteLine ("pointer2down");
oldDist = spacing(e);
if (oldDist > 10f)
{
savedMatrix.Set(matrix);
midPoint(mid, e);
mode = ZOOM;
}
break;
case MotionEventActions.Up:
Console.WriteLine ("up");
// figure out if user clicked
mode = NONE;
int xDiff = (int) Math.Abs(e.GetX() - start.X);
int yDiff = (int) Math.Abs(e.GetY() - start.Y);
if (xDiff < CLICK && yDiff < CLICK)
PerformClick();
break;
case MotionEventActions.Pointer2Up:
Console.WriteLine ("pointer2up");
mode = NONE;
break;
case MotionEventActions.Move:
Console.WriteLine ("move");
if (mode == DRAG) {
Console.WriteLine ("drag");
matrix.Set(savedMatrix);
matrix.PostTranslate(e.GetX() - start.X,
e.GetY() - start.Y);
}
else if (mode == ZOOM) {
Console.WriteLine ("zoom");
float newDist = spacing(e);
if (newDist > 10f) {
matrix.Set(savedMatrix);
float scale = newDist / oldDist;
matrix.PostScale(scale, scale, mid.X, mid.Y);
}
}
break;
}
transformImages(matrix);
return true;
}
private float spacing(MotionEvent e)
{
float x = e.GetX(0) - e.GetX(1);
float y = e.GetY(0) - e.GetY(1);
return FloatMath.Sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent e)
{
float x = e.GetX(0) + e.GetX(1);
float y = e.GetY(0) + e.GetY(1);
point.Set(x / 2, y / 2);
}
}