Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xamarin,ListView和RecyclerView,单击一个项目,选择另一个项目_Xamarin_Android Recyclerview_Onitemclick - Fatal编程技术网

Xamarin,ListView和RecyclerView,单击一个项目,选择另一个项目

Xamarin,ListView和RecyclerView,单击一个项目,选择另一个项目,xamarin,android-recyclerview,onitemclick,Xamarin,Android Recyclerview,Onitemclick,我在列表视图和回收视图 最初,我创建了一个列表视图,一切正常。然后我为它设置了onClick事件,这样每当我单击一个项目时,它的颜色都会变为黄色。我在main活动中编写的OnClick函数。问题是,当我测试时,不仅那个项目改变了它的颜色,还有两个项目也改变了。我读到这是因为我重用了视图 所以我改变了策略,改用RecyclerView,但同样的问题也发生了。当我单击一个项目以更改其颜色时,下面的另一个项目也会更改。我想这是因为ListView和RecyclerView都重复使用了这些项目,所以当我

我在
列表视图
回收视图

最初,我创建了一个
列表视图
,一切正常。然后我为它设置了
onClick
事件,这样每当我单击一个项目时,它的颜色都会变为黄色。我在
main活动中编写的
OnClick
函数。问题是,当我测试时,不仅那个项目改变了它的颜色,还有两个项目也改变了。我读到这是因为我重用了视图

所以我改变了策略,改用
RecyclerView
,但同样的问题也发生了。当我单击一个项目以更改其颜色时,下面的另一个项目也会更改。我想这是因为
ListView
RecyclerView
都重复使用了这些项目,所以当我单击其中一个时,它们会混淆

我不知道如何解决这个问题,我发现一个解决方案是添加一个
boolean
数组,该数组标记单击的项目,但它不起作用。有什么想法吗,伙计们

这是代码 主要活动

class main活动:活动
{
公共回收视图回收视图;
公共RecyclerView.LayoutManager;
公共RecyclerView.适配器;
列表lst;
创建时受保护的覆盖无效(捆绑包)
{
base.OnCreate(bundle);
//从“主”布局资源设置视图
SetContentView(Resource.Layout.Main);
init();
recyclerView=(recyclerView)FindViewById(Resource.Id.recyclerView);
经理=新的LinearLayoutManager(本);
recyclerView.SetLayoutManager(管理器);
CustomAdapter=新的CustomAdapter(lst,this);
adapter.ItemClick+=onItemClick;
recyclerView.SetAdapter(适配器);
}
公共void init()
{
lst=新列表();
对于(int i=0;i<15;i++)
{
Row Row=新行(){field1=“1:43:00”,field2=“09-Apr-16”,field3=“KPI/Overflow”,field4=“Kevin Bacon”,field5=“无人”,field6=“人员计数@IPCAM-ID-C-1-1”};
第一次添加(行);
}
}
public void onItemClick(对象发送器,int位置)
{
int itemPos=位置+1;
//Toast.MakeText(this,“this is”+itemPos,ToastLength.Short).Show();
recyclerView.GetChildAt(position.SetBackgroundColor(Android.Graphics.Color.Green);
}
}
自定义适配器

公共类CustomAdapter:RecyclerView.Adapter { 公共活动;; 公共列表lst; 公共事件事件处理程序项单击; 公共CustomAdapter(列表lst,活动) { 这是1.lst=lst; 这个。_活动=活动; } 公共覆盖int ItemCount { 得到 { 返回一次计数; } } 公共void OnClick(内部位置) { 如果(ItemClick!=null) { 项目点击(此,位置); } } 公共覆盖无效OnBindViewHolder(RecyclerView.ViewHolder,int位置) { MyViewHolder myholder=作为MyViewHolder的持有人; myholder.textView1.Text=lst[position].field1; myholder.textView2.Text=lst[position].field2; myholder.textView3.Text=lst[position].field3; myholder.textView4.Text=lst[position].field4; myholder.textView5.Text=lst[position].field5; myholder.textView6.Text=lst[position].field6; } public override RecyclerView.ViewHolder OnCreateViewHolder(视图组父级,int-viewType) { 视图v=此._活动.LayoutInflater.充气(Resource.Layout.item,父项,false); TextView tv1=(TextView)v.FindViewById(Resource.Id.textView1); TextView tv2=(TextView)v.FindViewById(Resource.Id.textView2); TextView tv3=(TextView)v.FindViewById(Resource.Id.textView3); TextView tv4=(TextView)v.FindViewById(Resource.Id.textView4); TextView tv5=(TextView)v.FindViewById(Resource.Id.textView5); TextView tv6=(TextView)v.FindViewById(Resource.Id.textView6); MyViewHolder=new MyViewHolder(v,OnClick){textView1=tv1,textView2=tv2,textView3=tv3,textView4=tv4,textView5=tv5,textView6=tv6}; 报税表持有人; } } 类MyViewHolder:RecyclerView.ViewHolder { 公共文本视图文本视图1、文本视图2、文本视图3、文本视图4、文本视图5、文本视图6; 公众观点; 公共MyViewHolder(视图、操作侦听器):基本(视图) { 主视图=视图; mainView.Click+=(发送者,e)=>listener(基本位置); } }
我遵循了
Xamarin站点上的
OnClic
k处理程序的示例
您的问题在于代码。您将正确的位置发送给事件处理程序,但随后在“活动”中将其递增1。两端应使用基于0的项目位置索引。没有必要增加1

要更改所选项目的背景色,可以使用XML中的选择器,这样就不需要在代码中执行此操作

这里有一个例子

行选择器.xml


row_content.axml


然后您的视图持有者将更新到此

class MyViewHolder : RecyclerView.ViewHolder
{
    public TextView textView1, textView2, textView3, textView4, textView5, textView6;
    public View mainView;
    private LinearLayout _layoutParent;

