单击事件返回错误位置的适配器视图

时间:2015-11-09 22:36:14

标签: android listview xamarin

视图持有者不再创建重复项,但有时会返回错误的位置。控制台输出如下以及当前代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Android.Text;
using System.Net;
using System.Collections.Specialized;

namespace MyMentor
{
    public class dashboardAdapter : BaseAdapter<DashboardLINQ>
    {
        List<DashboardLINQ> items;
        Activity context;
        int realpos;
        public dashboardAdapter(Activity context, List<DashboardLINQ> items)
            : base()
        {
            this.context = context;
            this.items = items;
        }
        public override long GetItemId(int position)
        {
            return position;
        }
        public override DashboardLINQ this[int position]
        {
            get { return items[position]; }
        }
        public override int Count
        {
            get { return items.Count; }
        }
        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            ServiceViewHolder holder = null;

            Console.WriteLine ("View No If: "+position);
            realpos = position;
            View view = convertView;
            if (view == null) {
                Console.WriteLine ("View == Null: "+position);
                realpos = position;

                holder = new ServiceViewHolder ();
                view = LayoutInflater.From (context).Inflate (Resource.Layout.dashboardItemLayout, null, false);
                holder.like = view.FindViewById<ImageButton> (Resource.Id.button1);
                holder.comment = view.FindViewById<ImageButton> (Resource.Id.button2);
                holder.share = view.FindViewById<ImageButton> (Resource.Id.button3);
                holder.usrname = view.FindViewById<TextView> (Resource.Id.textView1);
                holder.prof = view.FindViewById<ImageView> (Resource.Id.imageView1);

                holder.like.Click += (sender, e) => {
                    WebClient client = new WebClient ();
                    Uri uri = new Uri ("url");
                    NameValueCollection parameters = new NameValueCollection ();
                    parameters.Add ("UID", items [position].MID);
                    parameters.Add ("PID", items [position].ID);
                    client.UploadValuesAsync (uri, parameters);
                }; 

                holder.share.Click += (sender, e) => {
                    int MaxLength = 150;

                    var name = Html.FromHtml (items [position].pDesc).ToString ();
                    if (name.Length > MaxLength) {
                        name = name.Substring (0, MaxLength) + "... My Mentor";
                    }

                    var myIntent = new Intent (Android.Content.Intent.ActionSend);
                    myIntent.PutExtra (Intent.ExtraText, name);
                    myIntent.SetType ("text/plain");
                    this.context.StartActivity (Intent.CreateChooser (myIntent, "Choose an App"));
                };

                holder.usrname.Click += (sender, e) => {
//                  Bundle fragBundle = new Bundle ();
//                  fragBundle.PutString ("image", items [position].uPicLocal);
//                  fragBundle.PutString ("name", items [position].uFullName);
//                  var transaction = this.context.FragmentManager.BeginTransaction ();
//                  var dialogimgview = new DialogImageView ();
//                  dialogimgview.Arguments = fragBundle;
//                  transaction.AddToBackStack (null);
//                  dialogimgview.Show (transaction, "Dialog_Fragment" + position);
                };

                holder.prof.Click += (sender, e) => {
                    Console.WriteLine ("Realpos: "+realpos+"       Position: "+position);
                };
                view.Tag = holder;
            } else {
                holder = view.Tag as ServiceViewHolder;
                Console.WriteLine ("View Not Null: "+position);
            }

            ImageView prof = view.FindViewById<ImageView>(Resource.Id.imageView1);
            Koush.UrlImageViewHelper.SetUrlDrawable (prof, "url"+items [position].uPicLocal);

            TextView usrname = view.FindViewById<TextView> (Resource.Id.textView1);
            usrname.Text = items [position].uFullName;

            TextView date = view.FindViewById<TextView> (Resource.Id.textView2);
            date.Text = items [position].pDate;

            ImageView imagen = view.FindViewById<ImageView>(Resource.Id.imageView2);
            Koush.UrlImageViewHelper.SetUrlDrawable (imagen, "http://www.mymentor.org.za/"+items [position].pImage);

            TextView desc = view.FindViewById<TextView> (Resource.Id.textView3);
            desc.Text = Html.FromHtml (items [position].pDesc).ToString();

            TextView comlike = view.FindViewById<TextView> (Resource.Id.textView4);
            comlike.Text = "Likes: "+items [position].likecnumrows+"    Comments: "+items [position].commentscnumrows;

            return view;
        }

        void Prof_Click (object sender, EventArgs e)
        {
            Toast.MakeText(context, "Position: "+realpos, ToastLength.Long).Show();
        }

        public class ServiceViewHolder : Java.Lang.Object
        {
            public ImageButton like { get; set; }
            public ImageButton comment { get; set; }
            public ImageButton share { get; set; }
            public ImageView prof { get; set; }
            public TextView usrname { get; set; }
        }
    }
}

下面是控制台输出,显示我一直在运行的测试

下面有很多控制台数据,所以应该重点关注 - 查看否如果 -View == Null -Realpos - 位

如果您需要,请告诉我

