我有一个Grid RecyclerView
(3列),我在OnBindViewHolder
方法中添加了一个委托点击监听器。
场景(附加日志)
假设我有18个项目,即6行。默认情况下没有任何滚动,我只能看到2.5行。
当我点击项目(位置0-8)时,委托函数只被调用一次(尝试1~2)。
当我滚动到页面末尾,然后单击其中一个项目时,委托函数将被调用一次(尝试3)。
如果我向上滚动,然后单击其中一个项目,委托函数将被调用4次(尝试4)。
在我的(尝试5)中,我将其滚动到底部并单击一个项目,这次,委托函数被调用两次。
注意:
Xamarin.Android
我的问题是为什么会发生这种情况,还有其他正确的方法来实现吗?
日志
// Attempt 1 : (I clicked position 1)
[[Log ==== ]] [Time : 9/12/2015 10:36:44 AM ] Clicked position [1]
// Attempt 2 : (I clicked position 3)
[[Log ==== ]] [Time : 9/12/2015 10:36:52 AM ] Clicked position [3]
// Attempt 3 : (I scroll it till the end of the page and clicked position 14)
[[Log ==== ]] [Time : 9/12/2015 10:36:52 AM ] Clicked position [14]
// Attempt 4 : (I scroll it back to the top and clicked position 1)
[[Log ==== ]] [Time : 9/12/2015 10:40:08 AM ] Clicked position [4]
[[Log ==== ]] [Time : 9/12/2015 10:40:08 AM ] Clicked position [15]
[[Log ==== ]] [Time : 9/12/2015 10:40:08 AM ] Clicked position [5]
[[Log ==== ]] [Time : 9/12/2015 10:40:08 AM ] Clicked position [16]
[[Log ==== ]] [Time : 9/12/2015 10:40:08 AM ] Clicked position [1]
// Attempt 5 : (I scroll it down again and clicked position 14)
[[Log ==== ]] [Time : 9/12/2015 10:41:57 AM ] Clicked position [11]
[[Log ==== ]] [Time : 9/12/2015 10:41:57 AM ] Clicked position [14]
活动
[Activity (Label = "DrinksMenuCategory", Theme = "@style/AppTheme.ActionBar")]
public class DrinksMenuCategory : AppCompatActivity
{
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;
private int selected_drinksCategory;
private List<Drinks> drinksCategory;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Activity_DrinksMenuCategoryGridview);
SupportActionBar.SetDisplayHomeAsUpEnabled (true);
mRecyclerView = FindViewById<RecyclerView> (Resource.Id.recyclerView_drinksMenuCategoryGridView);
mRecyclerView.HasFixedSize = true;
mLayoutManager = new GridLayoutManager (this, 3);
mRecyclerView.SetLayoutManager (mLayoutManager);
mAdapter = new DrinksMenuCategoryRecyclerAdapter (drinksCategory, mRecyclerView);
mRecyclerView.SetAdapter (mAdapter);
}
}
适配器&amp; ViewHolder
public class DrinksMenuCategoryRecyclerAdapter : RecyclerView.Adapter
{
public List<Drinks> mDrinksItems;
public RecyclerView mRecyclerView;
public DrinksMenuCategoryRecyclerAdapter (List<Drinks> drinksItems, RecyclerView mRecyclerView)
{
this.mDrinksItems = drinksItems;
this.mRecyclerView = mRecyclerView;
}
public override int GetItemViewType (int position)
{
return Resource.Layout.recyclerView_cell_drinksMenu_category;
}
public override RecyclerView.ViewHolder OnCreateViewHolder (ViewGroup parent, int viewType)
{
View row = LayoutInflater
.From (parent.Context)
.Inflate (Resource.Layout.recyclerView_cell_drinksMenu_category, parent, false);
CardView v_drinksCard = row.FindViewById<CardView> (Resource.Id.drinks_card);
ImageView v_drinksImage = row.FindViewById<ImageView> (Resource.Id.drinks_image);
TextView v_drinksText = row.FindViewById<TextView> (Resource.Id.drinks_text);
DrinksMenuItemHolder viewHolder = new DrinksMenuItemHolder (row, parent.Context) {
mDrinksCard = v_drinksCard,
mDrinksImage = v_drinksImage,
mDrinksText = v_drinksText
};
return viewHolder;
}
public override void OnBindViewHolder (RecyclerView.ViewHolder holder, int position)
{
DrinksMenuItemHolder viewHolder = holder as DrinksMenuItemHolder;
viewHolder.mDrinksCard.Click += delegate {
// *** Click Event ***
Log.Debug ("[DrinksMenuCategoryRecyclerAdapter ==== ]", "[Time : " + DateTime.Now + " ] Clicked position [" + position + "]");
Toast.MakeText (viewHolder.context, "[Time : " + DateTime.Now + " ] Clicked position [" + position + "]", ToastLength.Short).Show ();
};
viewHolder.mDrinksText.Text = mDrinksItems[position].name;
}
public override int ItemCount {
get { return mDrinksItems.Count; }
}
public class DrinksMenuItemHolder : RecyclerView.ViewHolder
{
public Context context { get; set; }
public View mMainView { get; set; }
public CardView mDrinksCard { get; set; }
public ImageView mDrinksImage { get; set; }
public TextView mDrinksText { get; set; }
public DrinksMenuItemHolder (View view, Context context) : base (view)
{
this.context = context;
mMainView = view;
}
}
}
答案 0 :(得分:0)
(我知道我迟到了,但无论如何......)
viewHolder.mDrinksCard.Click += delegate {..}
每次绑定ViewhHolder
(发生很多事情)时,您都会创建一个新委托并将其添加到潜在的现有视图中。随着时间的推移,视图会累积多个Click
个代表,每个代表依次响应一次点击。
您需要断开连接,删除Click
中的Adapter.onViewRecycled()
代理。