Is it possible to call the onCheckedChanged method without interaction?

I have a custom ListView where clicking on an element launches a new Activity . Each row of a ListView has a CheckBox and a TextView .

This is the getView method from my custom ListView :

 public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.puzzles_row, null); } ListedPuzzle lp = items.get(position); if (lp != null) { TextView title = (TextView) v.findViewById(R.id.listTitles); title.setText(lp.getTitle()); CheckBox star = (CheckBox) v.findViewById(R.id.star_listed); star.setChecked(lp.isStarred()); star.setTag(new Integer(position)); star.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Integer realPosition = (Integer) buttonView.getTag(); ListedPuzzle obj = items.get(realPosition); starListedPuzzle(obj.getId(), isChecked); } }); } return v; } 

onCheckedChanged is called when returning from another Activty without any possible user interaction to really check anything.

The fact is that it works great and does not change anything. I read that this is a mistake, but I cannot believe it.

It always calls a method on the same two ListView elements. Can they be set as checkedChange=true some way?

+4
source share
4 answers

I have a feeling that this is happening in the onRestoreInstanceState method. Android automatically processes the state of most of the View in your activity when it is paused and resumed. When resuming, it sounds like the checked state of your CheckBox objects is being restored, starting onCheckedChanged . Try this in your Activity and let me know if this solves your problem:

 private boolean mRestoringInstanceState; @Override protected void onRestoreInstanceState( Bundle savedInstanceState ) { mRestoringInstanceState = true; super.onRestoreInstanceState( savedInstanceState ); mRestoringInstanceState = false; } 

Then change your onCheckChanged method as follows:

 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(!mRestoringInstanceState) { Integer realPosition = (Integer) buttonView.getTag(); ListedPuzzle obj = items.get(realPosition); starListedPuzzle(obj.getId(), isChecked); } } 

Edit: Probably a better / simpler solution would be to assign a listener in the onResume method, since it will be called after onRestoreInstanceState . Please note that when using this solution you will not implement any of the above:

 @Override protected void onResume() { super.onResume(); CheckBox star = (CheckBox) v.findViewById(R.id.star_listed); star.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // onCheckedChanged implementation } }); } 

Edit2: Just realized that you are doing this in the Adapter . This may not be related to onRestoreInstanceState , but I think I see the problem. You reuse View in the Adapter , which is good, but you set star to check before setting the listener. The problem is that star already has a listener the last time it went through the getView method. Before you call star.setChecked() , call star.setOnCheckedChangedListener(null) and find out if this solves your problem.

+9
source

I ran into this problem using a special adapter.

I found a check if the isShown button solves the problem:

 OnCheckedChangeListener ccl = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(buttonView.isShown()) { } } }; 
+6
source

It can be called onRestoreInstanceState inside your fragment

You can disable this with

 android:saveEnabled="false" 

in the checkbox layout definition

+2
source

Test your stack in the listener

 public void onCheckedChanged(CompoundButton buttonView, isChecked) { <breakpoint here> } 

If you see onRestoreInstanceState() in stacktrace, you can use this in the layout:

 <CheckBox ... android:saveEnabled="false" /> 

... as suggested here: Android CheckBox - restore state after screen rotation

or

If you see that star.setChecked() is the one that star.setChecked() is called from your stack, then just remove the listener on star.setOnCheckedChangedListener(null) to star.setChecked() (then you can reset the listener like and you). As Jason Robinson suggests.

+1
source

Source: https://habr.com/ru/post/1413232/


All Articles