ListView更新错误行的值

时间:2014-12-01 17:59:43

标签: android android-listview xamarin xamarin.android baseadapter

在下面的代码中,我有一个ListView,其中包含一个包含Name,Id和Quantity的Items列表。当我单击一行时,应根据UpdateItemSelectedInListView()方法中的通知参数更新此值。但只有第9行具有更改的值,与我选择的行无关。

的活动:

public class MainActivity : Activity
{
    ListView    _ListView;

    AdapterItem _Adapter;

    List<Item> _ListaItem = new List<Item>();

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        SetContentView(Resource.Layout.Main);

        CriaListView();
    }

    private void CriaListView()
    {
        _ListView = FindViewById<ListView>(Resource.Id.listaItems);

        _ListView.ItemClick += _ListView_ItemClick;

        _ListView.Adapter = CriaAdapter();
    }

    private AdapterItem CriaAdapter()
    {
        for (int i = 0; i < 15; i++)
        {
            _ListaItem.Add(new Item("Test Name",i));  
        }

        _Adapter = new AdapterItem(this, _ListaItem);

        return _Adapter;
    }
    void _ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
    {
        _Adapter.UpdateItemSelectedInListView(e.Position, 5);
    }
}

适配器:

public class AdapterItem : BaseAdapter
{

List<Item>     _ListaItem = new List<Item>();

Activity       _Activity;

LayoutInflater _Inflate;

ViewHolderItem _HolderItem;

Boolean        _HasUpdate;

int            _IdToUpDate;

int            _NewQntd;

int            _Position;

public AdapterItem(Activity activity, List<Item> listaItem)
{
    _Activity = activity;

    _ListaItem = listaItem;

    try
    {
        _Inflate = (LayoutInflater)_Activity.GetSystemService(Context.LayoutInflaterService);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

View _View;

public override View GetView(int position, Android.Views.View convertView,  Android.Views.ViewGroup parent)
{
    _View = convertView;

    try
    {
        if (_View != null)
            _HolderItem = _View.Tag as ViewHolderItem;

        else
        {
            _View = _Activity.LayoutInflater.Inflate(Resource.Layout.LayoutItem, null);

            _HolderItem = CriaViewHolder();
        }

        PopulaViewHolder(position);

        _View.Tag = _HolderItem;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }

    return _View;
}

private ViewHolderItem CriaViewHolder()
{
    ViewHolderItem holderItem = new ViewHolderItem();

    holderItem.txtNameItem = _View.FindViewById<TextView>(Resource.Id.nameItem);

    holderItem.txtIdItem   = _View.FindViewById<TextView>(Resource.Id.idItem);

    holderItem.txtqntItem  = _View.FindViewById<TextView>(Resource.Id.totalInStock);

    return holderItem;
}

private void PopulaViewHolder(int position)
{
    _HolderItem.txtNameItem.Text = _ListaItem[position].nome;

    _HolderItem.txtIdItem.Text   = _ListaItem[position].id.ToString();

    if (_HasUpdate && (position == _Position)) 
        UpdateAdapter();
}

public void UpdateAdapter()
{
    _HolderItem.txtqntItem.Text = _NewQntd.ToString();

    _HasUpdate = false;
}

public void UpdateItemSelectedInListView(int position, int newValue)
{
    _NewQntd = newValue;

    _HasUpdate = true;

    _Position = position;

    this.NotifyDataSetChanged();
}

public override Java.Lang.Object GetItem(int position)
{
    return 0;
}

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

public override long GetItemId(int position)
{
    return _ListaItem[position].id;
}

public override int GetItemViewType(int position)
{
    return base.GetItemViewType(position);
}

public override int ViewTypeCount
{
    get
    {
        return base.ViewTypeCount;
    }
}

private class ViewHolderItem : Java.Lang.Object
{
    public TextView txtNameItem { get; set; }
    public TextView txtIdItem   { get; set; }
    public TextView txtqntItem  { get; set; }
}

}

2 个答案:

答案 0 :(得分:0)

您需要在_View.Tag = _HolderItem;方法的其他内容中移动GetView

public override View GetView(int position, Android.Views.View convertView, Android.Views.ViewGroup parent)
{
    _View = convertView;

    try
    {
        if (_View != null)
            _HolderItem = _View.Tag as ViewHolderItem;

        else
        {
            _View = _Activity.LayoutInflater.Inflate(Resource.Layout.LayoutItem, null);

            _HolderItem = CriaViewHolder();

            //Set the tag only when you create a new one
            //otherwise you'll have the problem you are having
            _View.Tag = _HolderItem;
        }

        PopulaViewHolder(position);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }

    return _View;
}

答案 1 :(得分:0)

似乎你的_Adapter.UpdateItemSelectedInListView没有获取正确的位置,因为它失去了状态。相反,您可以使用绑定“事件操作”到视图类的每个视图行。 触发此操作事件[在GetView()中)对活动类的另一个事件操作,以处理Click事件。

//Viewholder class      
internal Action ActionImgViewSelectedToGetView{ get; set;} 
       internal void Initialize(View view)
       {
        imgItem=view.FindViewById<ImageView> (Resource.Id.imgItem);
        imgItem.Click += delegate(object sender , EventArgs e )
        {
         ActionImgViewSelectedToGetView(); //action event to getview()
        };  
       }

//在getview()

viewHolder.ActionImgViewSelectedToGetView = () =>
  {
   if(ActionImgSelectedToActivity!=null)
    ActionImgSelectedToActivity(_lstItem[position].ItemName); //action event,targeting to activity class method
  };

//活性

if ( objItemAdapter != null )
    {
     objItemAdapter.ActionImgSelectedToActivity -= SelectedItem;
     objItemAdapter = null;
    } 
    objItemAdapter = new ItemAdapterClass (this, lstItem);
    objItemAdapter.ActionImgSelectedToActivity += SelectedItem;
    listViewItem.Adapter = objItemAdapter;

void SelectedItem( string strItemName)
        {
            //seleced item
        }

了解更多详情:http://appliedcodelog.blogspot.in/2015/07/working-on-issues-with-listview-in.html#WrongPosition