2016-04-10 35 views
2

我有既ListViewRecyclerViewXamarin,无论ListView和RecyclerView,单击一个项目,一个又一个选择

麻烦起初,我创建了一个ListView,一切都很好。然后,我为其设置onClick事件,以便每次单击某个项目时,都会将其颜色更改为黄色。 OnClick函数我写在MainActivity。问题是,当我测试时,不仅该项目改变其颜色,而且2项改变。我读到这是因为我重用了视图。

因此,我切换我的策略,使用RecyclerView,而不是相同的问题发生。当我点击一个项目来改变它的颜色时,下面的另一个项目也会改变。我想这是因为ListViewRecyclerView重用这些项目,所以他们混淆,当我点击一个。

我不知道如何解决这个问题,我发现一个解决方案是添加一个boolean的数组,它标记哪个项目被点击但它不起作用。任何想法的家伙?

所以这里是代码 MainActivity

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 site https://developer.xamarin.com/guides/android/user_interface/recyclerview/

OnClicķ处理程序的例子
+0

如果你分享你到目前为止做了什么,以便其他人可以帮助你 – Pooya

+0

由于这是更好,我添加的代码 – LaXuanLinh

+0

也请分享你的recyclerview XML item – Pooya

回答

2

您的问题与您的代码。您将正确的位置发送给您的事件处理程序,但在活动中将其增加一。两端应使用项目位置的从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> 

那么你的观点持有者将被更新以这个...

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; 
    } 
} 

我删除了其他点击e发泄。如果您仍然因为其他原因需要它,则可以将其添加回去,但选择时仅设置项目背景颜色并不是必需的。

+0

感谢您的回复,我以前从来没有听说过XML选择器,所以我只是单击事件处理程序。其实我需要改变项目视图,当它被点击,我还没有找到如何去做,我尝试setBackgroundResource和Inflater在处理程序,但没有工作。所以我认为只要每次点击时改变它的颜色就可以首先测试项目点击事件。你有没有关于使用选择器改变项目视图的例子? – LaXuanLinh

+0

我的代码应该可以工作。 'row_selector.xml'文件应该位于'drawable'目录下。 –

0

对于Listview,您应该如下设置choiceMode。

listView.ChoiceMode = ChoiceMode.Single; 

希望它可以帮助你:) -

相关问题