if else statement with Checkbox not executing as expected - android

I have problems when using a CheckBox in an else if statement. I have a CheckBox list like:
cbapel, cbmangga, cbjeruk, cbbelimbing.
when I tick the checkBoxes cbapel, cbmangga, and cbjeruk the result is "2" instead of "4". What's the solution?
if(MainActivity.cbapel.isChecked() && MainActivity.cbbelimbing.isChecked()) {
tx.setText("1");}
else if(MainActivity.cbapel.isChecked() && MainActivity.cbjeruk.isChecked()) {
tx.setText("2");}
else if(MainActivity.cbapel.isChecked() && MainActivity.cbmangga.isChecked()) {
tx.setText("3");}
else if(MainActivity.cbapel.isChecked() && MainActivity.cbmangga.isChecked() && MainActivity.cbjeruk.isChecked()) {
tx.setText("4");}
else {
tx.setText("NOT FOUND");
}

You are really overlooking the simple solution here, by far (assuming you are just counting the number of checked boxes)
int checked = 0;
if (MainActivity.cbapel.isChecked()) {
checked++;
}
if (MainActivity.cbbelimbing.isChecked()) {
checked++;
}
if (MainActivity.cbmangga.isChecked()) {
checked++;
}
if (MainActivity.cbjeruk.isChecked()) {
checked++;
}
if (checked == 0) {
tx.setText("NOT FOUND");
} else {
tx.setText(String.valueOf(checked));
}
If you aren't looking to count the checkboxes, then I think this follows the same logic as what you tried in your question, but accounts for one condition ever being entered.
String value = "";
boolean bool1 = MainActivity.cbapel.isChecked();
boolean bool2 = MainActivity.cbbelimbing.isChecked();
boolean bool3 = MainActivity.cbmangga.isChecked();
boolean bool4 = MainActivity.cbjeruk.isChecked();
if (bool1) {
if (bool3 && bool4) {
value = "4";
} else if (bool3 && !bool4) {
value = "3";
} else if (!bool3 && bool4) {
value = "2";
}
if (value.isEmpty() && bool2) {
value = "1";
}
} else {
value = "NOT FOUND";
}
tx.setText(value.isEmpty() ? "NOT FOUND" : value);

