2017-09-25 4 views
3

Je travaille dans Xamarin Android. J'ai mis en place une vue recycleur avec la liste des patients. J'ai également mis en place une vue de recherche pour filtrer la liste des patients recherchés. J'ai un événement de clic de bouton dans le OnBindViewHolder qui est appelé plusieurs fois, chaque fois que j'implémente une recherche que la liste est mise à jour. Si je ne filtre pas les patients, le bouton n'est initialisé qu'une seule fois donc je n'ai aucun problème à cela. Mais si j'effectue un filtre de recherche, le bouton s'initialise à nouveau et à chaque fois que je clique sur un bouton, je passe plusieurs fois dans une autre activité "NewActivity". Comment puis-je resoudre ceci? Le "populateRecyclerView" sera appelé après l'exécution d'une requête que je n'ai pas mentionnée ici.Android Bouton Click L'événement est déclenché plusieurs fois lors de l'implémentation d'une vue recycleur avec filtre de recherche?

Mes 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(); 
    } 

Répondre

2

Sur votre Bind vous avez configuré votre clic de cette façon. ce paramètre est réglé seulement cliquer

afin de changer ce code

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

à cette

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

EDIT:

changer votre code parce que le problème est dans votre position. vous devez régler la position de l'adaptateur qui donnera la position correcte du bouton clic voir ci-dessous le code.

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

Bonjour @Ironman, j'ai essayé votre réponse, mais ce qui se passe est que, j'ai trois patients andy, bernie, James et quand je recherche pour James et cliquez sur le bouton checkin, le patient sélectionné devient andy –

+0

@ Amod voir ma réponse de mise à jour. – Ironman

+0

Bonjour @Ironman même problème, je pense que l'événement btncheckin prend le nom du premier patient et y rester, et quand je déclenche l'événement de clic, le nom du premier patient est passé au patient sélectionné –