Android按钮单击事件在使用搜索过滤器实现回收站视图时多次触发?

时间:2017-09-25 05:45:42

标签: android list events search android-recyclerview

我在Xamarin Android工作。我已经实施了一份包含患者名单的回收者视图。我还实施了一个搜索视图来过滤搜索到的患者列表。我在OnBindViewHolder中有一个按钮单击事件,每当我实现搜索时,随着列表的更新,它会被多次调用。如果我不过滤患者,按钮只会初始化一次,所以我没有问题。但是如果我执行搜索过滤器,按钮会一次又一次地初始化,所以每当我点击一个按钮时,我就会进入另一个活动" NewActivity"多次。我怎么解决这个问题? " populateRecyclerView"将在运行我未在此处提及的查询后调用。

  

My RecylerAdapter.cs

public class PatientRecyclerAdapter : RecyclerView.Adapter
{
    private Context context;
    private List<Patient> patientList, filteredPatientList;
    public event EventHandler<CheckInClickArgs> CheckInClicked;
    MyHolder myholder;

    public class CheckInClickArgs : EventArgs
    {
        public Patient selectedPatient { get; set; }
    }

    public PatientRecyclerAdapter(Context context, List<Patient> patientList)
    {
        this.context = context;
        this.patientList = patientList;
        this.filteredPatientList = patientList;
    }

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

    public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {
        myholder = (MyHolder)holder;
        Patient patient = filteredPatientList[position];
        myholder.tvPatientName.Text = patient.Fullname;
            myholder.btnCheckIn.Click += (sender, e) =>
            {
                if (CheckInClicked != null)
                {
                    CheckInClicked(this, new CheckInClickArgs { selectedPatient = patient });
                }       
        }

    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {
        View view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.layout_patientCardViewRecyler, parent, false);
        MyHolder holder = new MyHolder(view);
        return holder;
    }

    public void filter(string searchText)
    {
        searchText = searchText.ToLower();
        this.filteredPatientList = patientList.Where(x => x.Fullname.ToLower().Contains(searchText)).ToList();
    }
}

class MyHolder : RecyclerView.ViewHolder
{
    public TextView tvPatientName;
    public Button btnCheckIn;
    public MyHolder(View itemView) : base(itemView)
    {
        tvPatientName = itemView.FindViewById<TextView>(Resource.Id.textViewPatientName);
        btnCheckIn = itemView.FindViewById<Button>(Resource.Id.btnCheckIn);
    }
}
  

PatientsTabFragment.cs

public class PatientsTabFragment : Android.Support.V4.App.Fragment, ITextWatcher, TextView.IOnEditorActionListener
{
    private Android.Views.View view;
    private RecyclerView recyclerView;
    private RecyclerView.LayoutManager recyclerview_layoutmanager;
    private PatientRecyclerAdapter recyclerview_adapter;
    private EditText etSearchView;

    public override Android.Views.View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        view = inflater.Inflate(Resource.Layout.fragment_patients_tab, container, false);
        etSearchView = view.FindViewById<EditText>(Resource.Id.etSearchView);
        return view;
    }

   void populateRecyclerView(List<Patient> patient)
        {
        recyclerView = view.FindViewById<RecyclerView>(Resource.Id.recyclerViewPatient);
        recyclerview_layoutmanager = new LinearLayoutManager(this.Activity, LinearLayoutManager.Vertical, false);
        recyclerView.SetLayoutManager(recyclerview_layoutmanager);

        recyclerview_adapter = new PatientRecyclerAdapter(this.Activity, patient);
        recyclerView.SetAdapter(recyclerview_adapter);
        etSearchView.AddTextChangedListener(this);
        recyclerview_adapter.CheckInClicked += (sender, e) =>
        {
            AppController.SelectedPatient = e.selectedPatient;
            Activity.StartActivity(typeof(NewActivity));
        };
    }

    public void OnTextChanged(ICharSequence s, int start, int before, int count)
    {
        recyclerview_adapter.filter(s.ToString());
        recyclerview_adapter.NotifyDataSetChanged();
    }

1 个答案:

答案 0 :(得分:2)

在你的Bind上你已经设置了你的点击方式。这只是设置点击

所以改变你的代码

myholder.btnCheckIn.Click += (sender, e) =>
            {
                if (CheckInClicked != null)
                {
                    CheckInClicked(this, new CheckInClickArgs { selectedPatient = patient });
                }

到这个

if(!myholder.btnCheckIn.HasOnClickListeners)
{
        myholder.btnCheckIn.Click += (sender, e) =>
                {
                    if (CheckInClicked != null)
                    {
                        CheckInClicked(this, new CheckInClickArgs { selectedPatient = patient });
                    }
                }
}

编辑:

更改此代码,因为问题出在您的位置。你必须设置适配器位置,它将给出正确的按钮位置点击下面的代码。

myholder = (MyHolder)holder;
Patient patient = filteredPatientList[myholder.AdapterPosition];
myholder.tvPatientName.Text = patient.Fullname;