2016-11-22 103 views
2

在我簡單的adapater中,我想管理項目上的複選框。當我點擊複選框我改變狀態,當我在滾動的複選框狀態是假的,我不能修復我的代碼來解決此問題Android更改適配器上的複選框不能正常工作

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.CustomContactsViewHolder> { 
    private OnCardClickListener onCardClickListener; 
    private List<UserPhoneContacts> list = Collections.emptyList(); 
    private  Context   context; 
    private  Realm    realm; 
    public static OnSelectedContacts onSelectedContacts; 
    private Map<String, Boolean> checkBoxStates = new HashMap<>(); 

    public ContactsAdapter(List<UserPhoneContacts> list, Context context) { 
     this.list = list; 
     this.context = context; 
     this.realm = Realm.getDefaultInstance(); 
    } 

    @Override 
    public CustomContactsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View      v  = LayoutInflater.from(parent.getContext()).inflate(R.layout.contact_item, parent, false); 
     CustomContactsViewHolder holder = new CustomContactsViewHolder(v); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(final CustomContactsViewHolder holder, final int position) { 
     holder.contact_name.setText(list.get(position).getDisplayName()); 
     holder.contact_mobile.setText(list.get(position).getMobileNumber()); 

     Boolean checkedState = checkBoxStates.get(list.get(position).getMobileNumber()); 
     holder.select_contact.setChecked(checkedState == null ? false : checkedState); 
     holder.select_contact.setTag(position); 
     holder.select_contact.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       onChange((Integer) v.getTag()); 
      } 
     }); 
    } 

    private void onChange(int position) { 
     final UserPhoneContacts item = list.get(position); 
     if (item == null) { 
      return; 
     } 
     boolean checkedState = checkBoxStates.get(list.get(position).getMobileNumber()) != null; 
     checkBoxStates.put(item.getMobileNumber(), !checkedState); 
     notifyDataSetChanged(); 
    } 

    @Override 
    public int getItemCount() { 
     return list.size(); 
    } 

    @Override 
    public void onAttachedToRecyclerView(RecyclerView recyclerView) { 
     super.onAttachedToRecyclerView(recyclerView); 
    } 

    public void setData(List<UserPhoneContacts> list) { 
     this.list = list; 
    } 

    public static class CustomContactsViewHolder extends RecyclerView.ViewHolder { 
     @BindView(R.id.contact_name) 
     TextView contact_name; 

     @BindView(R.id.contact_mobile) 
     TextView contact_mobile; 

     @BindView(R.id.contact_photo) 
     CircleImageView contact_photo; 

     @BindView(R.id.select_contact) 
     CheckBox select_contact; 

     CustomContactsViewHolder(View view) { 
      super(view); 
      ButterKnife.bind(this, view); 
     } 
    } 
} 

當我點擊複選框會發生什麼?

點進>檢查,點進>選中,點進>選中,點進>選中,點進>選中

未選中的複選框後,我無法改變複選框的狀態之後,點擊那個

+0

在'的onChange()'方法添加'notifyDatasetChanged()''後checkBoxStates.put(item.getMobileNumber(),檢查);'此行 –

+0

@Anil我得到這個錯誤:'java.lang.IllegalStateException:無法調用此方法,而RecyclerView正在計算佈局或滾動' –

+0

滾動每當setOnCheckedChangeListener被調用,嘗試檢查readyandroid答案。 –

回答

1

在這裏,我使您的CustomContactsViewHolder類爲非靜態類,並做了一些關於clic的更改k事件並再次設置數據以檢查和取消選中,一旦通過將代碼作爲備份檢查完整代碼。

import android.content.Context; 
import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.CheckBox; 
import android.widget.TextView; 

