2017-10-07 78 views
0

我正在實現一個listview,其中每個元素包含2個文本視圖和一個seekbar。這樣的佈局: LayoutBaseAdapter在滾動時更改值

活動有一個viewpager與3個不同的片段。 在片段3中,我使用listview來顯示自定義適配器。 列表中的項目數量是動態的,因此滾動條可能會出現。

如果滾動條存在,並且一個滾動某些視圖不再顯示並再次返回,則值有時會更改。 我知道這是由於適配器中GetView()的重新創建。但我無法找到它改變的原因。

的過程應該是這樣的:

  • 沒有什麼選擇:搜索條是灰色的,右邊TextView的顯示不 初始化選擇
  • 事情:欄爲藍色,右TextView的搜索條進度

以下是的代碼自定義適配器

class EntryAdapter : BaseAdapter<Entry> 
{ 
    List<Entry> mEntryList; 
    Activity mActivity; 
    ColorFilter grayFilter; 
    ColorFilter blueFilter; 

    public EntryAdapter(Activity activity, List<Entry> entryList) : base() 
    { 
     mEntryList = entryList; 
     mActivity = activity; 

     grayFilter = new PorterDuffColorFilter(Color.Gray, PorterDuff.Mode.SrcIn); 
     blueFilter = new PorterDuffColorFilter(Color.Blue, PorterDuff.Mode.SrcIn); 
    } 

    public override Entry this[int position] 
    { 
     get 
     { 
      return mEntryList[position]; 
     } 
    } 

    public override int Count 
    { 
     get 
     { 
      return mEntryList.Count; 
     } 
    } 

    public override long GetItemId(int position) 
    { 
     return position; 
    } 

    public override View GetView(int position, View convertView, ViewGroup parent) 
    { 
     ViewHolder holder = null; 
     View view = convertView; 

     if (view == null) 
     { 
      holder = new ViewHolder(); 
      view = mActivity.LayoutInflater.Inflate(Resource.Layout.ListItem_Entry, null); 
      holder.Name = view.FindViewById<TextView>(Resource.Id.li_entry_tv_feature_name); 
      holder.Value = view.FindViewById<TextView>(Resource.Id.li_entry_tv_feature_value); 
      holder.Unit = view.FindViewById<TextView>(Resource.Id.li_entry_tv_feature_value_unit); 
      holder.Seeker = view.FindViewById<SeekBar>(Resource.Id.li_entry_sb_feature); 
      view.Tag = holder; 
     } 

     holder = (ViewHolder)view.Tag; 

     Entry current = mEntryList[position]; 


     holder.Seeker.Max = current.Max + 1; 
     holder.Seeker.Progress = current.Value; 
     holder.Seeker.Tag = current; 
     holder.Name.Text = current.Name; 
     holder.Value.Text = Convert.ToString(current.Value);  
     holder.Seeker.ProgressChanged += delegate (object sender, SeekBar.ProgressChangedEventArgs e) 
     { 
      Entry entry = e.SeekBar.Tag as Entry; 

      if (e.Progress <= 0) 
      { 
       holder.Name.Text = entry.Name; 
       entry.Value = 0; 
      } 
      else 
      { 
       holder.Name.Text = entry.Name + " (" + entry.Unit + "):"; 
       entry.Value = e.Progress - 1; 
      } 

      if (e.Progress <= 0) 
      { 
       holder.Value.Text = "Not initialized!"; 
       holder.Seeker.ProgressDrawable.SetColorFilter(grayFilter); 
       holder.Seeker.Thumb.SetColorFilter(grayFilter); 
      } 
      else 
      { 
       holder.Value.Text = Convert.ToString(e.Progress - 1); 
       holder.Seeker.ProgressDrawable.SetColorFilter(blueFilter); 
       holder.Seeker.Thumb.SetColorFilter(blueFilter); 
      } 
     }; 

     if (holder.Seeker.Progress <= 0) 
     { 
      holder.Name.Text = mEntryList[position].Name; 
      mEntryList[position].Value = 0; 
     } 
     else 
     { 
      holder.Name.Text = mEntryList[position].Name + " (" + mEntryList[position].Unit + "):"; 
      mEntryList[position].Value = holder.Seeker.Progress; 
     } 

     if (holder.Seeker.Progress <= 0) 
     { 
      holder.Value.Text = "Not initialized!"; 
      holder.Seeker.ProgressDrawable.SetColorFilter(grayFilter); 
      holder.Seeker.Thumb.SetColorFilter(grayFilter); 
     } 
     else 
     { 
      holder.Value.Text = Convert.ToString(holder.Seeker.Progress); 
      holder.Seeker.ProgressDrawable.SetColorFilter(blueFilter); 
      holder.Seeker.Thumb.SetColorFilter(blueFilter); 
     } 

     return view; 
    } 

    public class ViewHolder : Java.Lang.Object 
    { 
     public TextView Name { set; get; } 
     public TextView Value { set; get; } 
     public SeekBar Seeker { set; get; } 
     public Entry CurrentEntry { set; get; } 
    } 
} 

類條目看起來是這樣的:

class Entry : Java.Lang.Object, IParcelable 
{ 
    [ExportField ("CREATOR")] 
    static EntryCreator InitialieCreator() 
    { 
     return new EntryCreator(); 
    } 


    public int Id { set; get; } 
    public int Max { set; get; } 
    public int Value { set; get; } 
    public string Name { set; get; } 

    public Entry() 
    { 

    } 

    public Entry (int id, int max, int value, string name) 
    { 
     Id = id; 
     Max = max; 
     Value = value; 
     Name = name; 
    } 

    public int DescribeContents() 
    { 
     return 0; 
    } 

    public void WriteToParcel(Parcel dest, [GeneratedEnum] ParcelableWriteFlags flags) 
    { 
     dest.WriteInt(Id); 
     dest.WriteInt(Max); 
     dest.WriteInt(Value); 
     dest.WriteString(Name); 
    } 

    public class EntryCreator : Java.Lang.Object, IParcelableCreator 
    { 
     public Java.Lang.Object CreateFromParcel(Parcel source) 
     { 
      return new Entry(source.ReadInt(), source.ReadInt(), source.ReadInt(), source.ReadString()); 
     } 

     public Java.Lang.Object[] NewArray(int size) 
     { 
      return new Java.Lang.Object[size]; 
     } 
    } 
} 

也許有人可以告訴我爲什麼值發瘋。從「未初始化」到「一切都是可能的,而滾動」。現在我已經坐了幾個星期了。

回答

0

我終於找到了爲什麼會發生這種情況,這是由於EditText小部件有相同的問題。

其原因在於,更改應用程序初始化視圖時發生的值也會觸發偵聽器。有時候,它不夠快,有時它會以錯誤的立場來誇大價值。

要停止該SeekBar.ProgressChangedEventArgs提供boolFromUser這表明,如果改變是由用戶或程序做出。所以我只用if(FromUser)來包裝聽衆中的所有變化。

傳統上TextWatcherEditText s不提供此參數。但在這answer我找到了一個工作解決方案。如果您不需要EditTextTag

簡而言之:用隨機填充標籤,然後從代碼中修改EditText,然後設置Tag NULL。在監聽器中檢查標記是否爲NULL(用戶編輯)或NOT NULL(以編程方式)