【问题标题】:Selected item is changing on scrolling所选项目在滚动时发生变化
【发布时间】:2018-10-29 05:56:22
【问题描述】:

我有一个子布局和父布局,如下所示。我需要在子布局中选择多个项目。我可以选择多个项目,但面临两个问题。 1.滚动选择的项目正在改变。 2.当我选择第一行的项目时,第4行的项目也在选择中。

这是我的代码。

父布局:

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:id="@+id/formsheader">
        <include
            android:id="@+id/formToolbar"
            layout="@layout/toolbar" />
    </RelativeLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="#e9e7e9"
        android:layout_above="@+id/formsfooter"
        android:layout_below="@+id/formsheader"
        android:id="@+id/teamFormsContent">
        <GridView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:columnWidth="137dp"
            android:numColumns="auto_fit"
            android:verticalSpacing="20dp"
            android:horizontalSpacing="20dp"
            android:stretchMode="columnWidth"
            android:layout_marginLeft="23dp"
            android:layout_marginRight="23dp"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:scrollbars="none"
            android:id="@+id/form_gridView" />
    </RelativeLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:id="@+id/formsfooter"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:background="#051b2e">
        <TextView
            android:id="@+id/idletext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Idle"
            android:textColor="#47b8fd"
            android:textSize="15dp"
            android:textAppearance="?android:attr/textAppearanceMedium" />
        <TextView
            android:id="@+id/tapToViewText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Tap to view"
            android:textColor="#ffffff"
            android:textSize="15dp"
            android:layout_marginLeft="20dp"
            android:layout_toRightOf="@+id/idletext"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </RelativeLayout>
</RelativeLayout>

child_layout:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <LinearLayout
        android:id="@+id/form_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_gravity="center"
        android:background="@android:color/white"
        android:orientation="vertical">
        <LinearLayout
            android:id="@+id/form_view_layout"
            android:layout_width="137dp"
            android:layout_height="178dp"
            android:orientation="vertical"
            android:layout_marginTop="3dp"
            android:layout_marginBottom="3dp"
            android:layout_marginLeft="3dp"
            android:layout_marginRight="3dp"
            android:layout_gravity="center"
            android:weightSum="100"
            android:background="@android:color/white">
            <ImageView
                android:src="@drawable/image1"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="72"
                android:layout_gravity="center"
                android:id="@+id/form_Image" />
            <TextView
                android:text="sometext"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:textColor="#00ccff"
                android:textSize="12dp"
                android:layout_marginLeft="10dp"
                android:layout_marginBottom="5dp"
                android:layout_weight="18"
                android:id="@+id/heading" />
            <TextView
                android:text="sometext"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:textSize="12dp"
                android:layout_weight="10"
                android:layout_marginBottom="10dp"
                android:textColor="@android:color/black"
                android:layout_marginLeft="10dp"
                android:id="@+id/subHeading1" />
        </LinearLayout>
    </LinearLayout>
    <TextView
        android:text="sometext"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black"
        android:textSize="13dp"
        android:layout_below="@+id/form_view_layout"
        android:layout_marginTop="10dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:id="@+id/subHeading2" />
    <TextView
        android:text="14/01/1997 5:00"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#696969"
        android:textSize="13dp"
        android:layout_below="@+id/subHeading2"
        android:layout_marginTop="7dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:id="@+id/formupdateddatetime" />
</LinearLayout>

活动和适配器代码:

namespace FormSample.Activities
{
    [Activity(Label = "FormsActivity")]
    public class FormsActivity : BaseActivity
    {

        protected override int Layout => Resource.Layout.Forms;

        private FormModel _formModel;

        List<Form> formsList = new List<Form>();

        List<Form> formsListToDelete = new List<Form>();

        private bool _isMultiSelect;

        public override void OnBackPressed()
        {
            FinishAffinity();
        }