    public MyViewHolder(View view, Action<int> listener) : base(view)
    {
        mainView = view;
        _layoutParent = mainView.FindViewById<LinearLayout>(Resource.Id.row_layout_parent);
        _layoutParent.Click += (sender, e) => _layoutParent.Selected = true;
    }
}
类MyViewHolder:RecyclerView.ViewHolder
{
公共文本视图文本视图1、文本视图2、文本视图3、文本视图4、文本视图5、文本视图6;
公众观点;
私人线路布局-布局母公司;
公共MyViewHolder(视图、操作侦听器):基本(视图)
{
主视图=视图;
_layoutParent=mainView.FindViewById(Resource.Id.row\u layout\u parent);
_放置
public class CustomAdapter : RecyclerView.Adapter
    {
        public Activity _activity;
        public List<Row> lst;
        public event EventHandler<int> ItemClick;

        public CustomAdapter(List<Row> lst, Activity activity)
        {
            this.lst = lst;
            this._activity = activity;
        }

        public override int ItemCount
        {
            get
            {
                return lst.Count;
            }
        }

        public void OnClick(int position)
        {
            if (ItemClick!=null)
            {
                ItemClick(this, position);
            }
        }

        public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            MyViewHolder myholder = holder as MyViewHolder;

            myholder.textView1.Text = lst[position].field1;
            myholder.textView2.Text = lst[position].field2;
            myholder.textView3.Text = lst[position].field3;
            myholder.textView4.Text = lst[position].field4;
            myholder.textView5.Text = lst[position].field5;
            myholder.textView6.Text = lst[position].field6;


        }

        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {
            View v = this._activity.LayoutInflater.Inflate(Resource.Layout.item, parent, false);

            TextView tv1 = (TextView)v.FindViewById(Resource.Id.textView1);
            TextView tv2 = (TextView)v.FindViewById(Resource.Id.textView2);
            TextView tv3 = (TextView)v.FindViewById(Resource.Id.textView3);
            TextView tv4 = (TextView)v.FindViewById(Resource.Id.textView4);
            TextView tv5 = (TextView)v.FindViewById(Resource.Id.textView5);
            TextView tv6 = (TextView)v.FindViewById(Resource.Id.textView6);

            MyViewHolder holder = new MyViewHolder(v, OnClick) { textView1 = tv1, textView2 = tv2, textView3 = tv3, textView4 = tv4, textView5 = tv5, textView6 = tv6 };
            return holder;
        }
    }

    class MyViewHolder : RecyclerView.ViewHolder
    {
        public TextView textView1, textView2, textView3, textView4, textView5, textView6;
        public View mainView;

        public MyViewHolder(View view, Action<int> listener) : base(view)
        {
            mainView = view;
            mainView.Click += (sender, e) => listener(base.Position);
        }
    }
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:color="@android:color/green" />
    <item android:state_selected="false" android:color="@android:color/transparent"/>
</selector>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/row_layout_parent"
    android:background="@drawable/row_selector">

    <!-- your row content -->

</LinearLayout>
class MyViewHolder : RecyclerView.ViewHolder
{
    public TextView textView1, textView2, textView3, textView4, textView5, textView6;
    public View mainView;
    private LinearLayout _layoutParent;

    public MyViewHolder(View view, Action<int> listener) : base(view)
    {
        mainView = view;
        _layoutParent = mainView.FindViewById<LinearLayout>(Resource.Id.row_layout_parent);
        _layoutParent.Click += (sender, e) => _layoutParent.Selected = true;
    }
}
listView.ChoiceMode = ChoiceMode.Single;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Support.V7.Widget;
using Android.Text;
using Android.Text.Style;
using Android.Util;
using Android.Views;
using Android.Widget;
using Java.Util.Zip;
using ActionMenuView = Android.Support.V7.Widget.ActionMenuView;

namespace Android.Basic.Core
{
    public class GenericRecyclerViewAdapter<T> : RecyclerView.Adapter
    {
        /// <summary>
        /// You can set this for different custom cardview
        /// </summary>
        private int CardViewResourceLayout { get; set; }
        public ObservableCollection<T> Items { get; private set; }
        public  event EventHandler<RecyclerViewViewHolder> ItemViewTemplated;
        public RecyclerView.LayoutManager layoutManager;
        public GenericRecyclerViewAdapter(RecyclerView recyclerView, IEnumerable<T> items, int cardViewResourceLayout, bool isList = true, bool isVertical = true) : base()
        {
            
            if(isList)
            {
                var vertical = isVertical ? LinearLayoutManager.Vertical : LinearLayoutManager.Horizontal;
                layoutManager = new LinearLayoutManager(recyclerView.Context, vertical, false);
            }
            else
            {
                var vertical = isVertical ? GridLayoutManager.Vertical : GridLayoutManager.Horizontal;
                layoutManager = new GridLayoutManager(recyclerView.Context, 3, vertical, false);
            }
            recyclerView.SetLayoutManager(layoutManager);
            this.Items = new ObservableCollection<T>(items);
            this.CardViewResourceLayout = cardViewResourceLayout;
            this.Items.CollectionChanged += delegate
            {
                this.NotifyDataSetChanged();
            };
           
        }
        
        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {
            var itemView = LayoutInflater.From(parent.Context).Inflate(CardViewResourceLayout, parent, false);
#if DEBUG
            Log.Info("GenericRecyclerViewAdapter - ", CardViewResourceLayout.ToString());
#endif
            RecyclerViewViewHolder vh = new RecyclerViewViewHolder(itemView);
            return vh;
        }        
        
        public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            RecyclerViewViewHolder vh = holder as RecyclerViewViewHolder;
            vh.ItemPosition = position;
            vh.TemplateView.Tag = position;
            vh.TemplateView.Click -= TemplateView_Click;
            vh.TemplateView.Click += TemplateView_Click;
            ItemViewTemplated?.Invoke(this, vh);
        }
        public event EventHandler<T> ItemClicked;
     
        private void TemplateView_Click(object sender, EventArgs e)
        {
            var position = (int)((View)sender).Tag;
            this.ItemClicked?.Invoke(sender, this.Items[position]);
          
        }

        public override int ItemCount
        {
            get { return this.Items.Count; }
        }
        public override long GetItemId(int position)
        {
            return base.GetItemId(position);
        }

    }

    public class RecyclerViewViewHolder : RecyclerView.ViewHolder, View.IOnCreateContextMenuListener,
        IMenuItemOnMenuItemClickListener
    {
        public View TemplateView { get; private set; }
        public int ItemPosition { get;  set; }
        public event EventHandler<MenuInfo> ContextMenuCreated;
        public event EventHandler<object> MenuItemClicked;
        public MenuInfo MenuInfo { get; private set; }
        public object Data { get; set; }
        public RecyclerViewViewHolder(View itemView) : base(itemView)
        {
            // Locate and cache view references:
            this.TemplateView = itemView;
            this.TemplateView.SetOnCreateContextMenuListener(this);
           
        }

        public void OnCreateContextMenu(IContextMenu menu, View v, IContextMenuContextMenuInfo menuInfo)
        {
            MenuInfo = new MenuInfo(menu, v, menuInfo);
            ContextMenuCreated?.Invoke(this, MenuInfo);

        }
        private Android.Views.MenuInflater menuInflater = null;
        /// <summary>
        /// After ContextMenuCreated 
        /// </summary>
        /// <param name="resourcemenu"></param>
        public void InflateMenu(int resourcemenu, SpannableString titleColor = null, object dta = null)
        {
            if (dta != null)
                this.Data = dta;
            if (this.TemplateView.Context is AppCompatActivity activity)
            {
                menuInflater = activity.MenuInflater;

            }
            else if (this.TemplateView.Context is Activity activity2)
            {
                menuInflater = activity2.MenuInflater;
            }
            var contextMenu = this.MenuInfo.ContextMenu;
            contextMenu.Clear();
            menuInflater.Inflate(resourcemenu, contextMenu);
            var num = contextMenu.Size() - 1;
            for (int i = 0; i <= num; i++)
            {
                var men = contextMenu.GetItem(i);
                if(titleColor != null)
                {
                    if (i == 0)
                    {                       
                        men.SetTitle(titleColor);
                        men.SetChecked(true);
                    }
                }
                if (i != 0)
                {
                    men.SetOnMenuItemClickListener(this);
                }

            }
        }
        
        public bool OnMenuItemClick(IMenuItem item)
        {
            this.MenuItemClicked?.Invoke(item, this.Data);
            return true;
        }

        public float PosX;
        public float PosY;
        
    }
    
    public class MenuInfo
    {
        public IContextMenu ContextMenu { get; }
        public View View { get; }
        public IContextMenuContextMenuInfo ContextMenuInfo { get; }
        public MenuInfo(IContextMenu contextMenu, View view, IContextMenuContextMenuInfo menuInfo)
        {
            this.ContextMenu = contextMenu;
            this.View = view;
            this.ContextMenuInfo = menuInfo;
        }
    }
}
  RecyclerView recyclerView = new RecyclerView(this);
                    var viewAdapter = new Android.Basic.Core.GenericRecyclerViewAdapter<Java.IO.File>(recyclerView, files, Resource.Layout.directory_item);
                    var indiColor = ThemeHelper.IsDark ? ColorHelper.GetRandomLightColor() : ColorHelper.GetRandomDarkColor();
                    viewAdapter.ItemViewTemplated += (dd, holder) =>
                    {
                        var file = files[holder.ItemPosition];
                        var view = holder.ItemView;
                        var expanded = view.FindViewById<ExpandedView>(Resource.Id.expandedView);
                        expanded.SetToggleColor(indiColor);
                        expanded.SetTitle(file.Name);
                        GenerateRecycler(expanded, file);
                        
                    };
                    recyclerView.SetAdapter(viewAdapter);
                    expandedView.AddExpandedView(recyclerView);