2017-07-20 27 views
1

我有這個選擇活動我用來選擇元素。它基於超類,它使用RecyclerView。它是使用泛型構建的,所以很容易讓一個「選擇器」傳遞一個模型類。可以使用它來進行單個或多個選擇。Xamarin.Android:RecyclerView.Adapter,元素的錯誤回收

問題是,如果我選擇元素,我滾動,有時我也看到其他行選擇。 行爲是奇怪的,如果我向下滾動一切看起來不錯,如果我足夠回來看到選定的行,我重新開始向下滾動,我看到其他行重複。這只是一個圖形化的東西,所以如果我按OK,活動只返回正確的元素。

我很確定這是一個有關回收的問題,所以我試圖設置爲不可循環使用IsRecyclable選定的行,但它不起作用。

有什麼建議嗎?在RecyclerView.Adapter

enter image description here

部分:

public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup viewGroup, int position) 
{ 
    var itemView = LayoutInflater.From(viewGroup.Context).Inflate(Resource.Layout.activity_basemodel_item, viewGroup, false); 
    var viewHolder = new BaseModelViewHolder(itemView, OnClick, OnLongClick, DetailActivityType); 
    viewHolder.IsRecyclable = !SelectionEnabled; 

    return viewHolder; 
} 

public void HighLight(RecyclerView.ViewHolder viewHolder, int position) 
{ 
    if (!SelectionEnabled) { return; } 

    var guid = ((BaseModelViewHolder)viewHolder).Model.Id; 
    if (SelectedGuids.Contains(guid)) 
    { 
     viewHolder.ItemView.Selected = true; 
     viewHolder.ItemView.SetBackgroundColor(SelectedItemBackgroundColor); 
    } 
    else 
    { 
     viewHolder.ItemView.Selected = false; 
    } 
} 

public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) 
{ 
    TModel model = DataSet[position]; 

    String title = model.Title; 
    String subtitle = model.Subtitle; 

    ((BaseModelViewHolder)viewHolder).TxtTitle.SetText(title, TextView.BufferType.Normal); 
    if (!String.IsNullOrEmpty(subtitle) && !subtitle.Equals(title)) 
    { 
     ((BaseModelViewHolder)viewHolder).TxtSubtitle.SetText(subtitle, TextView.BufferType.Normal); 
    } 
    ((BaseModelViewHolder)viewHolder).Model = model; 

    this.HighLight(viewHolder, position); 
} 

回答

1

RecyclerViews可顯示當模型視圖模型內通過怪異的行爲:

((BaseModelViewHolder)viewHolder).Model = model; //problem 

爲了解決這個問題,你可以這樣做:

public void HighLight(RecyclerView.ViewHolder viewHolder, int position) 
{ 
    if (!SelectionEnabled) { return; } 

    TModel model = DataSet[position]; 
    var guid = model.Id; 
    if (SelectedGuids.Contains(guid)) 
    { 
     viewHolder.ItemView.SetBackgroundColor(SelectedItemBackgroundColor); 
    } 
    else 
    { 
     viewHolder.ItemView.SetBackgroundColor(DefaultItemBackgroundColor); 
    } 
} 

public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) 
{ 
    TModel model = DataSet[position]; 

    String title = model.Title; 
    String subtitle = model.Subtitle; 

    ((BaseModelViewHolder)viewHolder).TxtTitle.SetText(title, TextView.BufferType.Normal); 
    if (!String.IsNullOrEmpty(subtitle) && !subtitle.Equals(title)) 
    { 
     ((BaseModelViewHolder)viewHolder).TxtSubtitle.SetText(subtitle, TextView.BufferType.Normal); 
    } 

    this.HighLight(viewHolder, position); 

    // To highlight an item when clicked: 
    viewHolder.ItemView.Click -= HighLight_Item; 
    viewHolder.ItemView.Click += HighLight_Item; //This is to avoid subscribing the event everytime the view is shown 
} 

要選擇一個項目:

private void HighLight_Item(object sender, EventArgs e) 
{ 
    //You need to pass the RecyclerView as an argument to the Adapter 
    int position = this.recyclerView.GetChildAdapterPosition((View)sender); 
    TModel model = DataSet[position]; 
    var guid = model.Id; 
    //If already contains then remove, if doesn't contain then add 
    if(SelectedGuids.Contains(guid)) SelectedGuids.Remove(guid); 
    else SelectedGuids.Add(guid); 
    //This will update the item view 
    this.NotifyItemChanged(position); 
} 
+0

謝謝亞歷山大,它的工作。 –

+0

這足以設置viewHolder.ItemView.SetBackgroundColor(DefaultItemBackgroundColor);我也改變了((BaseModelViewHolder)viewHolder).Model.Id;在DataSet [position];在OnBindViewHolder中。如果你曾經來過意大利的Jesi/Ancona地區,或者今年8月來到愛丁堡,那麼你有足夠的飲料可以喝醉:) –

+0

不客氣的毛羅! – Alexandre