        public static Intent NewIntent(Context context)
        {
            try
            {

                var intent = new Intent(context, typeof(FormsActivity));           

                return intent;
            }
            catch (Exception exception)
            {

                return null;
            }
        }


        protected async override void FindViewElements()
        {
            try
            {


                _formModel = new FormModel()
                {
                    Form = FindViewById<GridView>(Resource.Id.form_gridView),
                    FormToolbar = FindViewById<Toolbar>(Resource.Id.formToolbar)
                };

                formsList = new List<Form>();

                var teamForms = new List<Form>();

                List<TeamlistResponse> _fromsListFromLocal = await LocalService.Instance.GetFormsCreatedInLocal();

                foreach (var form in _fromsListFromLocal)
                {
                    var localForm = ConvertTeamsListDtoToForm(form);

                    formsList.Add(localForm);
                }

                formsList = formsList.OrderByDescending(x => x.modified_timestamp).ToList();

                InitializeScreen();

                LoggingManager.Exit("MethodName:FindViewElements And ActivityName:FormsActivity");
            }
            catch (Exception exception)
            {
                LoggingManager.Error(exception, "FindViewElements", "FormsActivity");
            }
        }

        public void InitializeScreen()
        {
            try
            {
                LoggingManager.Enter("MethodName:InitializeScreen And ActivityName:FormsActivity");
                SetSupportActionBar(_formModel.FormToolbar);              
                GetListOfForms();
                LoggingManager.Exit("MethodName:InitializeScreen And ActivityName:FormsActivity");
            }
            catch (Exception exception)
            {
                LoggingManager.Error(exception, "InitializeScreen", "FormsActivity");
            }
        }

        private void GetListOfForms()
        {

              _formModel.Form.ItemClick += Form_Click;

              _formModel.Form.Adapter = new FormAdapter(formsList, this);

        }


        private async void Form_Click(Object sender, AdapterView.ItemClickEventArgs e)
        {
            try
            {


                    var selectedItem = formsList[e.Position];

                    if (selectedItem.Caption != "New Form" && selectedItem.id != null)
                    {
                        View selectedForm = e.View;
                        LinearLayout selectedFormLayout = selectedForm.FindViewById<LinearLayout>(Resource.Id.form_layout);
                        if (selectedItem.IsSelected)
                        {
                            selectedItem.IsSelected = false;                           
                            selectedFormLayout.SetBackgroundColor(Color.White);
                            formsListToDelete.Remove(selectedItem);
                        }
                        else
                        {
                            selectedItem.IsSelected = true;                           
                            selectedFormLayout.SetBackgroundResource(Resource.Drawable.Form_Border);
                            formsListToDelete.Add(selectedItem);
                        }
                    }

            }
            catch (Exception exception)
            {

            }
        }

    }

    public class Form
    {
        private bool _isSelected;


        public byte[] ImageResourceId { get; set; }

        public string Heading { get; set; }

        public string SubHeading { get; set; }

        public string Caption { get; set; }

        public string UpdatedFormDate { get; set; }

        public string id { get; set; }

        public bool IsSelected
        {

            get { return _isSelected; }
            set
            {
                _isSelected = value;
            }
        }

    }

    public class FormAdapter : BaseAdapter<Form>
    {
        private List<Form> formItems;

        private Activity context;

        public override Form this[int position]
        {
            get
            {
                return formItems[position];
            }
        }

        public override int Count => formItems.Count;

