一、前言

今天用了一下Spinner这个控件,主要是结合官网的例子来用的,不过官网的是把数据写在Strings.xml中的,

某种程度上,不是很符合我们需要的,比较多的应该都是从数据库读出来,绑定上去的。下面是官网的例子:

https://developer.xamarin.com/guides/android/user_interface/spinner/

二、来个简单的Demo

新建一个类 MyType.cs

     public class MyType
{
public int TypeId { get; set; } public string TypeName { get; set; } public override string ToString()
{
return TypeId + "-" + TypeName;
}
}

再来点数据

     public static class DB
{
public static List<MyType> Types { get; private set; } static DB()
{
Types = new List<MyType>();
Types.Add(new MyType { TypeId = , TypeName = "type1" });
Types.Add(new MyType { TypeId = , TypeName = "type2" });
Types.Add(new MyType { TypeId = , TypeName = "type3" });
Types.Add(new MyType { TypeId = , TypeName = "type4" });
}
}

最后写个Adapter,我们自定义的Adapter都需要继承BaseAdapter

     public class MyTypeAdapter : BaseAdapter<MyType>
{
private readonly Activity _context;
private readonly IList<MyType> _types; public MyTypeAdapter(Activity context, IList<MyType> types)
{
this._context = context;
this._types = types;
} public override MyType this[int position]
{
get
{
return this._types[position];
}
} public override int Count
{
get
{
return this._types.Count;
}
} public override long GetItemId(int position)
{
return position;
} public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
{
view = this._context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
} view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = this._types[position].ToString();
return view;
}
}

到这里,会发现有好几个重写的方法!!这些方法是直接通过实现抽象类生成的,然后自己去完善每个方法。

既然都这样了,那就果断去看看这个BaseAdapter是干嘛的

     //
// Summary:
// Common base class of common implementation for an Android.Widget.Adapter that
// can be /// used in both Android.Widget.ListView (by implementing the specialized
// /// Android.Widget.IListAdapter interface} and Android.Widget.Spinner (by implementing
// the /// specialized Android.Widget.ISpinnerAdapter interface.
//
// Type parameters:
// T:
// To be added.
//
// Remarks:
// ///
// Common base class of common implementation for an Android.Widget.Adapter that
// can be /// used in both Android.Widget.ListView (by implementing the specialized
// /// Android.Widget.IListAdapter interface} and Android.Widget.Spinner (by implementing
// the /// specialized Android.Widget.ISpinnerAdapter interface. ///
// ///
// /// /// [Android Documentation] /// ///
// ///
[DefaultMember("Item")]
[Register("android/widget/BaseAdapter", DoNotGenerateAcw = true)]
public abstract class BaseAdapter<T> : BaseAdapter
{
[Register(".ctor", "()V", "")]
public BaseAdapter();
public BaseAdapter(IntPtr handle, JniHandleOwnership transfer); public abstract T this[int position] { get; } public override Java.Lang.Object GetItem(int position);
}

可以看到这个主要就是给ListView和Spinner用的。主要的还是它继承了BaseAdapter这个抽象类(下面的,我是去掉了注释的,方便看)

     public abstract class BaseAdapter : Java.Lang.Object, IListAdapter, ISpinnerAdapter, IAdapter, IJavaObject, IDisposable
{
public BaseAdapter();
protected BaseAdapter(IntPtr javaReference, JniHandleOwnership transfer);
public abstract int Count { get; }
public virtual bool HasStableIds { get; }
public virtual bool IsEmpty { get; }
public virtual int ViewTypeCount { get; }
protected override IntPtr ThresholdClass { get; }
protected override Type ThresholdType { get; }
public virtual bool AreAllItemsEnabled();
public virtual View GetDropDownView(int position, View convertView, ViewGroup parent);
public abstract Java.Lang.Object GetItem(int position);
public abstract long GetItemId(int position);
public virtual int GetItemViewType(int position);
public abstract View GetView(int position, View convertView, ViewGroup parent);
public virtual bool IsEnabled(int position);
public virtual void NotifyDataSetChanged();
public virtual void NotifyDataSetInvalidated();
public virtual void RegisterDataSetObserver(DataSetObserver observer);
public virtual void UnregisterDataSetObserver(DataSetObserver observer); public static class InterfaceConsts
{
public const int IgnoreItemViewType = -;
public const int NoSelection = int.MinValue;
}
}

可以看到,我们在自定义Adapter时,自动实现的方法,有好几个是在这里面的!!!

具体每个方法是干嘛的,就看看API吧!

https://developer.xamarin.com/api/type/Android.Widget.BaseAdapter/

下面来看看我们的Activity:

 [Activity(Label = "SpinnerActivity",MainLauncher =true)]
public class SpinnerActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState); // Create your application here
SetContentView(Resource.Layout.spinnerlayout); var typesSpinner = FindViewById<Spinner>(Resource.Id.typesSpinner); typesSpinner.Adapter = new Models.MyTypeAdapter(this, Models.DB.Types); typesSpinner.ItemSelected += typesSpinner_ItemSelected;
} private void typesSpinner_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner spinner = (Spinner)sender; var toast = string.Format(spinner.GetItemAtPosition(e.Position).ToString()); Toast.MakeText(this, toast, ToastLength.Long).Show();
}
}

很简单,下面看看效果图

Xamarin.Android之Spinner的简单探讨-LMLPHP     Xamarin.Android之Spinner的简单探讨-LMLPHP

但是呢,我记得在原生的开发中,下面这句应该直接是得到一个Object对象,然后通过强制转化就可以得到对应的Model

spinner.GetItemAtPosition(e.Position)

我试过.net下面的强制转化和object获取在转化,都没办法得到想要的效果

Xamarin.Android之Spinner的简单探讨-LMLPHP

都是这个错。

回想刚才的BaseAdapter类,它继承了Java.Lang.Object

所以就直接让我们的MyType去继承这个试试。可以点出来了!!

Xamarin.Android之Spinner的简单探讨-LMLPHP

再来看看选择后的效果图:

Xamarin.Android之Spinner的简单探讨-LMLPHP

OK,达到想要的效果了!!这样我们就可以得到任何我们想要的属性了!!不用只局限一个.ToString()方法了!

下面是MyType类和typesSpinner_ItemSelected方法

      public class MyType : Java.Lang.Object
{
public int TypeId { get; set; } public string TypeName { get; set; } public override string ToString()
{
return TypeId + "-" + TypeName;
}
}
         private void typesSpinner_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner spinner = (Spinner)sender; //var toast = string.Format(spinner.GetItemAtPosition(e.Position).ToString()); var toast = (Models.MyType)spinner.GetItemAtPosition(e.Position); Toast.MakeText(this, toast.TypeName, ToastLength.Long).Show();
}
04-15 06:26
查看更多