View No If: 0
View == Null: 0
[art] JNI RegisterNativeMethods: attempt to register 0 native methods for md5c2cbda97c60838cc1822f8363c96ec60.dashboardAdapter_ServiceViewHolder
View No If: 1
View == Null: 1
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isShipBuild true
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isShipBuild true
[System.out] (HTTPLog)-Thread-43421-535359947: SmartBonding Enabling is false, SHIP_BUILD is true, log to file is false, DBG is false
[System.out] (HTTPLog)-Thread-43421-535359947: SMARTBONDING_FEATURE_ENABLED is true
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Thread-43420-520578202: SmartBonding Enabling is false, SHIP_BUILD is true, log to file is false, DBG is false
[System.out] (HTTPLog)-Thread-43420-520578202: SMARTBONDING_FEATURE_ENABLED is true
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
View No If: 2
View == Null: 2
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[ListView] change accessibility focus position = 0
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
Realpos: 2       Position: 0
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
Realpos: 2       Position: 1
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 2
View Not Null: 2
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
Realpos: 2       Position: 2
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 3
View Not Null: 3
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
Realpos: 3       Position: 0
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 4
View Not Null: 4
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
Realpos: 4       Position: 2
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 2
View Not Null: 2
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 1
View Not Null: 1
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
Realpos: 1       Position: 2
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 0
View Not Null: 0
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
Realpos: 0       Position: 1
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 2
View Not Null: 2
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 3
View Not Null: 3
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 4
View Not Null: 4
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
Realpos: 4       Position: 2
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 2
View Not Null: 2
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] KnoxVpnUidStorageknoxVpnSupported API value returned is false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 1
View Not Null: 1
[ViewRootImpl] ViewPostImeInputStage ACTION_DOWN
View No If: 0
View Not Null: 0
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[System.out] (HTTPLog)-Static: isSBSettingEnabled false
[skia] --- SkImageDecoder::Factory returned null
[skia] --- SkImageDecoder::Factory returned null

2 个答案:

答案 0 :(得分:2)

现在我明白你的意思!这个发生,因为我们重复使用行(是的,这样可以保存您的视图并且不会一次又一次地重新创建)。这部分代码存在问题:

if (view == null)

要解决此问题,您必须删除此代码块(其中view为null),之后就可以了,但是您将失去一些性能!(不要认为您有1000个列表项:),因为没有这个帖子条件方法 GetView()将重新绘制当前时刻可见的 ROW 。)
所以在你的情况下,我认为它可以做到。

让我们尝试示例,看看相同的东西(与Toast):
Main.axml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:id="@+id/editText1" />
        <ListView
            android:minWidth="25px"
            android:minHeight="25px"
            android:layout_width="match_parent"
            android:layout_height="460dp"
            android:id="@+id/lst"
            android:layout_marginTop="50dp" />
        <Button
            android:text="Button"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:id="@+id/Test"
            android:layout_alignParentBottom="true" />
    </RelativeLayout>
</LinearLayout>  

MainActivity

 [Activity(Label = "TestStuff", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {

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

            SetContentView(Resource.Layout.Main);
            Window.SetSoftInputMode(SoftInput.AdjustNothing | SoftInput.AdjustPan);
            ListView lst = FindViewById<ListView>(Resource.Id.lst);
            Button btn = FindViewById<Button>(Resource.Id.Test);

            List<string> Data = new List<string>();
            Data.Add("Prosto GG 1");
            Data.Add("Prosto GG 2");
            Data.Add("Prosto GG 3");
            Data.Add("Prosto GG 4");
            Data.Add("Prosto GG 5");
            Data.Add("Prosto GG 6");
            Data.Add("Prosto GG 7");
            Data.Add("Prosto GG 8");
            Data.Add("Prosto GG 9");
            Data.Add("Prosto GG 10");
            Data.Add("Prosto GG 11");

            CustomAdapter cst = new CustomAdapter(Data, this);
            lst.Adapter = cst;

            btn.Click += (sender, e) => 
                {
                    Data.Add("ne prosto");
                    cst.NotifyDataSetChanged();
                };


        }
    }  

最后,我们的新 CustomAdapter (没有View代码块== null)

class CustomAdapter: BaseAdapter<string>
    {

    List<string> _Items;
    Context _context;
    public CustomAdapter(List<string> Items,Context context)
    {
        this._Items = Items;
        this._context = context;
    }


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

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

            var view = convertView;

                holder = new ServiceViewHolder();
                view = LayoutInflater.From(_context).Inflate(Resource.Layout.ListItem, null);
                holder.Txt = view.FindViewById<TextView>(Resource.Id.txt);
                holder.PushME = view.FindViewById<Button>(Resource.Id.Push);
                holder.PushME.Click += (sender, e) => 
                    {

                        Toast.MakeText (_context, _Items [position] + " SHOWED", ToastLength.Short).Show ();
                        //holder.Txt.Text = holder.Txt.Text + "Izmenen najatiem" + position + " poziitii";
                    }

             holder.Txt.Text = _Items[position];

 return view;
  }  



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

    public override string this[int index]
    {
        get
        {
           return _Items[index];
        }
    }
    #endregion

}

public class ServiceViewHolder : Java.Lang.Object
{
    public Button PushME { get; set; }

    public TextView Txt { get; set; }

}

这样吧! 请享用!

PS我还想说,要注意大尺寸数据(例如列表中的500-1000项)。

PPS但说实话,没有必要将ListView与大项Data一起使用,因为它非常昂贵,为此可以使用RecycleView;)!

答案 1 :(得分:0)

如果您的问题是关于Position和Realpos之间的区别,原因是Realpos是一个类成员,您在每次调用GetView时都设置

例如,假设您滚动列表,每个新项目都会更新此变量并且所有项目都共享它,因此即使您单击索引的项目为0,添加的最后一个视图也是索引2并更新了此变量。