我目前遇到的问题是RecycleView中的视图正在被处理,尽管RecyclerView的Dispose功能未被调用(通过设置变量检查),也没有被回收(也通过设置变量来检查)。
主要问题:未清除MvxPropertyChangedListener。然后,侦听器尝试对已处理的视图执行操作,从而导致问题。无论我在哪里调用listener.Clear()(来自RecycleView.Adapter中的onViewRecycled,来自Dispose,在我们最初绑定ViewModel之前),我仍然得到'对象被处理'异常。
围绕有问题的视图进行尝试捕捉'修复'问题,但没有解决根本问题。
问题: 在Xamarin中,如何跟踪这些RecycleViews?通过我的try-catch,我可以看到哪些问题(这就是为什么我可以跟踪它是否被处理,回收等)和相关的ViewModel,但是不知道如何跟踪这些问题的原因和位置内部视图对象被处理?
注意:我有更多iOS开发经验。我的Android理解是公平的,但缺乏atm。
编辑:提供的代码。
public class CarouselViewHolder : BaseCarouselViewHolder
{
private SimpleProgressBar _progressBar;
// tile listener
private MvxPropertyChangedListener _tileListener;
private CarouselTileViewModel Tile => (Item as CarouselTileViewModel);
public SingleCarouselItemViewHolder(View v) : base(v)
{
_progressBar = v.FindViewById<BasicProgressBar>(Resource.Id.progressBar);
}
public override void PrepareForReuse()
{
ClearTileListener();
base.PrepareForReuse();
}
public void SetTile(CarouselTileViewModel tile)
{
// keep the item
Item = tile;
// progress bar
RefreshProgressBar ();
// listeners
SetupTileListener();
}
private void SetupTileListener()
{
ClearTileListener();
// setup the listener for the item
if(Item != null && Item is CarouselTileViewModel)
{
_tileListener = new MvxPropertyChangedListener(Item as CarouselTileViewModel);
_tileListener.Listen (() => (Item as CarouselTileViewModel).Progress, RefreshProgressBar);
}
}
private void RefreshProgressBar ()
{
try
{
if (_progressBar != null)
{
_progressBar.Visibility = Tile.Progress > 0 ? ViewStates.Visible : ViewStates.Gone;
_progressBar.SetProgress(Tile.Progress);
}
}
catch (ObjectDisposedException e)
{
Phx.TaggedError ("BasicProgressBar already disposed", "Exception {0}", e);
}
}
private void ClearTileListener()
{
// kill any old listeners
if(_tileListener != null)
{
_tileListener.Clear();
_tileListener.Dispose();
_tileListener = null;
}
}
public override void OnAttachedToWindow()
{
}
public override void OnDetachedFromWindow()
{
}
protected override void Dispose(bool disposing)
{
ClearTileListener();
base.Dispose(disposing);
}
}
public class CarouselItemAdapter : BaseCarouselAdapter<CarouselViewModel>
{
.
.
.
public override void OnViewAttachedToWindow(Java.Lang.Object holder)
{
base.OnViewAttachedToWindow(holder);
if(holder is CarouselViewHolder)
{
(holder as CarouselViewHolder).OnAttachedToWindow();
}
}
public override void OnViewDetachedFromWindow(Java.Lang.Object holder)
{
base.OnViewDetachedFromWindow(holder);
if (holder is CarouselViewHolder)
{
(holder as CarouselViewHolder).PrepareForReuse();
(holder as CarouselViewHolder).OnDetachedFromWindow();
}
}
public override void OnViewRecycled(Java.Lang.Object holder)
{
base.OnViewRecycled(holder);
if (holder is CarouselViewHolder)
{
(holder as CarouselViewHolder).PrepareForReuse();
}
}
}
答案 0 :(得分:1)
使用MvvmCross,您不必担心编写自己的ViewHolder或Adapter类。 MvxRecyclerView负责实现这些类并绑定所有ViewModel。
在父视图中定义MvxRecyclerView:
<MvxRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
local:MvxBind="ItemClick TileClickedCommand; ItemsSource Tiles;"
local:MvxItemTemplate="@layout/tileitemview" />
请注意MvxItemTemplate,您可以在此指定用于每个TileViewModel的辅助视图。
您的子视图可以看起来像这样简单:
<TextView 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="wrap_content"
local:MvxBind="Text Format('{0:f}', Progress)" />
注意:我使用TextView仅表示子视图将如何绑定到子ViewModel。子视图可以包含任意数量的控件。