import java.util.Collections; 
import java.util.HashMap; 
import java.util.Map; 

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.CustomContactsViewHolder> { 
    private OnCardClickListener onCardClickListener; 
    private List<UserPhoneContacts> list = Collections.emptyList(); 
    private Context context; 
    private  Realm    realm; 
    public static OnSelectedContacts onSelectedContacts; 
    private Map<String, Boolean> checkBoxStates = new HashMap<>(); 

    public ContactsAdapter(List<UserPhoneContacts> list, Context context) { 
     this.list = list; 
     this.context = context; 
     this.realm = Realm.getDefaultInstance(); 
    } 

    @Override 
    public CustomContactsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View v  = LayoutInflater.from(parent.getContext()).inflate(R.layout.contact_item, parent, false); 
     CustomContactsViewHolder holder = new CustomContactsViewHolder(v); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(final CustomContactsViewHolder holder, final int position) { 
     holder.contact_name.setText(list.get(position).getDisplayName()); 
     holder.contact_mobile.setText(list.get(position).getMobileNumber()); 
     boolean checkedState = checkBoxStates.containsKey(list.get(position).getMobileNumber())?checkBoxStates.get(list.get(position).getMobileNumber()):false; 
     holder.select_contact.setChecked(checkedState); 
    } 

    @Override 
    public int getItemCount() { 
     return list.size(); 
    } 

    @Override 
    public void onAttachedToRecyclerView(RecyclerView recyclerView) { 
     super.onAttachedToRecyclerView(recyclerView); 
    } 

    public void setData(List<UserPhoneContacts> list) { 
     this.list = list; 
    } 

    public class CustomContactsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
     @BindView(R.id.contact_name) 
     TextView contact_name; 

     @BindView(R.id.contact_mobile) 
     TextView contact_mobile; 

     @BindView(R.id.contact_photo) 
     CircleImageView contact_photo; 

     @BindView(R.id.select_contact) 
     CheckBox select_contact; 


     CustomContactsViewHolder(View view) { 
      super(view); 
      ButterKnife.bind(this, view); 
     } 

     @OnClick(R.id.select_contact) 
     @Override 
     public void onClick(View v) { 
      int position = getAdapterPosition(); 
      switch (v.getId()){ 
       case R.id.select_contact: 
        final UserPhoneContacts item = list.get(position); 
        if (item == null) { 
         return; 
        } 
        boolean checkedState = checkBoxStates.containsKey(list.get(position).getMobileNumber())?checkBoxStates.get(list.get(position).getMobileNumber()):false; 
        ((CheckBox)v).setChecked(!checkedState); 
        checkBoxStates.put(item.getMobileNumber(), !checkedState); 
        ContactsAdapter.this.notifyDataSetChanged(); 
        break; 
      } 
     } 
    } 
} 
+0

當我再次點擊選中的複選框,狀態將被取消選中後,再次檢查該狀態不會改變 –

+0

LogCat:E/checkedState:false E/checkBoxStates:{09122331743 = true} E/checkedState: true和 E/checkBoxStates:{09122331743 = false} E/checkedState:true E/checkBoxStates:{09122331743 = false}'和日誌位置是布爾值checkedState = checkBoxStates.get(list.get(position).getMobileNumber() )== null?假:真; (「checkedState」,checkedState +「」); checkBoxStates.put(item.getMobileNumber(),!checkedState); Log.e(「checkBoxStates」,checkBoxStates.toString()); notifyDataSetChanged();' –

+0

我的帖子更新先生 –

1

你並不需要創建一個單獨的Map<String, Boolean>列表維護您的CheckBox是否選擇與否。嘗試下面的簡單技巧。但是您需要按照以下方式更新UserPhoneContacts模型類。

public class UserPhoneContacts { 

    // other variables 

    private boolean isSelected = false; // add this 

    // your class constructor and other getter/setter methods 

    // add below getter method 
    public boolean isSelected() { 
    return this.isSelected; 
    } 

    // add below setter method 
    public void setSelected(boolean isSelected) { 
    this.isSelected = isSelected; 
    } 
} 

更改ContactAdapter類這樣

@Override 
public void onBindViewHolder(final CustomContactsViewHolder holder, final int position) { 
    ... 
    final UserPhoneContacts upc = list.get(position); 
    holder.select_contact.setChecked(upc.isSelected() ? true : false); 

    holder.select_contact.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      upc.setSelected(!upc.isSelected()); 
      holder.view.setChecked(upc.isSelected() ? true : false); 
     } 
    }); 
} 
+0

我必須創建'Map'先生,因爲我使用'Realm'數據庫解決方案,並且想要更改數據庫上的數據 –

+0

好的,您可以使用。使用上面的邏輯來檢查是否選中了「CheckBox」。根據模型類返回的布爾值,你可以更新Map Map條目,對嗎? – Shashanth

+0

是的,我的代碼邏輯是正確的,但它不能正常工作,當我嘗試點擊多個更改複選框狀態,我的帖子更新 –

0

你的問題的主要原因是的onChange方法。

private void onChange(int position) { 
    final UserPhoneContacts item = list.get(position); 
    if (item == null) { 
     return; 
    } 
    boolean checkedState = checkBoxStates.get(list.get(position).getMobileNumber()) != null; 
    checkBoxStates.put(item.getMobileNumber(), !checkedState); 
    notifyDataSetChanged(); 
} 

例如,首先單擊位置3項,checkBoxStates.get(3) return null,所以!checkedState將是真實的。

其次你點擊位置3,checkBoxStates.get(3) == True,checkedState = (True != null) = true,所以!checkedState會爲false。

第三你點擊位置3,checkBoxStates.get(3) == FalsecheckedState = (False != null) = true,所以!checkedState也會假的,新的狀態也會被取消選中。

固定代碼應該如下:

private void onChange(int position) { 
    final UserPhoneContacts item = list.get(position); 
    if (item == null) { 
     return; 
    } 
    Boolean lastCheckedState = checkBoxStates.get(list.get(position).getMobileNumber()); 
    boolean checkedState = (null == lastCheckedState) ? false : lastCheckedState; 
    checkBoxStates.put(item.getMobileNumber(), !checkedState); 
    notifyDataSetChanged(); 
} 
+0

我測試了您的代碼,但它不能正常工作,點擊複選框後,狀態更改 –

+1

您是否嘗試過調試斷點? –