Menü Schließen

Creating a Generic Adapter with Empty Value in Android

In Android adapters are used sometimes to provide objects for a spinner.

The following example shows how to extend that mechanism to add a null object. It was written using C# and Xamarin, but there should be no port to convert them to Java.

Object base class:

public class DatabaseObject
{
  public DatabaseObject() {
    this.ID = -1;
  }

  public int ID { get; set; }
}

Generic Adapter:

internal class GenericAdapter<T> : BaseAdapter<T> where T : DatabaseObject
{
  protected Activity context = null;
  protected List<T> list = null;

  public GenericAdapter(Activity context, List<T> list) {
    this.context = context;
    this.list = list;     
  }

#region implemented abstract members of BaseAdapter

  public override long GetItemId(int position) {
    if (list == null)
      return long.MinValue;
    return list[position].ID;
  }

  public override View GetView(int position, View convertView, ViewGroup parent) {
    View view = convertView; // re-use an existing view, if one is available
    if (view == null) // otherwise create a new one
      view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
    view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = list[position].ToString(); // <= Make sure .ToString() returns something!
    return view;
  }

  public override int Count {
    get {
      if (list == null)
        return 0;
      return list.Count;
    }
  }

  public override T this[int index] {
    get {
      if (list == null)
        return null;
      return list[index];
    }
  }

#endregion
}

Model Object Example:

public class Employee : DatabaseObject
{
  public Employee() { }

  public string FirstName { get; set; }

  public string LastName { get; set; }

  public string Name {
    get { 
      string s = LastName;
      if (!string.IsNullOrWhiteSpace(FirstName))
        s += ", " + FirstName;
      return s;
    }
  }

  public override string ToString() {
    return Name;
  }
}

Nullable Generic Adapter:

internal class GenericNullableAdapter<T> : GenericAdapter<T> where T : DatabaseObject
{
  public GenericNullableAdapter(Activity context, List<T> list) : base(context, list) { }

#region implemented abstract members of BaseAdapter

  public override long GetItemId(int position) {
    if (list == null || position == 0)
      return long.MinValue;
    return list[position - 1].ID;
  }

  public override View GetView(int position, View convertView, ViewGroup parent) {
    View view = convertView; // re-use an existing view, if one is available
    if (view == null) // otherwise create a new one
      view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
    if (position == 0)
      view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = "(" + context.GetString(Resource.String.Empty) + ")";
    else
      view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = list[position - 1].ToString();
    return view;
  }

  public override int Count {
    get {
      if (list == null)
        return 0;
      return list.Count + 1;
    }
  }

  public override T this[int index] {
    get {
      if (list == null || index <= 0)
        return null;
      return list[index - 1];
    }
  }

#endregion
}

Using in spinner:

// Setting values
var spinner = FindViewById<Spinner>(Resource.Id.SpinnerEmployee);
var adapter = new GenericNullableAdapter<Employee>(this, employees);
spinner.Adapter = adapter;
if (item.Employee == null)
  spinner.SetSelection(0);
else
  spinner.SetSelection(employees.IndexOf(item.Employee) + 1);


// Getting values
var spinner = FindViewById<Spinner>(Resource.Id.SpinnerEmployee);
item.Employee = (spinner.Adapter as GenericNullableAdapter<Employee>)[spinner.SelectedItemPosition];

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert