如何使用MvxListView返回我单击的ListView项?

时间:2016-04-29 05:34:57

标签: android listview xamarin mvvmcross

我有一个正确工作的MvxListView并显示我需要的信息。我甚至让我的ItemClick命令正常工作。我现在无法弄清楚的是如何获取用户点击的视图单元格。我想展开用户点击的视图单元格。以下是我正在使用的代码示例:

视图模型:

    private List<ContactItemEncrypted> _contactsEncryted;
    public List<ContactItemEncrypted> ContactsEncrypted
    {
        get { return _contactsEncryted; }
        set { _contactsEncryted = value; RaisePropertyChanged(() => ContactsEncrypted); }
    }

    private MvxCommand<ContactItemDecrypted> _itemSelectedCommand;
    public System.Windows.Input.ICommand ItemSelectedCommand
    {
        get
        {
            _itemSelectedCommand = _itemSelectedCommand ?? new MvxCommand<ContactItemDecrypted>(DoSelectItem);
            return _itemSelectedCommand;
        }
    }

    private void DoSelectItem(ContactItemDecrypted item)
    {
        var message = new ContactSelectedMessage(this, item);
        _messenger.Publish(message);
    }

查看:

[Activity(
    Label = "Contacts",
    Theme = "@style/AppTheme",
    ScreenOrientation = ScreenOrientation.Portrait
)]
public class ContactsListView : MvxAppCompatActivity
{
    private MvxListView _listView;
    private MvxSubscriptionToken _tokenContactSelected;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.ContactsListScreen);

        _listView = FindViewById<MvxListView>(Resource.Id.contactListView);

        var messenger = Mvx.Resolve<IMvxMessenger>();

        _tokenContactSelected = messenger.SubscribeOnMainThread<ContactSelectedMessage>(ContactSelected);
    }

    private void ContactSelected(ContactSelectedMessage obj)
    {
        ExpandView(_listView.Adapter.GetPosition(obj.SelectedContact));
    }

    private void ExpandView(int index)
    {
        itemLayout.Visibility = ViewStates.Visible;
    }
}

使用列表视图的布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Mvx.MvxListView
    android:id="@+id/contactListView"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    local:MvxBind="ItemsSource ContactsDecrypted; ItemClick ItemSelectedCommand; ItemLongClick ItemLongClickCommand"
    local:MvxItemTemplate="@layout/contactlistviewitemtemplate" />
</FrameLayout>

和ItemTemplate布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:minWidth="25px"
android:minHeight="25px">
<TextView
    android:id="@+id/textViewName"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="18dp"
    android:textColor="@color/black"
    android:layout_margin="14dp"
    custom:MvxBind="Text FullName" />
</LinearLayout>

请记住,我没有写出扩展视图的代码。在我真正拥有可以使用的视图之前,我不想重新开始。

谢谢。

3 个答案:

答案 0 :(得分:1)

您需要在AdapterView.IOnItemClickListener中实施ContactsListView,以便您可以收到点击的项目。

然而,这需要一些自定义,因为实现AdapterView.IOnItemClickListener似乎取消了ICommand的MvvmCross绑定。

查看MvxListView的{​​{3}},我们可以看到用于调用项ICommand的代码:

protected virtual void ExecuteCommandOnItem(ICommand command, int position)
{
    if (command == null)
        return;

    var item = this.Adapter.GetRawItem(position);
    if (item == null)
        return;

    if (!command.CanExecute(item))
        return;

    command.Execute(item);
}

OnItemClick

中实施此功能
public void OnItemClick(AdapterView parent, View view, int position, long id)
{
    MvxListView listView = parent as MvxListView;
    if (listView == null)
        return;

    var item = listView.Adapter.GetRawItem(position);

    if(item == null) 
        return;

    if (!listView.ItemClick.CanExecute(item))
        return;

    listView.ItemClick.Execute(item);

    // Write your code here for expanding the view
}

我不确定这是否可行,但这是实现目标的一种方式。

答案 1 :(得分:0)

ItemClickCommand只会为您提供ViewModel而非View。为了做这样的事情,你需要创建自己的绑定,返回ItemClick上的视图,类似于MvvmCross附带的绑定。或订阅ListView上的ItemClicked事件并处理其中的内容。

前者可能不是最好的主意,因为它根本不会与平台无关,你不得不从View中设置Command,这对我来说似乎有点傻。

所以我猜想在ItemClick / MvxListView上对ListView事件的简单订阅就可以完成返回视图的工作。

另一种方法可以是通过视图单元格的绑定ViewModel的属性切换扩展,这可以使用动画或您喜欢的任何内容切换可见性。

答案 2 :(得分:0)

我尝试了@Pilatus解决方案,似乎还有一些额外的工作。在实现AdapterView.IOnItemClickListener后,我最终使用了OnItemClick方法。我要做的额外事情是设置_listView.OnItemClickListener = this; (这是实现AdapterView.IOnItemClickListener的类)。然后我就可以使用传递给该方法的View并对其进行操作。

此外,作为补充说明,ICommand绑定未被取消。在我的实现中,两个事件都被触发了!

相关问题