BaseAdapter在滚动时更改值
问题描述:
我正在实现一个listview,其中每个元素包含2个文本视图和一个seekbar。这样的布局: BaseAdapter在滚动时更改值
活动有一个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];
}
}
}
也许有人可以告诉我为什么值发疯。从“未初始化”到“一切都是可能的,而滚动”。现在我已经坐了几个星期了。
答
我终于找到了为什么会发生这种情况,这是由于EditText小部件有相同的问题。
其原因在于,更改应用程序初始化视图时发生的值也会触发侦听器。有时候,它不够快,有时它会以错误的立场来夸大价值。
要停止该SeekBar.ProgressChangedEventArgs
提供bool
FromUser
这表明,如果改变是由用户或程序做出。所以我只用if(FromUser)
来包装听众中的所有变化。
传统上TextWatcher
为EditText
s不提供此参数。但在这answer我找到了一个工作解决方案。如果您不需要EditText
的Tag
。
简而言之:用随机填充标签,然后从代码中修改EditText,然后设置Tag NULL。在监听器中检查标记是否为NULL(用户编辑)或NOT NULL(以编程方式)。