2017-10-07 71 views
-1

儘管RecyclerView的Dispose函數沒有被調用(通過設置變量檢查),也沒有被回收(也通過設置變量進行檢查),但我目前正在處理RecycleView中的視圖被丟棄的問題。如何在Android C#中找到特定對象的父類?

主要問題:MvxPropertyChangedListener未被清除。偵聽器然後嘗試對處置的視圖執行操作,從而引發問題。無論我在哪裏調用listener.Clear()(從DisView中的ReViewView.Adapter中的onViewRecycled,在最初綁定ViewModel之前),我仍然會得到'object is dispos'異常。

圍繞有問題的視圖嘗試抓住'修復'問題,但並未解決根本問題。

問題: 在Xamarin中,我該如何跟蹤這些RecycleViews?通過我的try-catch,我可以看到哪些人有問題(這就是爲什麼我可以跟蹤它是否被處置,再循環等)和相關的ViewModel,但是不知道如何跟蹤這些內部視圖對象的原因和位置配置?

注:我有更多的iOS開發經驗。我的Android理解是公平的,但缺乏勇氣。

編輯:代碼提供。

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

應該歡迎一些代碼! – hugoterelle

+0

@hugorgor:我提供了代碼,但我的問題是關於'我該怎麼做?'類型。與代碼無關,但如果您有任何建議,我都會接受。 注意。這些點代表代碼的無關部分。 – user3431574

回答

1

隨着MvvmCross你不應該擔心寫你自己的ViewHolder或適配器類。 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,這是你指定要用於每個TileViewModels的次要視圖。

你的孩子視圖可以看起來像這樣簡單:

<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僅代表子視圖將如何綁定到子視圖模型。子視圖可以包含任意數量的控件。

相關問題