Android - RadioGroup's first button becomes unselectable after clearCheck() and rotate - android

I'm having problems with RadioGroups clearCheck method and rotating my app. I think it might be a Google issue?
I have a three button radio group that when launched has the first item selected by default in xml.
My problem is, I have a button that calls radio groups clearCheck(). If you rotate the app, and then try to press the first radio group item, it will not select it. It tries, it shows the animation, but it remains unselected.
I thought I was going crazy and it was something wrong in my code, but I've broken it down to the most simplistic app possible by just making a new app.
If I don't preselect Button A (via XML or code) then it works correctly, but I need this button pre-selected.
Any idea how I can work around this problem and have A selected by default?
Repo steps
Launch app
Select Radio Button B
Press Clear Check
Rotate App
Press Radio Button A
Result: Radio A won't select. If you then press B or C you can once again press A, but not until then.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
Button clearButton = (Button) findViewById(R.id.clearButton);
clearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
radioGroup.clearCheck();
}
});
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<RadioGroup
android:id="#+id/radioGroup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:gravity="center"
android:checkedButton="#+id/radioButtonA"
android:orientation="horizontal">
<RadioButton
android:id="#+id/radioButtonA"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="A" />
<RadioButton
android:id="#+id/radioButtonB"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="B" />
<RadioButton
android:id="#+id/radioButtonC"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="C" />
</RadioGroup>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear"
android:id="#+id/clearButton"
android:layout_below="#+id/searchRadioGroup"
android:layout_centerHorizontal="true"
android:layout_marginTop="114dp" />
</RelativeLayout>

Upon rotation, the checked id is reset due to android:checkedButton="#+id/radioButtonA".
If there was a button checked, CompoundButton's onRestoreInstanceState resets the checked button again to the correct checked button.
Contrarily, if there was no button checked, buttonA's onRestoreInstanceState will reset it to unchecked. RadioGroup is not handling this scenario because it is not designed to handle unchecks.
So, we end up with RadioGroup tracking buttonA as checked and buttonA tracking itself as unchecked. When you click on buttonA, the check is processed, however the UI does not update due to shortcircuit logic in the check() method because it assumes that since the id already matches the mCheckedId it has on hand, the button should already be checked:
// don't even bother
if (id != -1 && (id == mCheckedId)) {
return;
}
I guess this could be considered a bug, but it ultimately comes down to some strange design choices on your part. You are setting it to default to buttonA, which means that the user cannot uncheck any button under normal circumstances and then you provide a clear button to get them to a non-default state that they could not reach under normal circumstances. So, there are two possible solutions that would bring your UI design choices in to focus:
1) If you want there to always be a checked button, have the reset button reset to default state.
clearButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mRadioGroup.check(R.id.radioButtonA);
}
});
2) If you want there to possibly be no checked button, don't default to anything.

I had this problem in my App .
I cheated . I created a new radio buttom and I selected gone its visibility .
after that , I put setcheked=(true).

Related

How to disable double click event on radio button?

I just want to disable double click event on my radio button, that's it. I don't really know how to achieve that.
See my radio button is already inside radio group, I have custom it like this: when I click on it, it expand a dropdown, when I click again it collapse the dropdown, but when I double click on it while the list is expanded, the list collapse in but the radio button active, so I totally want to disable the double click event only.
Please help me out, thanks.
I found to solve this common problem,
If you want to call prevent two click from XML file then write below code,
<RadioButton android:id="#+id/radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/text"
android:onClick="preventTwoClick"/>
If you want to call prevent two click from JAVA file then write below code,
radioButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Prevent Two Click
preventTwoClick(view);
// Do magic
}
});
And in another function like,
public void preventTwoClick(final View view){
view.setEnabled(false);
view.postDelayed(new Runnable() {
public void run() {
view.setEnabled(true);
}
}, 500);
}
From documentation
To create each radio button option, create a RadioButton in your
layout. However, because radio buttons are mutually exclusive, you
must group them together inside a RadioGroup. By grouping them
together, the system ensures that only one radio button can be
selected at a time.
Then use like follow
<?xml version="1.0" encoding="utf-8"?>
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButton android:id="#+id/radio_pirates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/pirates"
android:onClick="onRadioButtonClicked"/>
<RadioButton android:id="#+id/radio_ninjas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/ninjas"
android:onClick="onRadioButtonClicked"/>
</RadioGroup>
Each RadioButton will be clicked unique time, avoiding the double click!

How to turn anything into a button in Android

