如何在Android C#中找到特定对象的父类?

时间:2017-10-07 02:45:18

标签: c# xamarin xamarin.android mvvmcross

我目前遇到的问题是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();
    }
}
}

1 个答案:

答案 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。子视图可以包含任意数量的控件。