        public FormAdapter(List<Form> forms, Activity context) : base()
        {
            try
            {
                LoggingManager.Enter("ConstructorName:FormAdapter And ActivityName:FormsActivity");
                this.context = context;
                formItems = forms;
                LoggingManager.Exit("ConstructorName:FormAdapter And ActivityName:FormsActivity");
            }
            catch (Exception exception)
            {
                LoggingManager.Error(exception, "FormAdapter", "FormAdapter", "FormsActivity");
            }
        }

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

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

            }
            catch (Exception exception)
            {              
                return 0;
            }
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            try
            {

                var form = formItems[position];
                View view = convertView;
                if (view == null)
                    view = context.LayoutInflater.Inflate(Resource.Layout.Forms_ChildLayout, null);

                var imageBitMap = BitmapFactory.DecodeByteArray(form.ImageResourceId, 0, form.ImageResourceId.Length);
                view.FindViewById<ImageView>(Resource.Id.form_Image).SetImageBitmap(imageBitMap);
                view.FindViewById<TextView>(Resource.Id.heading).Text = form.Heading;
                view.FindViewById<TextView>(Resource.Id.subHeading1).Text = form.SubHeading;
                view.FindViewById<TextView>(Resource.Id.subHeading2).Text = form.Caption;
                view.FindViewById<TextView>(Resource.Id.formupdateddatetime).Text = form.UpdatedFormDate;

                return view;

            }
            catch (Exception exception)
            {
                LoggingManager.Error(exception, "GetView", "FormsActivity");
                return null;
            }
        }
    }
}

通过灼热,我开始知道必须使用 viewholder,但是作为 xamarin.android 的新手,我并不真正了解如何做到这一点。请帮忙解决这个问题。

【问题讨论】:

  • 这是因为一旦滚动就会调用 getview 方法,因此第一个项目选择也会选择项目 3
  • 感谢@G.hakim 的回复,请告诉我如何解决这个问题。

标签: android xamarin xamarin.android


【解决方案1】:

通过搜索我知道viewholder必须使用,但作为新手 xamarin.android 我真的不明白该怎么做

在这里,我正在尝试为您制作Holder 课程。可能对你有帮助

在同一个文件FormAdapter 中声明FormHolder 类,其中包含您在项目布局Forms_ChildLayout 中拥有的所有控件。

public class FormHolder : Java.Lang.Object
{
    public ImageView Form_Image { get; set; }
    public TextView Heading { get; set; }
    public TextView SubHeading1 { get; set; }
    public TextView SubHeading2 { get; set; }
    public TextView Formupdateddatetime { get; set; }
}

这将是您的FormAdapterGetView

public override View GetView(int position, View convertView, ViewGroup parent)
{
    var view = convertView;
    FormHolder holder = null;
    if (view != null)
    {
        holder = view.Tag as FormHolder;
    }
    if (holder == null)
    {
        holder = new FormHolder();
        view = context.LayoutInflater.Inflate(Resource.Layout.Forms_ChildLayout, parent, false);
        holder.Form_Image = (ImageView)view.FindViewById(Resource.Id.form_Image);
        holder.Heading = (TextView)view.FindViewById(Resource.Id.heading);
        holder.SubHeading1 = (TextView)view.FindViewById(Resource.Id.subHeading1);
        holder.SubHeading2 = (TextView)view.FindViewById(Resource.Id.subHeading2);
        holder.Formupdateddatetime = (TextView)view.FindViewById(Resource.Id.formupdateddatetime);

        holder.Form_Image.SetImageBitmap(imageBitMap);
        holder.Heading.Text= form.Heading;
        holder.SubHeading1.Text= form.SubHeading;
        holder.SubHeading2.Text = form.Caption;
        holder.Formupdateddatetime.Text = form.UpdatedFormDate;
    }
    return view;
}

【讨论】:

  • 这是这样做的方法,但还有另一种解决方案,那就是使用RecyclerView。我知道ListView 完成了很多与RecyclerView 非常相似的事情,但是使用RecyclerView 会强制您使用ViewHolder 模式,您将永远不会再遇到这个问题。并不是说您的解决方案是错误的,因为它绝对不是,但也有使用 RecyclerView 的解决方案 :-)
  • @Darwind - 我同意你的看法,在这种特殊情况下RecyclerView 会更准确。这不会在滚动时混淆项目并且比 ListView 更高级。
猜你喜欢
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
相关资源
最近更新 更多