else if(MainActivity.cbapel.isChecked() && MainActivity.cbjeruk.isChecked()) {
Let's look at this...
Is MainActivity.cbapel.isChecked()? Yes
Is MainActivity.cbjeruk.isChecked()? Yes
So this evaluates to true and so it won't check any of the other conditional statements.
There are many different ways for this logic to flow. But, to know what is best for your situation, depends on what these variables actually mean and what you are doing.
The best advice I could give you from what you have provided is to check the most filtered situation first. So...
if(MainActivity.cbapel.isChecked() && MainActivity.cbmangga.isChecked()
&& MainActivity.cbjeruk.isChecked()) {
tx.setText("4");
}
then add the else ifs after that for the other checks.
Also, cricket has a good suggestion in his comment you are checking the same condition every time so you can remove that and wrap it all in one if to remove some duplication.

Use this listener to each check box and set your conditions accordingly
class CheckboxListeners implements CompoundButton.OnCheckedChangeListener {
private CheckBox checkbox;
CheckboxListeners(CheckBox checkbox) {
this.checkbox = checkbox;
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
checkbox.setChecked(isChecked);
}
}

Related

How to check for tap in monogame?

I want to check that Rectangle was tapped. This mehod does the job and it works almost how I want:
private bool CheckRectangleTouch(Rectangle target)
{
var touchCollection = TouchPanel.GetState();
if (touchCollection.Count > 0)
{
foreach (var touch in touchCollection)
{
if (target.Contains(touch.Position))
{
return true;
}
}
}
return false;
}
Problem I have is that after I've tapped rectangle it keeps returning true until I release it (it can register 10-30 times for one tap) and I want it to return true just once - for the first touch.
I've tried this (replace code inside foreach):
var isFirstTouch = !touch.TryGetPreviousLocation(out _);
if (target.Contains(touch.Position) && isFirstTouch)
{
return true;
}
And this (bad one, I don't really want it to register after release):
if (target.Contains(touch.Position) && touch.State == TouchLocationState.Released)
{
return true;
}
But nothing is does it. Either logic is not consistent or doesn't work at all.
So how do I check for tap?
Update: this works but it's very hacky, has delay and gives me random phantom taps:
try
{
var tap = TouchPanel.ReadGesture(); // falls each time when no input
return tap.GestureType == GestureType.Tap && target.Contains(tap.Position);
}
catch { }
return false;
Here's what I ended up doing:
I have singleton to hold my game state (many different props updated as needed). I added to it:
public TouchCollection TouchCollection { get; set; }
Prop to hold TouchPanel.GetState result. I fill it in Games Update method once per frame, as #craftworkgames suggested:
State.TouchCollection = TouchPanel.GetState();
Also I added this prop to my game state:
public bool TouchActive { get; set; }
And this is the method to check for rectangle tap. It returns true only for the first contact in tap:
private bool CheckRectangleTap(Rectangle target)
{
if (State.TouchCollection.Count == 0)
{ // if no input
return State.TouchActive = false;
}
var targetTouched = false;
foreach (var touch in State.TouchCollection)
{
if (target.Contains(touch.Position))
{
targetTouched = true;
}
}
if (targetTouched && !State.TouchActive)
{ // if target is touched and it's first contact
return State.TouchActive = true;
}
return false;
}
It doesn't seem ideal but it works for my case.

How to disable call inside onChecked change conditionally?

I have toggle(Switch) buttons inside my fragment.After coming on the fragment I am reading BLE values and setting the toggle buttons.
#Override
public void sosStatus(boolean sosvalue, BluetoothGattCharacteristic sosCharac) {
if (sosvalue) {
byte[] charValue = sosCharac.getValue();
String valueOfCharInstring = StringUtils.byteToHex(charValue[0]);
Log.d("+++++SosStatus",""+sosCharac.getUuid().toString() + " " + valueOfCharInstring);
if (sosCharac.getUuid().toString().equalsIgnoreCase(BLEConstants._BUTTON_CHARACTERISTIC)) {
if (valueOfCharInstring.equalsIgnoreCase(BLEConstants.EnableCharacInString)) {
setButtonStatus(touchButton,R.id.switch_btn_device_touch,"Enabled");
// touchButton.setChecked(true);
// tvTouchButtonAction.setText("Enabled");
} else if (valueOfCharInstring.equalsIgnoreCase(BLEConstants.DisableCharacInString)) {
setButtonStatus(touchButton,R.id.switch_btn_device_touch,"Disabled");
// touchButton.setChecked(false);
// tvTouchButtonAction.setText("Disabled");
}
}
if (characList.size() > 0) {
gattclientCallBack.readCharacteristicMain(UUID.fromString(characList.remove(characList.size() - 1)));
} else {
useOnCheckedChangeMethod = true;
showProgress(false);
}
} else {
useOnCheckedChangeMethod = true;
showProgress(false);
HandleCharacListData(true,false,"");
}
}
Now since Switch widget is used, what is happening is that when I read the values programatically for first time, it works fine.but when I toggle the button with touch, onCheckChanged is repeatedly getting called as if I set some value, it keeps on calling itself in infinite loop. This is my oncheckchanged code.
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
try {
if (useOnCheckedChangeMethod) {
switch (compoundButton.getId()) {
case R.id.switch_btn_device_touch:
touchButton.setOnCheckedChangeListener(null);
//showProgress(true);
HandleCharacListData(true,false,"");
HandleCharacListData(false,false,BLEConstants.TOUCH_BUTTON_CHARACTERISTIC);
if(characList!=null && characList.size()>0) {
if(b) {
gattclientCallBack.writeCharacteristic(characList.remove(characList.size() - 1), BLEConstants.DisableCharac);
}
else {
gattclientCallBack.writeCharacteristic(characList.remove(characList.size() - 1), BLEConstants.EnableCharac);
}
}
Log.d("Touch++++", "+++");
break;
}
So it continuously keep on toggling as on and off due to the check if(b). :)
what can I do to ensure that the onCheckChange methos only gets called once after the value is set ?
Things that I have also tried
1) Use onClick listener and disable call in oncheckchanged and enable on click.
2) Use onTouch
Thank you :)
That interesting, because inside of setChecked() it actually checks to see if it's in the middle of broadcasting and returns...
public void setChecked(boolean checked) {
if (mChecked != checked) {
mChecked = checked;
refreshDrawableState();
notifyViewAccessibilityStateChangedIfNeeded(
AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
// Avoid infinite recursions if setChecked() is called from a listener
if (mBroadcasting) {
return;
}
mBroadcasting = true;
if (mOnCheckedChangeListener != null) {
mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
}
if (mOnCheckedChangeWidgetListener != null) {
mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
}
mBroadcasting = false;
}
}
The only solution I know of is un-registering the callback before calling setChecked() and register the callback again after your call returns. This works because the callback isn't called asynchronously but instead, called immediately inside of setChecked().
Hey I got my answer in the link below to a question framed little differently . Thanks to this guy :)
onCheckedChanged called automatically

