防止滚动时 SetTag/GetTag 的用户在 RecyclerView 网格中重用第一个项目视图
Prevent reuse of first item view in RecycleView grid with the user of SetTag/GetTag on scroll
我正在创建一个应用程序,我在这个应用程序中创建了一个带有 recycleview 的图像网格。第一项显示当前用户的照片,而其他图像显示其他用户的图像。为了为第一个项目设置正确的图像,我使用了一个变量计数。如果计数 == 0 则设置正确的图像。不幸的是,当网格滚动到默认背景资源图像时,加载的第一个项目图像发生了变化。当然这是由于 ItemViewHolder 对视图的重用。所以我的问题是如何在滚动网格时在第一项中保持正确的图像。从我目前的研究来看,可能有效的是 SetTag/GetTag。但是,我不确定在这种情况下使用它。任何帮助,将不胜感激。
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
try
{
View itemview = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.Search_item_layout_local, parent, false);
ItemViewHolder ivh = new ItemViewHolder(itemview, OnClick);
ISharedPreferences iSharedPref = PreferenceManager.GetDefaultSharedPreferences(itemview.Context);
ISharedPreferencesEditor iSharedPrefEditor = iSharedPref.Edit();
var genImage = itemview.FindViewById<SquareImageView>(Resource.Id.grid_item_image);
var count = ii++;
if (count == 0)
{
string image = string.Empty;
if (iSharedPref.GetString("Gender", "Male").ToString() == "Female")
{
genImage.SetBackgroundResource(Resource.Mipmap.Female);
}
else
{
genImage.SetBackgroundResource(Resource.Mipmap.Male);
ivh._ProfileImage.SetTag(Resource.Mipmap.Male, count);
}
}
else
{
if (iSharedPref.GetString("Seeking", "Female").ToString() == "Female")
{
genImage.SetBackgroundResource(Resource.Mipmap.Female);
}
else
{
genImage.SetBackgroundResource(Resource.Mipmap.Male);
}
}
return ivh;
}
catch (Exception ex)
{
FirebaseCrash.Report(ex);
return null;
}
}
您应该将 OnCreateViewHolder
减少到仅实例化、设置该视图并返回 ViewHolder
,然后在 OnBindViewHolder
覆盖中处理绑定,这样您就有了稳定的 ID 来采取行动。
类似于:
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.app_info, parent, false);
return new ItemViewHolder(itemview); // "OnClick" should be added in the OnBindViewHolder and removed in the OnViewRecycled
}
现在在 OnBindViewHolder
中,您将获得一个稳定的 position
值,您可以根据该值采取行动(在您的情况下,位置为零是一种特殊情况)。在此覆盖中,您将处理为 ViewHolder 分配值,添加 listeners/event 处理程序等。:
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var viewHolder = holder as ItemViewHolder;
if (position == 0)
{
~~~
}
else
{
~~~
}
}
在 OnViewRecycled
覆盖中,删除所有 listeners/event 处理程序等。以防止内存泄漏等...
public override void OnViewRecycled(Java.Lang.Object holder)
{
var viewHolder = holder as ItemViewHolder;
~~~
base.OnViewRecycled(holder);
}
我正在创建一个应用程序,我在这个应用程序中创建了一个带有 recycleview 的图像网格。第一项显示当前用户的照片,而其他图像显示其他用户的图像。为了为第一个项目设置正确的图像,我使用了一个变量计数。如果计数 == 0 则设置正确的图像。不幸的是,当网格滚动到默认背景资源图像时,加载的第一个项目图像发生了变化。当然这是由于 ItemViewHolder 对视图的重用。所以我的问题是如何在滚动网格时在第一项中保持正确的图像。从我目前的研究来看,可能有效的是 SetTag/GetTag。但是,我不确定在这种情况下使用它。任何帮助,将不胜感激。
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
try
{
View itemview = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.Search_item_layout_local, parent, false);
ItemViewHolder ivh = new ItemViewHolder(itemview, OnClick);
ISharedPreferences iSharedPref = PreferenceManager.GetDefaultSharedPreferences(itemview.Context);
ISharedPreferencesEditor iSharedPrefEditor = iSharedPref.Edit();
var genImage = itemview.FindViewById<SquareImageView>(Resource.Id.grid_item_image);
var count = ii++;
if (count == 0)
{
string image = string.Empty;
if (iSharedPref.GetString("Gender", "Male").ToString() == "Female")
{
genImage.SetBackgroundResource(Resource.Mipmap.Female);
}
else
{
genImage.SetBackgroundResource(Resource.Mipmap.Male);
ivh._ProfileImage.SetTag(Resource.Mipmap.Male, count);
}
}
else
{
if (iSharedPref.GetString("Seeking", "Female").ToString() == "Female")
{
genImage.SetBackgroundResource(Resource.Mipmap.Female);
}
else
{
genImage.SetBackgroundResource(Resource.Mipmap.Male);
}
}
return ivh;
}
catch (Exception ex)
{
FirebaseCrash.Report(ex);
return null;
}
}
您应该将 OnCreateViewHolder
减少到仅实例化、设置该视图并返回 ViewHolder
,然后在 OnBindViewHolder
覆盖中处理绑定,这样您就有了稳定的 ID 来采取行动。
类似于:
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.app_info, parent, false);
return new ItemViewHolder(itemview); // "OnClick" should be added in the OnBindViewHolder and removed in the OnViewRecycled
}
现在在 OnBindViewHolder
中,您将获得一个稳定的 position
值,您可以根据该值采取行动(在您的情况下,位置为零是一种特殊情况)。在此覆盖中,您将处理为 ViewHolder 分配值,添加 listeners/event 处理程序等。:
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var viewHolder = holder as ItemViewHolder;
if (position == 0)
{
~~~
}
else
{
~~~
}
}
在 OnViewRecycled
覆盖中,删除所有 listeners/event 处理程序等。以防止内存泄漏等...
public override void OnViewRecycled(Java.Lang.Object holder)
{
var viewHolder = holder as ItemViewHolder;
~~~
base.OnViewRecycled(holder);
}