Skip to content

Instantly share code, notes, and snippets.

@deapsquatter
Created January 31, 2013 11:11
Show Gist options
  • Save deapsquatter/4682188 to your computer and use it in GitHub Desktop.
Save deapsquatter/4682188 to your computer and use it in GitHub Desktop.
Show a list with group headers similar to iOS UITableView with Sections. To use bind ItemsSource to an IEnumerable containing items that implement IEnumerable.
using System;
using Cirrious.MvvmCross.Binding.Droid.Views;
using System.Linq;
using Android.Content;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
namespace Cirrious.MvvmCross.Binding.Droid.Views
{
public class MvxBindableGroupListAdaptor : MvxBindableListAdapter
{
int groupTemplateId;
private IEnumerable _itemsSource;
public MvxBindableGroupListAdaptor(Context context): base(context)
{
}
public int GroupTemplateId
{
get { return groupTemplateId; }
set
{
if (groupTemplateId == value)
return;
groupTemplateId = value;
// since the template has changed then let's force the list to redisplay by firing NotifyDataSetChanged()
if (ItemsSource != null)
NotifyDataSetChanged();
}
}
void OnItemsSourceCollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
FlattenAndSetSource(_itemsSource);
}
void FlattenAndSetSource(IEnumerable value)
{
var list = value.Cast<object>();
var flattened = list.SelectMany ((g) => FlattenHierachy (g));
base.SetItemsSource (flattened.ToList ());
}
protected override void SetItemsSource (System.Collections.IEnumerable value)
{
if (_itemsSource == value)
return;
var existingObservable = _itemsSource as INotifyCollectionChanged;
if (existingObservable != null)
existingObservable.CollectionChanged -= OnItemsSourceCollectionChanged;
_itemsSource = value;
var newObservable = _itemsSource as INotifyCollectionChanged;
if (newObservable != null)
newObservable.CollectionChanged += OnItemsSourceCollectionChanged;
if (value != null) {
FlattenAndSetSource(value);
}else
base.SetItemsSource(null);
}
public class FlatItem
{
public bool IsGroup;
public object Item;
}
IEnumerable<Object> FlattenHierachy(object group)
{
yield return new FlatItem {IsGroup = true, Item = group};
IEnumerable items = group as IEnumerable;
if (items != null)
foreach (object d in items)
yield return new FlatItem {IsGroup = false, Item = d};
}
protected override global::Android.Views.View GetBindableView(global::Android.Views.View convertView, object source, int templateId)
{
FlatItem item = (FlatItem)source;
if (item.IsGroup)
return base.GetBindableView(convertView, item.Item, GroupTemplateId);
else
return base.GetBindableView(convertView, item.Item, ItemTemplateId);
}
}
}
using System;
using Android.Content;
using Android.Util;
using System.Collections.Generic;
using System.Windows.Input;
namespace Cirrious.MvvmCross.Binding.Droid.Views
{
public class MvxBindableGroupListView : MvxBindableListView
{
public MvxBindableGroupListView(Context context, IAttributeSet attrs)
: this(context, attrs, new MvxBindableGroupListAdaptor(context))
{
}
public MvxBindableGroupListView(Context context, IAttributeSet attrs, MvxBindableGroupListAdaptor adapter)
: base(context, attrs, adapter)
{
var groupTemplateId = MvxBindableListViewHelpers.ReadAttributeValue(context, attrs,
MvxAndroidBindingResource.Instance
.BindableListViewStylableGroupId,
MvxAndroidBindingResource.Instance
.BindableListGroupItemTemplateId);
adapter.GroupTemplateId = groupTemplateId;
}
protected override void ExecuteCommandOnItem(ICommand command, int position)
{
if (command == null)
return;
var item = Adapter.GetRawItem(position);
if (item == null)
return;
var flatItem = (MvxBindableGroupListAdaptor.FlatItem)item;
if (flatItem.IsGroup || !command.CanExecute(flatItem.Item))
return;
command.Execute(flatItem.Item);
}
}
}
Make this method virtual:
protected virtual void ExecuteCommandOnItem(ICommand command, int position)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MvxBinding">
<attr name="MvxBind" format="string"/>
</declare-styleable>
<declare-styleable name="MvxBindableListView">
<attr name="MvxItemTemplate" format="string"/>
<attr name="MvxDropDownItemTemplate" format="string"/>
<attr name="MvxGroupItemTemplate" format="string"/>
</declare-styleable>
<item type="id" name="MvxBindingTagUnique"/>
<item type="id" name="MvxBindableListItemTagUnique"/>
<declare-styleable name="MvxHttpImageView">
<attr name="MvxHttpSource" format="string"/>
</declare-styleable>
</resources>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment