我在使用 ListView
和 RecyclerView
时都遇到问题
最初,我创建了一个ListView
,一切都很好。然后我为其设置了 onClick
事件,以便每次单击某个项目时,它都会将其颜色更改为黄色。我在MainActivity
中编写的OnClick
函数。问题是,当我测试时,不仅该项目改变了颜色,而且 2 个项目也发生了变化。我读到这是因为我重用了 View 。
所以我改变策略,使用 RecyclerView
代替,但出现了同样的问题。当我单击一个项目来更改其颜色时,下面的另一个项目也会发生变化。我猜这是因为 ListView
和 RecyclerView
都重用了这些 Item,所以当我单击其中一个时,它们会感到困惑。
我不知道如何解决这个问题,我发现一个解决方案是添加一个 boolean
数组来标记哪个项目被单击,但它不起作用。大家有什么想法吗?
所以这是代码 主要事件
class MainActivity : Activity
{
public RecyclerView recyclerView;
public RecyclerView.LayoutManager manager;
public RecyclerView.Adapter adapter;
List<Row> lst;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
init();
recyclerView = (RecyclerView)FindViewById(Resource.Id.recyclerView);
manager = new LinearLayoutManager(this);
recyclerView.SetLayoutManager(manager);
CustomAdapter adapter = new CustomAdapter(lst, this);
adapter.ItemClick += onItemClick;
recyclerView.SetAdapter(adapter);
}
public void init()
{
lst = new List<Row>();
for (int i = 0; i < 15; i++)
{
Row row = new Row() { field1="1:43:00", field2="09-Apr-16", field3="KPI/Overflow", field4="Kevin Bacon", field5="Unowned", field6= "People Counting @ IPCAM-ID-C-1-1" };
lst.Add(row);
}
}
public void onItemClick(object sender, int position)
{
int itemPos = position + 1;
//Toast.MakeText(this, "this is " + itemPos, ToastLength.Short).Show();
recyclerView.GetChildAt(position).SetBackgroundColor(Android.Graphics.Color.Green);
}
}
自定义适配器
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);
}
}
我按照 Xamarin 站点
上的 OnClic
k 处理程序示例进行操作
https://developer.xamarin.com/guides/android/user_interface/recyclerview/
最佳答案
您的问题出在您的代码上。您将正确的位置发送到事件处理程序,然后在事件中将其加一。两端都应使用项目位置的从 0 开始的索引。无需加一。
要更改所选项目的背景颜色,您可以使用 XML 中的选择器,这样您甚至不需要在代码中执行此操作。
这是一个示例。
row_selector.xml
<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>
row_content.axml
<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>
然后您的 View 持有者将更新为此...
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;
}
}
我删除了其他点击事件。如果您由于其他原因仍然需要它,那么您可以将其添加回来,但仅在选择时设置项目背景颜色是不必要的。
关于Xamarin,ListView和RecyclerView,单击一项,选择另一项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36525852/