I need a way of turning a TableRow into a Button in android. I have tried to set up an onCLickListener() and I have tried nesting a TableRow inside a Button but that just crashes the app.
Edit:
I deleted the android:onCLick="onClick" like you said and that got rid of the crashing but nothing happens when I click the table row.
My code:
tableRow1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent openInfoTR1 = new Intent("android.intent.action.MENU");
fromTableRow = 1;
startActivity(openInfoTR1);
System.out.println("Confirmed click");
}
});
<TableLayout
android:id="#+id/tlDisplayTable"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow
android:id="#+id/trTableRow1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="100"
android:visibility="invisible"
android:clickable="true">
<TextView
android:id="#+id/tvDisplayedText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:padding="5dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_weight="5"/>
</TableRow>
</TableLayout>
Every element that inherits from View can have attached an OnClickListener. No need to wrap it inside a button.
However, you'll have to look at how events are propagated through your layout. E.g. if you have clickable elements within your TableRow, the click events will normally be consumed by that elements and will not reach your OnClickListener. There are different ways to intercept or modify that behaviour, but you'd have to post your code to get more specific help.
EDIT:
The exception in your app comes from the line android:onClick="onClick" in your layout file. As you set the onClick listener programmatically, you do not need this. android:onClick="onClick" is a shortcut that would expect a method void onClick(View view) directly within your Activity (not, as you have it, as part of the OnClickListener implementation).

Android apply animation to button background

I have a button which currently has an animation assigned to it on click:
Button btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
v.startAnimation(animRotate);
}
});
Here is an example of the button in XML:
<Button
android:id="#+id/btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:text="#string/btnText"
android:textColor="#ffffff"
android:textSize="18dp"
android:padding="12dp"
android:drawableTop="#drawable/btnIcon"
android:layout_weight="1" />
The animation works spot on, however on the button itself there is a text value and a drawable value, and I would like to be able to target the drawable and animate that only. I have searched all over the net and everything appears to be targeting objects by their id without any background/drawable selection.
Any feedback is welcome, even if its just to inform me that it can't be done.
Many thanks.
You may want to create a FrameLayout with the TextView and the Button and animate only the Button.

Android: Radio Buttons for Navigation

I am writing an application in which I want to limit access to a menu section from one user group. That user group has no fine motor skills, so I decided that a good way to access the menu would be to use a slider or some other method that requires precision hand movements.
I have been trying to use Radio Buttons to do this; I have 3 radio buttons, and I want to have it so that when they are all checked, they (the radio buttons) become invisible and the button that allows users to navigate to the next menu screen becomes visible.
I have been reading around, but am unsure of how to do this. Any code or tips that point me in the right direction would be greatly appreciated!
Sorted it out, using the following:
In the XML:
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:onClick="onCheckboxClicked"
android:text="" />
<CheckBox
android:id="#+id/checkBox2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:onClick="onSecondCheckboxClicked"
android:visibility="gone"
android:text="" />
In the Java:
public void onCheckboxClicked(View v) {
CheckBox cb2 = (CheckBox) findViewById(R.id.checkBox2);
// Perform action on clicks, depending on whether it's now checked
if (((CheckBox) v).isChecked()) {
// Toast.makeText(MainPage.this, "Selected",
// Toast.LENGTH_SHORT).show();
cb2.setVisibility(View.VISIBLE);
}
}
public void onSecondCheckboxClicked(View v2) {
Button button = (Button) findViewById(R.id.access_adult_controls);
if (((CheckBox) v2).isChecked()) {
button.setVisibility(View.VISIBLE);
}
}

How to make a button press once and then not pressable anymore?

I have a button
<Button
android:layout_above="#id/choice2"
android:layout_centerHorizontal="true"
android:textColor="#FFFF00"
android:textSize="25sp"
android:gravity="center"
android:background="#drawable/loginbutton"
android:layout_height="30dp"
android:layout_width="fill_parent"
android:layout_marginBottom="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="#string/q1a1"
android:id="#+id/choice1">
</Button>
and when you press this button, it adds 10 to a counter/score keeper. How do I make this button able to be pressed once, but then not pressable again after that? Users are able to cheat and press the button multiple times to add more to there score.
in your onCreate method, do it like this:
final Button choice1 = (Button) findViewById(R.id.choice1);
choice1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
choice1.setEnabled(false);
}
});
You can either hide or disable it
Button mybutton;
mybutton.setVisibility(View.GONE); // hide it
mybutton.setClickable(false); // disable the ability to click it
Disable the button when it is pressed (in the code that is also handling the 'normal' action of the button).

Categories

Resources