how to retrieve and sum up values of multiple checkboxes?

if(checkbox1.isChecked())
{
String text=checkbox1.getText().toString();
}
For all of your checkboxes use :
if(checkbox1.isChecked && checkbox2.isChecked)
{
//Do your stuff
}
For one of checkboxes:
if(checkbox1.isChecked || checkbox2.isChecked)
{
//Do your stuff
}

Random boolean generator for android

I am trying to create a random (50/50) chance of a case A or case B happen in android and I need it to be as simple and as resource efficient as possible. I've looked through stackoverflow but all I find for random boolean is in C++?
Would appreciate if someone could give me a suggestion as to how to do this, whether with boolean or with strings/integers (since I was told that booleans is a primitive).
I tried the following
public static boolean getRandomBoolean() {
return Math.random() < 0.5; }
boolean atrg = getRandomBoolean();
if (atrg = true)
{ Toast.makeText(cxt, "TRUE", Toast.LENGTH_SHORT).show(); }
else if (atrg = false)
{ Toast.makeText(cxt, "FALSE", Toast.LENGTH_SHORT).show(); }
But in nearly every case, I tested (>20x), its TRUE?. This is likely a stupid question but is getRandomBoolean a boolean or an int/double? Sorry, I'm very new to android, as you probably guessed.
Your random generator is fine, but your toast displaying the result is not.
The problem is in the if-statement where you use a single equals sign (=) which is an assignment. The result of this assignment will be true and thus it will never show the "FALSE" toast.
Try this instead.
boolean atrg = getRandomBoolean();
if (atrg) {
Toast.makeText(cxt, "TRUE", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(cxt, "FALSE", Toast.LENGTH_SHORT).show();
}
This is not how you check boolean in if. = is the assignment operator and == is used for comparison. You should check like:
if(atrg == true)
or in case of boolean it is simply:
if(atrg)
Your statement:
if(atrg = true)
assigns atrg with true and you never get a false case.
Just use Math.random(), it will return a value between 0 and 1.. Example below:
public static boolean getRandomBoolean() {
return Math.random() < 0.5;
}
public static void main(String[] args) {
System.out.println(getRandomBoolean());
}

add or remove a string from a list based on an if statement

I have the below code:
if(cb.isChecked())
{
selectedPlanets.add(planet.getDisplayName());
}
if (!cb.isChecked())
{
selectedPlanets.remove(planet.getDisplayName());
}
testing();
}
private void testing() {
serverString.setText(null);
Iterator<String>i = selectedPlanets.iterator();
while(i.hasNext()){
String aNum1 = i.next();
serverString.append(aNum1+",");
}
I then need to iterate through selectedPlanets but the removed ones show up too. By setting the TextView null again, it works if three or more are selected. However, if two are selected, the checked planet also gets removed from the list.
EDIT: for anyone who runs into this problem, I solved it by using the else (programmer's block made me lose sense!) and then implementing some other methods that I needed to make it work.
Why don't you just do it like this?
if (cb.isChecked()) {
selectedPlanets.add(planet.getDisplayName());
} else {
selectedPlanets.remove(planet.getDisplayName());
}
Why not do this:
for(int i=0; i<selectedPlanet.size(); i++) {
if(planet.isChecked()) {
selectedPlanets.add(planet.getDisplayName());
} else {
selectedPlanets.remove(planet.getDisplayName());
}
}
What you are trying to do is
if isChecked true then add something
if(cb.isChecked())
{
selectedPlanets.add(planet.getDisplayName());
}
if isChecked is not true then remove something
if (!cb.isChecked())
{
selectedPlanets.remove(planet.getDisplayName());
}
Instead of using not true condition you must use else case like
if(cb.isChecked()) {
selectedPlanets.add(planet.getDisplayName());
} else {
selectedPlanets.remove(planet.getDisplayName());
}

Categories

Resources