SwipeRefreshLayout return 错误
SwipeRefreshLayout return bug
我使用的是 SwipeRefeshLayout
,里面有 RecycleView
。
此 recycleView
包含 view-holders
,它们具有可更改显示的点击功能。这工作正常,直到我多次刷新视图。
例如:如果我刷新 5 次,点击一个 viewholder
,我将不得不在 return 按钮上点击 5 次才能 return 到 recycleview
片段。
代码:
HomeFragment.cs:
private void HandleRefresh(object sender, EventArgs e)
{
try
{
page = 0;
adapter.clearMoments();
RefreshData(adapter, 0);
mySwipeRefreshLayout.Refreshing = false;
}
private async void RefreshData(MomentAdapterRV adapter, int page)
{
JsonValue json = await model.getMoments(page);
try
{
InitData(adapter, json, page);
}
private void InitData(MomentAdapterRV adapter, JsonValue json, int pageNum)
{
var myActivity = (MainActivity)this.Activity;
try
{
if (json.Count > 0)
{
for (var i = 0; i < json.Count; i++)
{
// Some code
adapter.addMoment(Moment moment)
}
// Some code
}
}
MomentAdapterRV.cs:
public MomentAdapterRV(Context context, List<Moment> items, MainActivity activity)
{
mItems = items;
mContext = context;
mActivity = activity;
cb = CommunityBuilderModel.Instance;
}
/// <summary>
/// This is the constuctor function of this adapter where the given class arguments (streamFragment, Moments) are being passed to the class variables.
/// </summary>
/// <param name="streamFragement"></param>
/// <param name="mItems"></param>
public MomentAdapterRV(StreamFragment streamFragement, List<Moment> mItems)
{
this.streamFragement = streamFragement;
this.mItems = mItems;
}
public void addMoment(Moment moment)
{
mItems.Add(moment);
NotifyDataSetChanged();
}
public void clearMoments()
{
mItems.Clear();
}
public override RecyclerView.ViewHolder
OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.MomentListItem, parent, false);
MomentViewHolder vh = new MomentViewHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
// Some code
vh.llMain.Click += (object sender, EventArgs e) =>
{
//Check if you don't get a negative position from the header.
if (holder.AdapterPosition >= 0)
{
// Create a new fragment and a transaction.
FragmentTransaction fragmentTx = mActivity.FragmentManager.BeginTransaction();
MomentFragment aDifferentDetailsFrag = new MomentFragment();
// Some code
// Replace the fragment that is in the View fragment_container (if applicable).
fragmentTx.Replace(Resource.Id.frameLayout1, aDifferentDetailsFrag);
// Add the transaction to the back stack.
fragmentTx.AddToBackStack(null);
// Commit the transaction.
fragmentTx.Commit();
//Put Argument
aDifferentDetailsFrag.Arguments = utilBundle;
}
};
}
}
}
您的问题是您在 OnBindViewHolder
中分配了 Click
事件并且您从未取消订阅此点击事件。
因此,每次您在 RecyclerView 中刷新项目时,都会调用 OnBindViewHolder
。如果您的列表长于屏幕上无法显示的长度并且您上下滚动,也会发生这种情况。
相反,即使在 OnCreateViewHolder
中,您也应该分配 Click
,这样它只会连接一次,而不是每次都显示。
我使用的是 SwipeRefeshLayout
,里面有 RecycleView
。
此 recycleView
包含 view-holders
,它们具有可更改显示的点击功能。这工作正常,直到我多次刷新视图。
例如:如果我刷新 5 次,点击一个 viewholder
,我将不得不在 return 按钮上点击 5 次才能 return 到 recycleview
片段。
代码: HomeFragment.cs:
private void HandleRefresh(object sender, EventArgs e)
{
try
{
page = 0;
adapter.clearMoments();
RefreshData(adapter, 0);
mySwipeRefreshLayout.Refreshing = false;
}
private async void RefreshData(MomentAdapterRV adapter, int page)
{
JsonValue json = await model.getMoments(page);
try
{
InitData(adapter, json, page);
}
private void InitData(MomentAdapterRV adapter, JsonValue json, int pageNum)
{
var myActivity = (MainActivity)this.Activity;
try
{
if (json.Count > 0)
{
for (var i = 0; i < json.Count; i++)
{
// Some code
adapter.addMoment(Moment moment)
}
// Some code
}
}
MomentAdapterRV.cs:
public MomentAdapterRV(Context context, List<Moment> items, MainActivity activity)
{
mItems = items;
mContext = context;
mActivity = activity;
cb = CommunityBuilderModel.Instance;
}
/// <summary>
/// This is the constuctor function of this adapter where the given class arguments (streamFragment, Moments) are being passed to the class variables.
/// </summary>
/// <param name="streamFragement"></param>
/// <param name="mItems"></param>
public MomentAdapterRV(StreamFragment streamFragement, List<Moment> mItems)
{
this.streamFragement = streamFragement;
this.mItems = mItems;
}
public void addMoment(Moment moment)
{
mItems.Add(moment);
NotifyDataSetChanged();
}
public void clearMoments()
{
mItems.Clear();
}
public override RecyclerView.ViewHolder
OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.MomentListItem, parent, false);
MomentViewHolder vh = new MomentViewHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
// Some code
vh.llMain.Click += (object sender, EventArgs e) =>
{
//Check if you don't get a negative position from the header.
if (holder.AdapterPosition >= 0)
{
// Create a new fragment and a transaction.
FragmentTransaction fragmentTx = mActivity.FragmentManager.BeginTransaction();
MomentFragment aDifferentDetailsFrag = new MomentFragment();
// Some code
// Replace the fragment that is in the View fragment_container (if applicable).
fragmentTx.Replace(Resource.Id.frameLayout1, aDifferentDetailsFrag);
// Add the transaction to the back stack.
fragmentTx.AddToBackStack(null);
// Commit the transaction.
fragmentTx.Commit();
//Put Argument
aDifferentDetailsFrag.Arguments = utilBundle;
}
};
}
}
}
您的问题是您在 OnBindViewHolder
中分配了 Click
事件并且您从未取消订阅此点击事件。
因此,每次您在 RecyclerView 中刷新项目时,都会调用 OnBindViewHolder
。如果您的列表长于屏幕上无法显示的长度并且您上下滚动,也会发生这种情况。
相反,即使在 OnCreateViewHolder
中,您也应该分配 Click
,这样它只会连接一次,而不是每次都显示。