I have the list view with some pre-checked checked boxes. When I use to uncheck the checked checkbox and scroll it again, it gets checked, and if I check the unchecked the checkbox then scroll it, it changed to the unchecked state.
When I
check the checkbox and then scroll it, it gets unchecked
uncheck the pre checked checkbox and scroll it, it gets checked
Code:
public class Adapter extends BaseAdapter {
private Context activity;
private ArrayList<Data> data;
private static LayoutInflater inflater = null;
private View vi;
TextView roll;
TextView menu;
CheckBox checkBox;
CheckBox cb;
boolean[] checkBoxState;//maintain a local boolean array to store the checked status of checkboxes positionwise
public Adapter(Context context, ArrayList<Data> items) {
this.activity = context;
this.data = items;
checkBoxState=new boolean[items.size()];//initializing the local boolean array inside the constructor
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int i) {
return data.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(final int position, View view, ViewGroup viewGroup) {
vi = view;
final int pos = position;
final Data items = data.get(pos);
vi = inflater.inflate(R.layout.list_row, null);
checkBox = (CheckBox) vi.findViewById(R.id.cb);
menu = (TextView) vi.findViewById(R.id.nama_menu);
roll = (TextView) vi.findViewById(R.id.roll);
menu.setText(items.getMenu());
roll.setText(items.getRoll());
if (items.getRoll().equals(items.getRollBlocked())) {
checkBox.setChecked(true);
checkBoxState[position] = true;
items.setCheckbox(true);//maintaining boolean check status according to conditions
notifyDataSetChanged();
vi.setEnabled(false);
}
else if (items.getRoll().equals(items.getRollLate())) {
checkBox.setChecked(true);
checkBoxState[position] = true;//maintaining boolean check status according to conditions
items.setCheckbox(true);
notifyDataSetChanged();
vi.setEnabled(false);
}
else if (items.getRoll().equals(items.getRollCheck())) {
checkBox.setChecked(true);
checkBoxState[position] = true;
items.setCheckbox(true);//maintaining boolean check status according to conditions
} else if (items.getRollBlocked().equals("-")&& items.getRollCheck().equals("-") && items.getRollLate().equals("-")) {
checkBox.setChecked(false);
items.setCheckbox(false);
checkBoxState[position] = false;//maintaining boolean check status according to conditions
}
checkBox.setChecked(checkBoxState[position]);//checkbox is finally checked depending upon the local boolean array which u just created according to ur needs
vi.setTag(checkBox);
vi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Data items = data.get(pos);
cb = (CheckBox) v.getTag();
if(items.getRoll().equals(items.getRollBlocked())){
if(((CheckBox)v).isChecked()) {
checkBoxState[position] = true; //explicitly making it true
vi.setEnabled(false);
cb.setChecked(true);
}
else {
checkBoxState[position] = false;//explicitly making it false
}
}
else if(items.getRoll().equals(items.getRollLate())){
if(((CheckBox)v).isChecked()) {
checkBoxState[position] = true; //explicitly making it true
vi.setEnabled(false);
cb.setChecked(true);
}
else {
checkBoxState[position] = false;//explicitly making it false
}
}
else if(items.getRoll().equals(items.getRollCheck())){
if(((CheckBox)v).isChecked()) {
checkBoxState[position] = true; //explicitly making it true
cb.setChecked(false);
items.setCheckbox(false);
}
else {
cb.setChecked(true);
items.setCheckbox(true);
checkBoxState[position] = false;//explicitly making it false
}
}else if (items.getRollBlocked().equals("-") && items.getRollCheck().equals("-") && items.getRollLate().equals("-")){
if(((CheckBox)v).isChecked()) {
checkBoxState[position] = true; //explicitly making it true
cb.setChecked(false);
items.setCheckbox(false);
}
else {
cb.setChecked(true);
items.setCheckbox(true);
checkBoxState[position] = false;//explicitly making it false
}
}else{
}
}
});
return vi;
}
public ArrayList<Data> getAllData(){
return data;
}
}
Logcat:
FATAL EXCEPTION: main
Process: , PID: 1366
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at com.mark_attendance.list.adapter.Adapter.getView(Adapter.java:78)
at android.widget.AbsListView.obtainView(AbsListView.java:2360)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1326)
at android.widget.ListView.onMeasure(ListView.java:1233)
at android.view.View.measure(View.java:19731)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:19731)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:714)
at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:90)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1391)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:784)
at android.view.View.measure(View.java:19731)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:19731)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19731)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:19731)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19731)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:687)
at android.view.View.measure(View.java:19731)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2271)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1358)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1607)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1246)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6301)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Data .java
public class Data {
private String roll;
private String menu;
private boolean check;
private String roll_check;
private String roll_blocked;
private String roll_late;
private String studentID;
private int blockedposition;
private int blockedposition2;
public Data() {}
public Data(String roll,String menu, boolean check,String roll_check,int blockedposition,String roll_blocked,int blockedposition2,String roll_late,String studentID) {
this.roll=roll;
this.menu = menu;
this.check = check;
this.roll_check = roll_check;
this.blockedposition=blockedposition;
this.blockedposition2=blockedposition2;
this.roll_blocked=roll_blocked;
this.roll_late=roll_late;
this.studentID=studentID;
}
public String getRoll() {
return roll;
}
public void setRoll(String roll) {
this.roll = roll;
}
//-----------------------Studentid---------------------------------------
public String getStudentID() {
return studentID;
}
public void setStudentID(String studentID) {
this.studentID = studentID;
}
//--------------------------------------
//------------------------------------------------------------
public int getBlockedPosition() {
return blockedposition;
}
public void setBlockedPosition(int blockedposition) {
this.blockedposition = blockedposition;
}
//------------------------------------------------------------
//------------------------------------------------------------
public int getBlockedPosition2() {
return blockedposition2;
}
public void setBlockedPosition2(int blockedposition2) {
this.blockedposition2 = blockedposition2;
}
//------------------------------------------------------------
public String getRollCheck() {
return roll_check;
}
public void setRollCheck(String roll_check) {
this.roll_check = roll_check;
}
//------------------------------------------------------------
public String getRollBlocked() {
return roll_blocked;
}
public void setRollBlocked(String roll_blocked) {
this.roll_blocked = roll_blocked;
}
//-----------------------LATE-----------------------------------------------------
public String getRollLate() {
return roll_late;
}
public void setRollLate(String roll_late) {
this.roll_late = roll_late;
}
//--------------------------------------------------------------------------
public String getMenu() {
return menu;
}
public void setMenu(String menu) {
this.menu = menu;
}
public boolean isCheckbox() {
return check;
}
public void setCheckbox(boolean check) {
this.check = check;
}
}
Try doing like this,please read the comments as i tried to explain in detail : In ur Data Class just add this Boolean Flag which will be the primary flag on which checked or unchecked will depend :
Now Modify ur data set according to ur conditions by running a basic for-each loop and set boolean status according to ur conditions: Let's assume ur data set is ArrayList datas;
Loop through the data set and place boolean flags wherever if condition succeeds
And ur adapter class,U have to write like this :
Just try to remove
checkBox.setChecked()
fromif
clause and set it likecheckBox.setChecked(items.getRoll().equals(items.getRollLate()))
. It should do the job.I'm going to answer while changing your code as little as possible. Also, I started with your last revision, before you made the changes based on another answer.
However, there may be some issues with your logic. You want to control the checkbox based on both the content of the item and based on user input. That's OK but how do you know which to use? My answer uses the content until the the user clicks the item then it is manual from that point. To go back to using content after a click, there needs to be a way to tell the view to go back to using content. The may be what you are doing with
vi.setEnabled()
, I wasn't sure.1st, add this to the Data class. You may re-purpose the the
boolean
variable you already have but to be safe I just created another one.And here's the
getView()
method, including theOnClickListener()
.In general, there are a few things that would be better to do another way. In your
getView()
, you inflate the view every time. See ListView for a more efficient way to do this. Also, it's more common to useOnItemClickListener()
for a ListView. If you use a ViewHolder for your ListView, thenonClickListener()
is better. Anyway, I didn't want to change too much in your code. I hope this solves your problem.The issue I can see in your code is that you are not making your Adapter in standard way. Check this code , make your Adapter with this way or better copy and paste your code in this class. It will work fine.
The main essential part of this Adapter is ViewHolder class, ViewHolder class will make sure that your values of data array won't mix-up with each other.
override this method in adapter class
}