每行带有按钮的 MvxRecyclerView
MvxRecyclerView with button in each row
我正在使用 Xamarin.Android 和 MvvmCross 制作一个 Android 应用程序。我有一个 MvxRecyclerView
:
<MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
local:MvxItemTemplate="@layout/auto_complete_search_item"
local:MvxBind="ItemsSource SearchAutoCompleteItems; ItemClick SearchAutoCompleteItemClick" />
还有我的auto_complete_search_item.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/auto_complete_search_item_height"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_large"
local:MvxBind="Text Title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_large"
local:MvxBind="Text Category" />
</LinearLayout>
<TextView
android:id="@+id/fill_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="@dimen/text_medium"
android:textColor="@color/black"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
local:MvxLang="Text fa-arrow-up"
local:MvxBind="Style ., Converter=String, ConverterParameter=fonts/fontawesome.ttf" />
</LinearLayout>
我的点击处理程序 ItemClick SearchAutoCompleteItemClick
可以工作,但我需要单独处理用户点击我的 fill_button
时的点击事件。我怎样才能做到这一点?
您可以向 TextView
添加第二个绑定。这会将 Click
事件绑定到您将在 SearchAutoCompleteItem
类型中定义的命令(该命令将在单个项目的级别上声明)。
local:MvxBind="Click FillCommand; Style ., Converter=String, ConverterParameter=fonts/fontawesome.ttf"
我想出了如何使用自定义 MvxRecyclerView
和自定义 MvxRecyclerAdapter
:
public class TwoPieceMvxRecyclerView : MvxRecyclerView
{
private ICommand _itemClickPiece1;
private ICommand _itemClickPiece2;
public ICommand ItemClickPiece1
{
get { return _itemClickPiece1; }
set
{
if (ReferenceEquals(_itemClickPiece1, value))
{
return;
}
_itemClickPiece1 = value;
}
}
public ICommand ItemClickPiece2
{
get { return _itemClickPiece2; }
set
{
if (ReferenceEquals(_itemClickPiece2, value))
{
return;
}
_itemClickPiece2 = value;
}
}
public TwoPieceMvxRecyclerView(Context context, IAttributeSet attr) : base(context, attr)
{
}
public TwoPieceMvxRecyclerView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
}
public class TwoPieceMvxRecyclerAdapter : MvxRecyclerAdapter, IOnClickListener
{
public TwoPieceMvxRecyclerAdapter(IMvxAndroidBindingContext context) : base(context)
{
}
public TwoPieceMvxRecyclerView TwoPieceMvxRecyclerView { get; set; }
protected override Android.Views.View InflateViewForHolder(Android.Views.ViewGroup parent, int viewType, MvvmCross.Binding.Droid.BindingContext.IMvxAndroidBindingContext bindingContext)
{
var view = base.InflateViewForHolder(parent, viewType, bindingContext);
var clickablePiece1 = view.FindViewById<View>(Resource.Id.clickable_piece1);
var clickablePiece2 = view.FindViewById<View>(Resource.Id.clickable_piece2);
clickablePiece1.SetOnClickListener(this);
clickablePiece2.SetOnClickListener(this);
return view;
}
public void OnClick(View v)
{
var viewHolder = this.TwoPieceMvxRecyclerView.FindContainingViewHolder(v);
var item = GetItem(viewHolder.LayoutPosition); // What different is viewHolder.AdapterPosition? I tested it with 100 items and it's always the same, but I'm not sure if this will never break...
if (v.Id == Resource.Id.clickable_piece1)
{
TwoPieceMvxRecyclerView.ItemClickPiece1.Execute(item);
}
else if (v.Id == Resource.Id.clickable_piece2)
{
TwoPieceMvxRecyclerView.ItemClickPiece2.Execute(item);
}
}
}
然后在包含 activity(或片段)中:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_search);
var r = FindViewById<TwoPieceMvxRecyclerView>(Resource.Id.my_twopiecemvxrecyclerview);
var adapter = new TwoPieceMvxRecyclerAdapter(((IMvxAndroidBindingContext)BindingContext));
adapter.TwoPieceMvxRecyclerView = r;
r.Adapter = adapter;
}
并像这样使用它:
<My.Namespace.TwoPieceMvxRecyclerView
android:id="@+id/my_twopiecemvxrecyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
local:MvxItemTemplate="@layout/my_two_piece_layout"
local:MvxBind="ItemsSource MyItems; ItemClickPiece1 MyItemClick1; ItemClickPiece2 MyItemClick2" />
my_two_piece_layout.xml
需要具有 ID 为 clickable_piece1
和 clickable_piece2
的视图
我正在使用 Xamarin.Android 和 MvvmCross 制作一个 Android 应用程序。我有一个 MvxRecyclerView
:
<MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
local:MvxItemTemplate="@layout/auto_complete_search_item"
local:MvxBind="ItemsSource SearchAutoCompleteItems; ItemClick SearchAutoCompleteItemClick" />
还有我的auto_complete_search_item.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/auto_complete_search_item_height"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_large"
local:MvxBind="Text Title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_large"
local:MvxBind="Text Category" />
</LinearLayout>
<TextView
android:id="@+id/fill_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="@dimen/text_medium"
android:textColor="@color/black"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
local:MvxLang="Text fa-arrow-up"
local:MvxBind="Style ., Converter=String, ConverterParameter=fonts/fontawesome.ttf" />
</LinearLayout>
我的点击处理程序 ItemClick SearchAutoCompleteItemClick
可以工作,但我需要单独处理用户点击我的 fill_button
时的点击事件。我怎样才能做到这一点?
您可以向 TextView
添加第二个绑定。这会将 Click
事件绑定到您将在 SearchAutoCompleteItem
类型中定义的命令(该命令将在单个项目的级别上声明)。
local:MvxBind="Click FillCommand; Style ., Converter=String, ConverterParameter=fonts/fontawesome.ttf"
我想出了如何使用自定义 MvxRecyclerView
和自定义 MvxRecyclerAdapter
:
public class TwoPieceMvxRecyclerView : MvxRecyclerView
{
private ICommand _itemClickPiece1;
private ICommand _itemClickPiece2;
public ICommand ItemClickPiece1
{
get { return _itemClickPiece1; }
set
{
if (ReferenceEquals(_itemClickPiece1, value))
{
return;
}
_itemClickPiece1 = value;
}
}
public ICommand ItemClickPiece2
{
get { return _itemClickPiece2; }
set
{
if (ReferenceEquals(_itemClickPiece2, value))
{
return;
}
_itemClickPiece2 = value;
}
}
public TwoPieceMvxRecyclerView(Context context, IAttributeSet attr) : base(context, attr)
{
}
public TwoPieceMvxRecyclerView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
}
public class TwoPieceMvxRecyclerAdapter : MvxRecyclerAdapter, IOnClickListener
{
public TwoPieceMvxRecyclerAdapter(IMvxAndroidBindingContext context) : base(context)
{
}
public TwoPieceMvxRecyclerView TwoPieceMvxRecyclerView { get; set; }
protected override Android.Views.View InflateViewForHolder(Android.Views.ViewGroup parent, int viewType, MvvmCross.Binding.Droid.BindingContext.IMvxAndroidBindingContext bindingContext)
{
var view = base.InflateViewForHolder(parent, viewType, bindingContext);
var clickablePiece1 = view.FindViewById<View>(Resource.Id.clickable_piece1);
var clickablePiece2 = view.FindViewById<View>(Resource.Id.clickable_piece2);
clickablePiece1.SetOnClickListener(this);
clickablePiece2.SetOnClickListener(this);
return view;
}
public void OnClick(View v)
{
var viewHolder = this.TwoPieceMvxRecyclerView.FindContainingViewHolder(v);
var item = GetItem(viewHolder.LayoutPosition); // What different is viewHolder.AdapterPosition? I tested it with 100 items and it's always the same, but I'm not sure if this will never break...
if (v.Id == Resource.Id.clickable_piece1)
{
TwoPieceMvxRecyclerView.ItemClickPiece1.Execute(item);
}
else if (v.Id == Resource.Id.clickable_piece2)
{
TwoPieceMvxRecyclerView.ItemClickPiece2.Execute(item);
}
}
}
然后在包含 activity(或片段)中:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_search);
var r = FindViewById<TwoPieceMvxRecyclerView>(Resource.Id.my_twopiecemvxrecyclerview);
var adapter = new TwoPieceMvxRecyclerAdapter(((IMvxAndroidBindingContext)BindingContext));
adapter.TwoPieceMvxRecyclerView = r;
r.Adapter = adapter;
}
并像这样使用它:
<My.Namespace.TwoPieceMvxRecyclerView
android:id="@+id/my_twopiecemvxrecyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
local:MvxItemTemplate="@layout/my_two_piece_layout"
local:MvxBind="ItemsSource MyItems; ItemClickPiece1 MyItemClick1; ItemClickPiece2 MyItemClick2" />
my_two_piece_layout.xml
需要具有 ID 为 clickable_piece1
和 clickable_piece2