【问题标题】:BaseAdapter Changing Values while scrollingBaseAdapter 在滚动时更改值
【发布时间】:2017-10-07 12:01:02
【问题描述】:

我正在实现一个列表视图,其中每个元素包含 2 个文本视图和一个搜索栏。像这样的布局(this):

该活动有一个带有 3 个不同片段的 viewpager。 在片段 3 中,我使用列表视图来显示自定义适配器。 列表中的项目数是动态的,因此可能会出现滚动条。

如果存在滚动条并且将某些视图滚动出显示并再次返回,则值有时会发生变化。 我知道这是由于适配器中的 GetView() 重新创建的。但我找不到它改变的原因。

流程应该是这样的:

  • 无选择:搜索栏为灰色,右侧的 textview 未显示 初始化
  • 选择了一些东西:栏是蓝色的,右边的 textview seekbar 进度

这是自定义适配器的代码:

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];
        }
    }
}

也许有人可以告诉我为什么价值观会变得疯狂。滚动时,从“未初始化”到 n 一切皆有可能。我已经不知所措了几个星期了。

【问题讨论】:

    标签: android xamarin xamarin.android baseadapter


    【解决方案1】:

    我终于找到了为什么会这样,因为 EditText 小部件也有同样的问题。

    其原因是在应用程序初始化视图时发生的值更改也会触发侦听器。有时它不够快,有时它会将值与错误的位置混淆。

    为了阻止 SeekBar.ProgressChangedEventArgs 提供 bool FromUser 来显示更改是由用户还是以编程方式进行的。所以我只是用if(FromUser) 结束了侦听器中的所有更改。

    顺便提一下,TextWatcherEditTexts 不提供此参数。但是在这个answer 中,我找到了一个可行的解决方案。如果你不需要EditTextTag

    简而言之:在您从代码中更改 EditText 并在之后将 Tag 设置为 NULL 之前,用随机的东西填充标签。在侦听器中检查 Tag 是否为 NULL(用户编辑)或 NOT NULL(以编程方式)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-30
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多