• xamarin C# 安卓实现 ListView 放大缩小


    翻译自java示例https://raw.githubusercontent.com/Xjasz/AndroidZoomableViewGroup/master/ZoomListView.java

    using Android.App;
    using Android.Widget;
    using Android.OS;
    using Android.Views;
    using System.Collections.Generic;
    using Android.Net;
    using Android.Graphics;
    using System.Net;
    using Android.Content;
    using Android.Util;
    using Java.Lang;
    
    namespace App1
    {
        [Activity(Label = "App1", MainLauncher = true, Icon = "@drawable/icon")]
        public class MainActivity : Activity
        {
            protected override void OnCreate(Bundle bundle)
            {
                base.OnCreate(bundle);
    
                // Set our view from the "main" layout resource
                SetContentView (Resource.Layout.Main);
    
                var listView1 = FindViewById<ListView>(Resource.Id.listView1);
                var rows = new List<RowItem>();
                rows.Add(new RowItem { URL = "http://192.168.0.50:8001/OMS/tempimage/c152fd1f-ef44-42a6-96fb-3b4894ab8004636499813730162442.gif" });
                rows.Add(new RowItem { URL = "http://192.168.0.50:8001/OMS/tempimage/9e8a1d81-7211-4c1f-bc5c-b7193c12a92c636499813730162442.gif" });
                rows.Add(new RowItem { URL = "http://192.168.0.50:8001/OMS/tempimage/6f0eca83-7b5e-4e9e-999c-3ef88e277117636499813730162442.gif" });
                listView1.Adapter = new ListViewRowAdapter(this, rows);
            }
        }
    
        public class MyListView : ListView
        {
            private MyListViewParameter ParameterInfo = new MyListViewParameter();
            private ScaleGestureDetector ScaleDetector { get; set; }
    
            public MyListView(Context context)
                :base(context)
            {
                this.ScaleDetector = new ScaleGestureDetector(context, new ScaleListener(ParameterInfo, this));
            }
            public MyListView(Context context, IAttributeSet attrs)
                :base(context,attrs)
            {
                this.ScaleDetector = new ScaleGestureDetector(context, new ScaleListener(ParameterInfo, this));
            }
            public MyListView(Context context, IAttributeSet attrs, int defStyleAttr)
                :base(context,attrs,defStyleAttr)
            {
                this.ScaleDetector = new ScaleGestureDetector(context, new ScaleListener(ParameterInfo, this));
            }
            public MyListView(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes)
                :base(context,attrs,defStyleAttr,defStyleRes)
            {
                this.ScaleDetector = new ScaleGestureDetector(context, new ScaleListener(ParameterInfo, this));
            }
    
            protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
            {
                this.ParameterInfo.Width = MeasureSpec.GetSize(widthMeasureSpec);
                this.ParameterInfo.Height = MeasureSpec.GetSize(heightMeasureSpec);
                base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
            }
    
            public override bool OnTouchEvent(MotionEvent ev)
            {
                var result = base.OnTouchEvent(ev);
                var action = ev.Action;
                this.ScaleDetector.OnTouchEvent(ev);
                switch (action)
                {
                    case MotionEventActions.Down:
                        {
                            float x = ev.GetX();
                            float y = ev.GetY();
    
    
                            this.ParameterInfo.LastTouchX = x;
                            this.ParameterInfo.LastTouchY = y;
    
    
                            this.ParameterInfo.ActivePointerId = ev.GetPointerId(0);
                            break;
                        }
    
    
                    case MotionEventActions.Move:
                        {
                            int pointerIndex = ev.FindPointerIndex(this.ParameterInfo.ActivePointerId);
                            float x = ev.GetX(pointerIndex);
                            float y = ev.GetY(pointerIndex);
                            float dx = x - this.ParameterInfo.LastTouchX;
                            float dy = y - this.ParameterInfo.LastTouchY;
    
    
                            this.ParameterInfo.PosX += dx;
                            this.ParameterInfo.PosY += dy;
    
                            if (this.ParameterInfo.PosX > 0.0f)
                                this.ParameterInfo.PosX = 0.0f;
                            else if (this.ParameterInfo.PosX < this.ParameterInfo.MaxWidth)
                                this.ParameterInfo.PosX = this.ParameterInfo.MaxWidth;
    
                            if (this.ParameterInfo.PosY > 0.0f)
                                this.ParameterInfo.PosY = 0.0f;
                            else if (this.ParameterInfo.PosY < this.ParameterInfo.MaxHeight)
                                this.ParameterInfo.PosY = this.ParameterInfo.MaxHeight;
    
                            this.ParameterInfo.LastTouchX = x;
                            this.ParameterInfo.LastTouchY = y;
                            
                            this.Invalidate();
                            break;
                        }
    
    
                    case MotionEventActions.Up:
                        {
                            this.ParameterInfo.ActivePointerId = this.ParameterInfo.INVALID_POINTER_ID;
                            break;
                        }
    
    
                    case MotionEventActions.Cancel:
                        {
                            this.ParameterInfo.ActivePointerId = this.ParameterInfo.INVALID_POINTER_ID;
                            break;
                        }
    
    
                    case MotionEventActions.PointerUp:
                        {
                            int pointerIndex = ((int)action & (int)MotionEventActions.PointerIndexMask) >> (int)MotionEventActions.PointerIndexShift;
                            int pointerId = ev.GetPointerId(pointerIndex);
                            if (pointerId == this.ParameterInfo.ActivePointerId)
                            {
                                int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                                this.ParameterInfo.LastTouchX = ev.GetX(newPointerIndex);
                                this.ParameterInfo.LastTouchY = ev.GetY(newPointerIndex);
                                this.ParameterInfo.ActivePointerId = ev.GetPointerId(newPointerIndex);
                            }
                            break;
                        }
                }
    
                return true;
            }
    
            protected override void OnDraw(Canvas canvas)
            {
                base.OnDraw(canvas);
                canvas.Save(SaveFlags.Matrix);
                canvas.Translate(this.ParameterInfo.PosX, this.ParameterInfo.PosY);
                canvas.Scale(this.ParameterInfo.ScaleFactor, this.ParameterInfo.ScaleFactor);
                canvas.Restore();
    
            }
    
            protected override void DispatchDraw(Canvas canvas)
            {
                canvas.Save(SaveFlags.Matrix);
                if (this.ParameterInfo.ScaleFactor == 1.0f)
                {
                    this.ParameterInfo.PosX = 0.0f;
                    this.ParameterInfo.PosY = 0.0f;
                }
                canvas.Translate(this.ParameterInfo.PosX, this.ParameterInfo.PosY);
                canvas.Scale(this.ParameterInfo.ScaleFactor, this.ParameterInfo.ScaleFactor);
                base.DispatchDraw(canvas);
                canvas.Restore();
                this.Invalidate();
            }
    
            public class MyListViewParameter
            {
                public MyListViewParameter()
                {
                    this.INVALID_POINTER_ID = -1;
                    this.ActivePointerId = -1;
                    this.ScaleFactor = 1.0f;
                    this.MaxWidth = 0.0f;
                    this.MaxHeight = 0.0f;
                }
    
                public int INVALID_POINTER_ID { get; private set; }
                public int ActivePointerId { get; set; }
                public float ScaleFactor { get; set; }
                public float MaxWidth { get; set; }
                public float MaxHeight { get; set; }
                public float LastTouchX { get; set; }
                public float LastTouchY { get; set; }
                public float PosX { get; set; }
                public float PosY { get; set; }
                public float Width { get; set; }
                public float Height { get; set; }
            }
    
            private class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener
            {
                private MyListViewParameter ParameterInfo { get; set; }
                private ListView MyListView { get; set; }
    
                public ScaleListener(MyListViewParameter pi,ListView lv)
                {
                    this.ParameterInfo = pi;
                    this.MyListView = lv;
                }
    
                public override bool OnScale(ScaleGestureDetector detector)
                {
                    this.ParameterInfo.ScaleFactor *= detector.ScaleFactor;
                    this.ParameterInfo.ScaleFactor = Math.Max(1.0f, Math.Min(this.ParameterInfo.ScaleFactor, 3.0f));
                    this.ParameterInfo.MaxWidth = this.ParameterInfo.Width - (this.ParameterInfo.Width * this.ParameterInfo.ScaleFactor);
                    this.ParameterInfo.MaxHeight = this.ParameterInfo.Height - (this.ParameterInfo.Height * this.ParameterInfo.ScaleFactor);
                    this.MyListView.Invalidate();
                    return true;
                }
            }
        }
    
        
    
        public class RowItem
        {
            public string URL { get; set; }
        }
    
        public class ListViewRowAdapter : BaseAdapter<RowItem>
        {
            List<RowItem> items;
            Activity context;
            public ListViewRowAdapter(Activity context, List<RowItem> items)
                : base()
            {
                this.context = context;
                this.items = items;
            }
            public override long GetItemId(int position)
            {
                return position;
            }
            public override RowItem this[int position]
            {
                get { return items[position]; }
            }
            public override int Count
            {
                get { return items.Count; }
            }
    
            /// <summary>
            /// 下载图片
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            private Bitmap GetImageBitmapFromUrl(string url)
            {
                Bitmap imageBitmap = null;
    
                using (var webClient = new WebClient())
                {
                    var imageBytes = webClient.DownloadData(url);
                    if (imageBytes != null && imageBytes.Length > 0)
                    {
                        imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
                    }
                }
    
                return imageBitmap;
            }
            public override View GetView(int position, View convertView, ViewGroup parent)
            {
                var item = items[position];
                View view = convertView;
                if (view == null) // no view to re-use, create new
                    view = context.LayoutInflater.Inflate(Resource.Layout.ListViewRow, null);
                var url = Uri.Parse(item.URL);
                view.FindViewById<ImageView>(Resource.Id.Image1).SetImageBitmap(GetImageBitmapFromUrl(item.URL));
                return view;
            }
        }
    }
  • 相关阅读:
    安卓权威编程指南-笔记(第24章 Looper Handler 和 HandlerThread)
    AndroidImageSlider
    ToolBar的使用
    安卓权威编程指南-笔记(第26章 服务的作用)
    关于两个update语句互相死锁的显现,加深我们对锁的了解 转载
    js 原型和构造方法 转载
    关于distinct 和group by的去重逻辑浅析
    tab 下一个
    当前浏览器版本
    清除li间隔
  • 原文地址:https://www.cnblogs.com/nanfei/p/8269714.html
Copyright © 2020-2023  润新知