我只是想知道 ExpandableListViews 的功能或类似的功能是否潜伏在 Mvvmmcross 框架中,或者这种类型的控件是否不适用于多平台要求。在 http://deapsquatter.blogspot.com/2013/02/mvvmcrossdeapextensions.html找到的功能很酷,但不确定展开/折叠功能是否可用。
任何指针/示例代码将不胜感激
我只是想知道 ExpandableListViews 的功能或类似的功能是否潜伏在 Mvvmmcross 框架中,或者这种类型的控件是否不适用于多平台要求。在 http://deapsquatter.blogspot.com/2013/02/mvvmcrossdeapextensions.html找到的功能很酷,但不确定展开/折叠功能是否可用。
任何指针/示例代码将不胜感激
这就是它(我把它放在 Deepsqautter 的代码中)。整理完代码后,我会把它放在方便的地方,或者它可能是 mvvmcross 本身的有用补充......
风景:
public class BindableExpandableListView : ExpandableListView
{
public BindableExpandableListView(Context context, IAttributeSet attrs)
: this(context, attrs, new BindableExpandableListAdapter(context))
{
}
public BindableExpandableListView(Context context, IAttributeSet attrs, BindableExpandableListAdapter adapter)
: base(context, attrs)
{
var groupTemplateId = MvxAttributeHelpers.ReadAttributeValue(context, attrs,
MvxAndroidBindingResource.Instance
.ListViewStylableGroupId,
AndroidBindingResource.Instance
.BindableListGroupItemTemplateId);
var itemTemplateId = MvxAttributeHelpers.ReadListItemTemplateId(context, attrs);
SetAdapter(adapter);
adapter.GroupTemplateId = groupTemplateId;
adapter.ItemTemplateId = itemTemplateId;
}
// An expandableListView has ExpandableListAdapter as propertyname, but Adapter still exists but is always null.
protected BindableExpandableListAdapter ThisAdapter { get { return ExpandableListAdapter as BindableExpandableListAdapter; } }
private IEnumerable _itemsSource;
[MvxSetToNullAfterBinding]
public virtual IEnumerable ItemsSource
{
get { return ThisAdapter.ItemsSource; }
set { ThisAdapter.ItemsSource = value; }
}
public int ItemTemplateId
{
get { return ThisAdapter.ItemTemplateId; }
set { ThisAdapter.ItemTemplateId = value; }
}
private ICommand _itemClick;
public new ICommand ItemClick
{
get { return _itemClick; }
set { _itemClick = value; if (_itemClick != null) EnsureItemClickOverloaded(); }
}
public ICommand GroupClick { get; set; }
private bool _itemClickOverloaded = false;
private void EnsureItemClickOverloaded()
{
if (_itemClickOverloaded)
return;
_itemClickOverloaded = true;
base.ChildClick += (sender, args) => ExecuteCommandOnItem(this.ItemClick, args.GroupPosition, args.ChildPosition);
}
protected virtual void ExecuteCommandOnItem(ICommand command, int groupPosition, int position)
{
if (command == null)
return;
var item = ThisAdapter.GetRawItem(groupPosition, position);
if (item == null)
return;
if (!command.CanExecute(item))
return;
command.Execute(item);
}
}
和适配器
public class BindableExpandableListAdapter : MvxAdapter, IExpandableListAdapter
{
private IList _itemsSource;
public BindableExpandableListAdapter(Context context)
: base(context)
{
}
int groupTemplateId;
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();
}
}
protected override void SetItemsSource(System.Collections.IEnumerable value)
{
Mvx.Trace("Setting itemssource");
if (_itemsSource == value)
return;
var existingObservable = _itemsSource as INotifyCollectionChanged;
if (existingObservable != null)
existingObservable.CollectionChanged -= OnItemsSourceCollectionChanged;
_itemsSource = value as IList;
var newObservable = _itemsSource as INotifyCollectionChanged;
if (newObservable != null)
newObservable.CollectionChanged += OnItemsSourceCollectionChanged;
if (value != null)
{
// dit weggehaald FlattenAndSetSource(value);
}
else
base.SetItemsSource(null);
}
public int GroupCount { get { return (_itemsSource != null ? _itemsSource.Count : 0); } }
public void OnGroupExpanded(int groupPosition)
{
// do nothing
}
public void OnGroupCollapsed(int groupPosition)
{
// do nothing
}
public bool IsChildSelectable(int groupPosition, int childPosition)
{
return true;
}
public View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
{
var item = _itemsSource[groupPosition];
return base.GetBindableView(convertView, item, GroupTemplateId);
}
public long GetGroupId(int groupPosition)
{
return groupPosition;
}
public Java.Lang.Object GetGroup(int groupPosition)
{
return null;
}
public long GetCombinedGroupId(long groupId)
{
return groupId;
}
public long GetCombinedChildId(long groupId, long childId)
{
return childId;
}
public object GetRawItem(int groupPosition, int position)
{
return ((_itemsSource[groupPosition]) as IEnumerable).Cast<object>().ToList()[position];
}
public View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
{
var sublist = ((_itemsSource[groupPosition]) as IEnumerable).Cast<object>().ToList();
var item = sublist[childPosition];
return base.GetBindableView(convertView, item, ItemTemplateId);
}
public int GetChildrenCount(int groupPosition)
{
return ((_itemsSource[groupPosition]) as IEnumerable).Cast<object>().ToList().Count();
}
public long GetChildId(int groupPosition, int childPosition)
{
return childPosition;
}
public Java.Lang.Object GetChild(int groupPosition, int childPosition)
{
return null;
}
//public object GetRawItem
}
以及示例 XAML 代码:
<DeapExtensions.Binding.Droid.Views.BindableExpandableListView
android:minWidth="25px"
android:minHeight="25px"
android:id="@+id/toclist"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="ItemsSource Chapters; ItemClick ShowCommand"
local:MvxItemTemplate="@layout/indextocsectionlistitem"
local:GroupItemTemplate="@layout/indextocitem"
android:background="@android:color/white" />
然后甚至是一些数据示例(伪代码):
public class SubItem {
public String Name {get; set;}
}
// this is the special part: a chapter does not CONTAIN a sublist, but IS a list of subitems.
public class Chapter : List<Subitem> {
public String Name {get; set;}
}
// en some usage code
var chapters = new List<Chapter>();
var chapter = new Chapter(){Name = "chap 1"};
chapter.Add(new SubItem(){Name = " 1"});
chapter.Add(new SubItem(){Name = "item 2"});
chapters.Add(chap);
这是我的 MvxBindingAttributes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MvxBinding">
<attr name="MvxBind" format="string"/>
<attr name="MvxLang" format="string"/>
</declare-styleable>
<declare-styleable name="MvxControl">
<attr name="MvxTemplate" format="string"/>
</declare-styleable>
<declare-styleable name="MvxListView">
<attr name="MvxItemTemplate" format="string"/>
<attr name="MvxDropDownItemTemplate" format="string"/>
<attr name="GroupItemTemplate" format="string"/>
</declare-styleable>
<item type="id" name="MvxBindingTagUnique"/>
<declare-styleable name="MvxImageView">
<attr name="MvxSource" format="string"/>
</declare-styleable>
</resources>
BTW:我在 MvvmCross 中只剩下一个项目,其余的已转换为 Xamarin.Forms 甚至远离 Xamarin。所以代码不再更新。
据我所知,以前没有人这样做过
但是您可以相当简单地将现有的 Android 控件转换为绑定控件 - 您已经在 @deapsquatter 的 repo 中看到了它是如何完成的。
要转换 ExpandableListView,我会一步一步来。
当/如果您遇到特定问题时,您可以随时回到这里询问这些问题。但是,首先将 1 和 2 放在适当的位置,那么您将有一些可靠的问题要问。
希望有帮助。