The lack of SelectedItem in the Droid was identified as a problem last week while preparing for Daniel's talk in Build.
To get around this, there were a few quick answers:
1 There is a SelectedItemPosition that you can use to bind - this is an int
2 You can use the Click ICommand/IMvxCommand instead of using SelectedItem - in your example, it will be the same axml, but
public IMvxCommand ShowItemCommand { get { return new MvxRelayCommand<Address>(address => DoShowContact(address)); } }
To be clear , this Click parameter above is what I will use.
If SelectedItem is really necessary ...
Then for a complete answer, Daniel and I prototyped a new binding. This binding has been reported using:
registry.RegisterFactory(new MvxCustomBindingFactory<MvxBindableListView>("SelectedItem", adapterView => new MvxAdapterViewSelectedItemTargetBinding(adapterView)));
and contained the logic:
using System; using Android.Widget; using Cirrious.MvvmCross.Binding.Droid.Views; using Cirrious.MvvmCross.Binding.Interfaces; using Cirrious.MvvmCross.Interfaces.Platform.Diagnostics; namespace Cirrious.MvvmCross.Binding.Droid.Target { #warning This needs to be redone for all adapterviews not just list view! #warning The use of ItemClick instead of ItemSelected needs to be reinvestigated here! public class MvxAdapterViewSelectedItemTargetBinding : MvxBaseAndroidTargetBinding { private readonly MvxBindableListView _view; private object _currentValue; public MvxAdapterViewSelectedItemTargetBinding(MvxBindableListView view) { _view = view; ((ListView)_view).ItemClick += OnItemClick; } private void OnItemClick(object sender, AdapterView.ItemClickEventArgs itemClickEventArgs) { var container = (_view.GetItemAtPosition(itemClickEventArgs.Position) as MvxJavaContainer); if (container == null) { MvxBindingTrace.Trace(MvxTraceLevel.Warning, "Missing MvxJavaContainer in MvxAdapterViewSelectedItemTargetBinding"); return; } var newValue = container.Object; if (!newValue.Equals(_currentValue)) { _currentValue = newValue; FireValueChanged(newValue); } } public override void SetValue(object value) { #warning Sort out Equals test here if (value != null && value != _currentValue) { var index = _view.Adapter.GetPosition(value); if (index < 0) { MvxBindingTrace.Trace(MvxTraceLevel.Warning, "Value not found for spinner {0}", value.ToString()); return; } _currentValue = value; _view.SetSelection(index); } } public override MvxBindingMode DefaultMode { get { return MvxBindingMode.TwoWay; } } public override Type TargetType { get { return typeof(object); } } protected override void Dispose(bool isDisposing) { if (isDisposing) { ((ListView)_view).ItemClick -= OnItemClick; } base.Dispose(isDisposing); } } }
To test this, I used the Tutorial PullToRefresh code using:
<Mvx.MvxBindableListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" local:MvxBind="{'ItemsSource':{'Path':'Emails'},'ItemClick':{'Path':'ShowItemCommand'},'SelectedItem':{'Path':'TheSelectedEmail'}}" local:MvxItemTemplate="@layout/listitem_email" />
and
public class SimpleEmail { public string From { get; set; } public string Header { get; set; } public string Message { get; set; } } private ObservableCollection<SimpleEmail> _emails; public ObservableCollection<SimpleEmail> Emails { get { return _emails; } private set { _emails = value; RaisePropertyChanged(() => Emails); } } private SimpleEmail _email; public SimpleEmail TheSelectedEmail { get { return _email; } set { _email = value; MvxTrace.Trace(MvxTraceLevel.Error, "HELLO {0} ", value == null ? "null" : value.From); } }
One thing that should be careful in all this work is that the list item selected in Android is slightly different from the selected list item in Silverlight / wp - for example. It can be quite difficult to get the list in android to highlight the current selection, and it can be quite difficult to get listview to generate the highlighted modified events.
Note. I registered the problem in the Droid SelectedItem for https://github.com/slodge/MvvmCross/issues/52 - I will definitely contact the core library in the near future