如何使图像在Xamarin.Android中可缩放?

如何使图像在Xamarin.Android中可缩放?,xamarin.android,zooming,Xamarin.android,Zooming,我有以下图像: 其尺寸为1920 X 1901像素。以下链接上是其真实尺寸: 我想让它占据工具栏下屏幕的所有空间,但是当我把图像放在屏幕上运行应用程序时,它太大了,当我尝试转到活动时,图像在其中,我得到了一个例外。除了想让图像占据工具栏下方的整个空间外,我还想在我做手势时,分别放大和缩小图像 另外,我在5英寸的设备上运行该应用程序,但我也计划在更大和更小的设备上运行它。在Xamarin Android中,您可以自定义ImageView的事件来实现它 Xml:添加带有示例图像的ImageVie

我有以下图像:

其尺寸为1920 X 1901像素。以下链接上是其真实尺寸:

我想让它占据
工具栏下屏幕的所有空间,但是当我把图像放在屏幕上运行应用程序时,它太大了,当我尝试转到
活动时,图像在其中,我得到了一个例外。除了想让图像占据工具栏下方的整个空间外,我还想在我做手势时,分别放大和缩小图像


另外,我在5英寸的设备上运行该应用程序,但我也计划在更大和更小的设备上运行它。

在Xamarin Android中,您可以自定义ImageView的事件来实现它

Xml:添加带有示例图像的ImageView:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ImageView
        android:id="@+id/main_imgZooming"
        android:background="@color/accent_material_dark"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:scaleType="matrix"
        android:layout_gravity="center"
        android:src="@drawable/imageone"/>

</RelativeLayout>

然后在活动中,您可以自定义触摸事件:

public class MainActivity : AppCompatActivity
{
    private ImageView view;

    private static  int NONE = 0;
    private static  int DRAG = 1;
    private static  int ZOOM = 2;

    private int mode = NONE;
    private float oldDist;
    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();
    private PointF start = new PointF();
    private PointF mid = new PointF();

    float minScaleR = 0.1f;  //Minimum scaling
    static  float MAX_SCALE = 4f; //Maximum zoom ratio
    //float dist = 1f;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.activity_main);

        /*
        view = FindViewById<ImageView>(Resource.Id.main_imgZooming);
        view.Touch += Img_test_Touch;

        matrix.SetScale(minScaleR, minScaleR); //Start zooming out first

        var metrics = Resources.DisplayMetrics;
        int screenWidth = metrics.WidthPixels;

        matrix.PostTranslate(screenWidth / 4, screenWidth / 2);     //The position of the image is offset by screenWidth/2 pixels from the top left corner of the imageview
        view.ImageMatrix = matrix;
        */
    }

    // calculator the distance of two points
    private float distance(MotionEvent eventA)
    {
        float x = eventA.GetX(0) - eventA.GetX(1);
        float y = eventA.GetY(0) - eventA.GetY(1);
        return (float)(System.Math.Sqrt(x * x + y * y));
    }

    // calculator the middle point of two points
    private PointF middle(MotionEvent eventB)
    {
        float x = eventB.GetX(0) + eventB.GetX(1);
        float y = eventB.GetY(0) + eventB.GetY(1);
        return new PointF(x / 2, y / 2);
    }


    private void Img_test_Touch(object sender, Android.Views.View.TouchEventArgs e)
    {
        ImageView view = sender as ImageView;
        switch (e.Event.Action & e.Event.ActionMasked)
        {
            //single finger
            case MotionEventActions.Down:
                //matrix.Set(view.Matrix);
                savedMatrix.Set(matrix);
                start.Set(e.Event.GetX(), e.Event.GetY());
                mode = DRAG;
                Console.WriteLine(mode +"---"+ e.Event.GetX());
            break;

            //double finger
            case MotionEventActions.PointerDown:
                oldDist = distance(e.Event);
                if (oldDist > 10f)
                {
                    savedMatrix.Set(matrix);
                    middle(e.Event);
                    mode = ZOOM;
                }
                Console.WriteLine(mode+"---" + oldDist);
             break;
            //finger up
            case MotionEventActions.Up:
            case MotionEventActions.PointerUp:
                mode = NONE;
                break;
            // finger move
            case MotionEventActions.Move:
                if (mode == DRAG)
                {
                    //single finger
                    matrix.Set(savedMatrix);
                    matrix.PostTranslate(e.Event.GetX() - start.X, e.Event.GetY() - start.Y);
                } else if (mode == ZOOM) {
                    //double finger
                    float newDist = distance(e.Event);
                    if (newDist > 10f) {
                        matrix.Set(savedMatrix);
                        float scale = newDist / oldDist;
                        matrix.PostScale(scale, scale, mid.X, mid.Y);
                    }
            }
            break;
        }

        view.ImageMatrix = matrix;
        CheckScale();  //Limit zoom range
        center();
    }

    //Limit maximum and minimum scaling
    protected void CheckScale()
    {
        float[] p = new float[9];
        matrix.GetValues(p);
        if (mode == ZOOM)
        {
            if (p[0] < minScaleR)
            {
                matrix.SetScale(minScaleR, minScaleR);
            }
            if (p[0] > MAX_SCALE)
            {
                matrix.Set(savedMatrix);
            }
        }
    }


    //Automatic centering
    protected void center()
    {
        center(true, true);
    }

    private void center(bool horizontal, bool vertical)
    {
        Matrix m = new Matrix();
        m.Set(matrix);
        Drawable d = GetDrawable(Resource.Drawable.imageone);
        //Get image width and height
        int imgWidth = d.IntrinsicWidth;
        int imgHeight = d.IntrinsicHeight;


        RectF rect = new RectF(0, 0, imgWidth, imgHeight);
        m.MapRect(rect);
        float height = rect.Height();
        float width = rect.Width();
        float deltaX = 0, deltaY = 0;

        var metrics = Resources.DisplayMetrics;

        if (vertical)
        {

            int screenHeight = metrics.HeightPixels;
            //Phone screen resolution height

            if (height < screenHeight)
            {
                deltaY = (screenHeight - height) / 2 - rect.Top;
            }
            else if (rect.Top > 0)
            {
                deltaY = -rect.Top;
            }
            else if (rect.Bottom < screenHeight)
            {
                deltaY = view.Height - rect.Bottom;
            }
        }

        if (horizontal)
        {
            //Phone screen resolution width
            int screenWidth = metrics.WidthPixels;

            if (width < screenWidth)
            {
                deltaX = (screenWidth - width) / 2 - rect.Left;
            }
            else if (rect.Left > 0)
            {
                deltaX = -rect.Left;
            }
            else if (rect.Right < screenWidth)
            {
                deltaX = screenWidth - rect.Right;
            }
        }
        matrix.PostTranslate(deltaX, deltaY);
    }
}
public类main活动:AppCompatActivity
{
私有图像视图;
私有静态int NONE=0;
私有静态int-DRAG=1;
私有静态int-ZOOM=2;
私有int模式=无;
私人浮动区;
私有矩阵=新矩阵();
私有矩阵savedMatrix=新矩阵();
private PointF start=new PointF();
私有点f mid=新点f();
浮点最小刻度=0.1f;//最小刻度
静态浮点最大刻度=4f;//最大缩放比
//浮动距离=1f;
创建时受保护的覆盖无效(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(这个,savedInstanceState);
//从“主”布局资源设置视图
SetContentView(Resource.Layout.activity_main);
/*
view=findviewbyd(Resource.Id.main\u imgZooming);
view.Touch+=Img\u test\u Touch;
matrix.SetScale(minScaleR,minScaleR);//首先开始缩小
var-metrics=Resources.DisplayMetrics;
int screenWidth=metrics.WidthPixels;
matrix.PostTranslate(screenWidth/4,screenWidth/2);//图像的位置从imageview的左上角偏移screenWidth/2像素
view.ImageMatrix=矩阵;
*/
}
//计算两点之间的距离
专用浮动距离(MotionEvent eventA)
{
float x=eventA.GetX(0)-eventA.GetX(1);
float y=eventA.GetY(0)-eventA.GetY(1);
返回(浮点)(系统数学Sqrt(x*x+y*y));
}
//计算两点的中间点
私有点F中间(运动事件B)
{
float x=eventB.GetX(0)+eventB.GetX(1);
float y=eventB.GetY(0)+eventB.GetY(1);
返回新的点F(x/2,y/2);
}
私有void Img\u test\u Touch(对象发送者,Android.Views.View.TouchEventArgs e)
{
ImageView=发送方作为ImageView;
开关(e.Event.Action和e.Event.ActionMasked)
{
//单指
案例MotionEventActions.Down:
//矩阵集合(视图矩阵);
savedMatrix.Set(矩阵);
Set(e.Event.GetX(),e.Event.GetY());
模式=拖动;
Console.WriteLine(mode+“--”+e.Event.GetX());
打破
//双指
案例MotionEventActions.PointerDown:
oldDist=距离(如事件);
如果(旧区>10f)
{
savedMatrix.Set(矩阵);
中间(如事件);
模式=缩放;
}
Console.WriteLine(模式+“--”+oldDist);
打破
//竖起手指
case MotionEventActions.Up:
case MotionEventActions.PointerUp:
模式=无;
打破
//手指移动
case MotionEventActions。移动:
如果(模式==拖动)
{
//单指
矩阵集(savedMatrix);
PostTranslate(e.Event.GetX()-start.X,e.Event.GetY()-start.Y);
}else if(模式==缩放){
//双指
float newDist=距离(如事件);
如果(新距离>10f){
矩阵集(savedMatrix);
浮动比例=新距离/旧距离;
矩阵。后标度(标度、标度、X中、Y中);
}
}
打破
}
view.ImageMatrix=矩阵;
CheckScale();//限制缩放范围
中心();
}
//限制最大和最小缩放
受保护的void CheckScale()
{
浮动[]p=新浮动[9];
矩阵。GetValues(p);
如果(模式==缩放)
{
if(p[0]最大刻度)
{
矩阵集(savedMatrix);
}
}
}
//自动定心
受保护的空中心()
{
中心(真,真);
}
专用空隙中心(水平方向,垂直方向)
{
矩阵m=新矩阵();
m、 集合(矩阵);
Drawable d=GetDrawable(Resource.Drawable.imageone);
//获取图像宽度和高度
int imgWidth=d.IntrinsicWidth;
intimgheight=d.IntrinsicHeight;
RectF rect=新的RectF(0,0,imgWidth,imgHeight);
m、 MapRect(rect);
浮动高度=矩形高度();
浮动宽度=矩形宽度();
浮动deltaX=0,deltaY=0;
var-metrics=Resources.DisplayMetrics;
如果(垂直)
{
int屏幕高度=metrics.HeightPixels;
//手机屏幕分辨率高度
如果(高度<屏幕高度)
{
三角洲=(