[Xamarin] 用ListFragment 製作 List
2016-07-19
之前在 製作過ListActivity (http://no2don.blogspot.tw/2013/07/xamarin-listactivity.html) ,今天我們聊聊使用ListFragment 來製作列表,至於為什麼呢?因為現在官方很多範例都是用ListFragment
1. Layout部分 Main.axml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
這裡面有一個FrameLayout 負責拿來放List的資料,然後每一個item 的Layout itemlayout.axml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="@+id/linearContainer"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip">
<TextView
android:id="@+id/tvId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#CDFFE7"
android:textSize="20dip"
android:textStyle="italic"
android:text="USERID" />
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dip"
android:textColor="#E76DA9"
android:paddingLeft="100dip"
android:text="USERNAME" />
</LinearLayout>
<ImageView
android:id="@+id/imgUser"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="5dp"
android:src="@drawable/Icon"
android:layout_alignParentRight="true" />
</RelativeLayout>
2.建立MainListFragment ,主要繼承 Android.Support.V4.App.ListFragment 如果沒有取得component 記得要去下載
public class MainListFragment : Android.Support.V4.App.ListFragment
{ private List<UserInfo> datas; private DListAdapter adapter; private Activity _Activity;public override void OnCreate(Bundle savedInstanceState)
{ base.OnCreate(savedInstanceState);}
public override void OnAttach(Activity activity)
{ base.OnAttach(activity); //載入假資料 datas = new List<UserInfo>();for (int i = 1; i <= 10; i++)
{datas.Add(new UserInfo { Id = i + "", Name = "當麻許" + i, Thumb = "https://scontent-tpe1-1.xx.fbcdn.net/v/t1.0-1/p160x160/12717553_990702884338448_4996131999379625346_n.jpg?oh=08b10033b3195da4c798a155b6a53c4e&oe=58246A46" });
datas.Add(new UserInfo { Id = i + "", Name = "Donma" + i, Thumb = "https://scontent-tpe1-1.xx.fbcdn.net/v/t1.0-1/c12.12.155.155/577256_189686817873269_571470949_n.jpg?oh=e2885725dfe986899f6426aef31bd65a&oe=58331088" });
datas.Add(new UserInfo { Id = i + "", Name = "Grimm" + i, Thumb = "https://scontent-tpe1-1.xx.fbcdn.net/v/t1.0-1/p160x160/11204432_944409652247471_1055773727056515807_n.jpg?oh=bff2eefe683ae75d5cd01cd1ee3dec68&oe=5824D6C7" });
}
adapter = new DListAdapter(activity); //載入資料adapter.LoadData(datas);
//將ListFragment 的 ListAdapter 配入 //這一行一定要加入ListAdapter = adapter;
}
}
其中 我放入了30筆的假資料這裡面有一個Adapter 這配接器 必須繼承 Android.Widget.BaseAdapter
private class DListAdapter : BaseAdapter<UserInfo>
{List<UserInfo> items;
Activity context;
//暫存圖片下載的任務ConcurrentDictionary<string, Task<byte[]>> faceCache = new ConcurrentDictionary<string, Task<byte[]>>();
public DListAdapter(Activity context) : base() { this.context = context;}
public void LoadData(List<UserInfo> items)
{ this.items = items;NotifyDataSetChanged();
}
public override long GetItemId(int position)
{ return position;}
//取得每一個item 的viewpublic override View GetView(int position, View convertView, ViewGroup parent)
{var view = EnsureView(convertView);
var item = items[position];
var img = view.FindViewById<ImageView>(Resource.Id.imgUser);
var id = view.FindViewById<TextView>(Resource.Id.tvId);
var name = view.FindViewById<TextView>(Resource.Id.tvName);
id.Text = item.Id;
name.Text = item.Name;
FetchImage(item.Thumb, view);
return view;}
public override int Count
{ get { return items.Count; }}
public override UserInfo this[int position]
{ get { return items[position]; }}
//轉換確保為DiscussionViewDiscussionView EnsureView(View convertView)
{ DiscussionView view = convertView as DiscussionView;if (view == null)
view = new DiscussionView(context); return view;}
public override int ViewTypeCount
{get
{ return 1;}
}
void FetchImage(string url, DiscussionView 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.imgUser);
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.imgUser);
avatar.SetImageBitmap(bmp);
});
}
});
GC.Collect();
}
}
//縮圖Bitmap ResizeBitmap(Bitmap inputBitmap)
{ var size = (int)TypedValue.ApplyDimension(ComplexUnitType.Px, 48, context.Resources.DisplayMetrics);return Bitmap.CreateScaledBitmap(inputBitmap, size, size, true);
}
}
3.之後再主要的Activity 部分就可以將 MainListFragment 建立起來
listFragment=new MainListFragment();SupportFragmentManager.BeginTransaction()
.Add(Resource.Id.container, listFragment,"TAG").Commit();source:
https://www.dropbox.com/s/ow1271lxnz9pf7r/TestListFragment.7z?dl=0
reference:
https://developer.xamarin.com/api/type/Android.App.ListFragment/
https://blog.xamarin.com/android-the-swipe-down-to-refresh-pattern/
