[Xamarin] GridView 製作兩欄的列表

2016-07-25

最近朋友問我怎麼做兩欄式的ListView ,結果他用 LinearLayout 拼湊出來,千萬不要搞死自己,可以用更好的方法的。

Screenshot_20160725-173511

1.主要參考這一篇 http://no2don.blogspot.com/2013/07/xamarin-listview.html 製作列表的方法
2.把ListView 改成 GridView

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:numColumns="2"
    android:verticalSpacing="2dp"
    android:horizontalSpacing="2dp"
    android:scrollbarStyle="insideOverlay"
    android:verticalScrollbarPosition="right"
    android:scrollbars="vertical" />

幾個重點 numColumns 2 代表兩欄,然後 verticalSpacing 代表兩欄中間的距離,然後horizontalSpacing 代表列與列的距離
3.建立DataAdapter

class ListDataAdapter : BaseAdapter<UserInfo>
   {
       /// <summary>
       /// 所有UserInof 的資料
       /// </summary>
       List<UserInfo> items;
 
       Activity context;
       //暫存圖片下載的任務
       ConcurrentDictionary<string, Task<byte[]>> faceCache = new ConcurrentDictionary<string, Task<byte[]>>();
 
       public ListDataAdapter(Activity context, List<UserInfo> items)
           : base()
       {
           this.context = context;
           this.items = items;
       }
       public override long GetItemId(int position)
       {
           return position;
       }
       public override UserInfo this[int position]
       {
           get { return items[position]; }
       }
       public override int Count
       {
           get { return items.Count; }
       }
 
       /// <summary>
       /// 系統會呼叫 並且render.
       /// </summary>
       /// <param name="position"></param>
       /// <param name="convertView"></param>
       /// <param name="parent"></param>
       /// <returns></returns>
       public override View GetView(int position, View convertView, ViewGroup parent)
       {
           var view = convertView;
           if (view == null)
           {
               //listitem1
               view = context.LayoutInflater.Inflate(Resource.Layout.listitem1, null);
           }
 
           Display display = context.WindowManager.DefaultDisplay;
           Point size = new Point();
           display.GetSize(size);
 
 
           RelativeLayout.LayoutParams parms = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MatchParent, (size.X - 10) / 2); //Width, Height
 
           view.LayoutParameters = parms;
 
           var item = items[position];
 
           var img = view.FindViewById<ImageView>(Resource.Id.img);
           var name = view.FindViewById<TextView>(Resource.Id.textView1);
 
           name.Text = item.Name;
           FetchImage(item.Thumb, view);
           return view;
       }
 
 
       void FetchImage(string url, Android.Views.View view)
       {
           var data = faceCache.GetOrAdd(url, u => Task.Run(() =>
           {
 
               var client = new WebClient();
               try
               {
                   return client.DownloadData(u);
               }
               catch
               {
                   return null;
               }
           }));
 
           if (data.IsCompleted && data.Result != null)
           {
 
               var imgUser = view.FindViewById<ImageView>(Resource.Id.img);
               var bmp = BitmapFactory.DecodeByteArray(data.Result, 0, data.Result.Length);
               bmp = ResizeBitmap(bmp);
               imgUser.SetImageBitmap(bmp);
               //imgUser.SetImageDrawable(new VignetteDrawable(bmp, withEffect: false));
               GC.Collect();
           }
           else
           {
               data.ContinueWith(t =>
               {
                   if (t.Result != null)
                   {
                       var bmp = BitmapFactory.DecodeByteArray(data.Result, 0, data.Result.Length);
                       bmp = ResizeBitmap(bmp);
                       context.RunOnUiThread(() =>
                       {
                           var avatar = view.FindViewById<ImageView>(Resource.Id.img);
                           avatar.SetImageBitmap(bmp);
                       });
                   }
               });
               GC.Collect();
           }
 
       }
       //縮圖
       Bitmap ResizeBitmap(Bitmap inputBitmap)
       {
           var size = (int)TypedValue.ApplyDimension(ComplexUnitType.Px, 500, context.Resources.DisplayMetrics);
           return Bitmap.CreateScaledBitmap(inputBitmap, size, size, true);
       }
 
 
       /// <summary>
       /// 因為圖片是網址,所以將其圖片download回來後轉為bitmap
       /// Get IamgeBitmap form url.
       /// code reference : http://forums.xamarin.com/discussion/4323/image-from-url-in-imageview
       /// </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;
       }
 
   }

其中這一段取得解析度後,讓每一個item 的高度等於寬度

Display display = context.WindowManager.DefaultDisplay;
Point size = new Point();
display.GetSize(size);
 
 
RelativeLayout.LayoutParams parms = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MatchParent, (size.X - 10) / 2); //Width, Height
 
view.LayoutParameters = parms;

結果:
Screenshot_20160725-173511

source code :
https://www.dropbox.com/s/boeisemmfzfgt2u/TwoColumnListView.7z?dl=0

reference :
https://developer.android.com/guide/topics/ui/layout/gridview.html


當麻許的超技八 2014 | Donma Hsu Design.