Android Radio Group multiple selection issue - java

I'm programatically creating a series of radio buttons in a radiogroup:
for (Soldier soldier:clickedSquad.getMembers()) {
Integer I=0;
soldier.setId(I);
RadioButton radiobutton=new RadioButton(getContext());
radiobutton.setText(soldier.toString());
radiobutton.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
radiobutton.setId(soldier.getId());
I++;
soldierRgrp.addView(radiobutton);
}
It creates the radiobuttons as I intend, but when I click several they all stay clicked like a checkbox, and I need only one to be clicked at a time like radiobuttons usually do.
Any idea why this is happening?
The radiogroup is in the XML and looks as follows:
<RadioGroup
android:layout_margin="10dp"
android:id="#+id/reg_rgrp_soldiers"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RadioGroup>

RadioButtons behave that way only if they same id. In your case they do! You are initialising your variable I=0 each time. Hence, each soldier is given the same id. Soldiers don't particularly like that! Change you code to:
int i=0;
for (Soldier soldier:clickedSquad.getMembers()) {
soldier.setId(i++);
RadioButton radiobutton=new RadioButton(getContext());
radiobutton.setText(soldier.toString());
radiobutton.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
radiobutton.setId(soldier.getId());
soldierRgrp.addView(radiobutton);
}

Related

Creating textfields after hitting a button (Eclipse/Android)

I am trying to learn android development in Eclipse and I am stuck. I created a button with using this.
<Button
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="bla"
android:layout_gravity="center"
android:textSize="15dp"
android:id="#+id/bla"
/>
And my listener is the following.
button1=(Button) findViewById(R.id.bla);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});
What I want is the following. When I click my button I want 3 different textfields to be seen. After I enter some values to that textfields, I want to get back to the initial screen which contains button1. How can I do that? Also with which method I can store the values that are written to this textfields?
Edit:All answers were helpful and I upvoted them but I accepted Diego's answer because of the clarity
If you want the EditText appear after you click a Button you can include all of them in the same XML layout file, set the EditText to INVISIBLE (android:visibility="invisible") and change it to VISIBLE in the OnClick listener.
To create EditText call this on OnButton Click
LinearLayout ll = (LinearLayout) findViewById(R.id.linearlayout2);
EditText tv;
List<EditText> allEds = new ArrayList<EditText>();
for (int i = 0; i < 5; i++) {
tv = new EditText(this);
tv.setText("Dynamic TextView" + i);
tv.setId(i + 5);
ll.addView(tv);
}
And get inserted values from EditText check this
String[] strings = new String[allEds.size()];
for (int i = 0; i < allEds.size(); i++) {
strings[i] = allEds.get(i).getText().toString();
}
Initially create 3 edit text's in your xml file and place them as invisible like android:visibility="invisible" for each and every edit text,
now in our java file when button is clicked visible them. like buttonid.setVisibility(View.VISIBLE);

getSelectionStart() doesn't work in android

I want to get EditText selection start when user click in EditText (touch).
I do with this code :
int startIndex = txtMean.getSelectionStart();
this always return 0;
and EditText xml code:
<EditText
android:id="#+id/txtMean"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#null"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint=""
android:inputType="textMultiLine"
android:scrollbars="none" />
my code work in android 2.* but don't work in 4.*
txtMean.getSelectionStart();
getSelectionStart doesn't relate to the user's last touch or click per se. It relates to the text selection on the screen. By default, when the user does a long click text-handles will come up, and allow the user to expand a highlighted text selection. It's the highlighted text that refers to the selection, which is not necessarily where the user last touched.
When the user makes a text selection it becomes highlighted because the EditText will apply a SelectionSpan to the character sequence, and getSelectionStart will return the start value of this span.
Update, Solution Help:
#Override
public boolean onTouchEvent(MotionEvent event) {
// this = EditText;
// will give you the position of the nearest chracter.
int offset = this.getOffsetForPosition(event.getX(), event.getY());

Android: Nested Linearlayouts will not display a grid of buttons, Matching parent

I have an app under construction. In one of the sub-menus I have a need for generic display of buttons, and therefor I want to make an activity that can display the given number of needed buttons.
I have succesfully made this happen, programmatically, but I want the total grid of buttons to fill up the entire parent they are placed in, which happens to be 3/4 of a landscape screen. The number of buttons varies from 16-38.!
I have also succesfully made this happen with other grids of buttons, in xml, with weight values, and match_parent values of entries.
When I assign buttons or rows the match_parent value programatically, it occupies the entire parent layout, not sharing it like i expect it to do, even though they have the same weight value of 1.0f
The relevant code follows below. I would like to post images as well, but I have not the reputation to do so.
`LinearLayout layout = (LinearLayout) findViewById(R.id.linear_custom_draw);
layout.setOrientation(LinearLayout.VERTICAL);
int columns = Math.min(6, 4+category); //sets number of buttons per row to 4-6
for (int i = 0; i < 4+category; i++) {
LinearLayout row = new LinearLayout(this);
row.setLayoutParams(new android.view.ViewGroup.LayoutParams(android.view.WindowManager.LayoutParams.MATCH_PARENT,
android.view.WindowManager.LayoutParams.MATCH_PARENT));
//the line above is the line that fills up the entirety of the linearlayout, even though there are more entries, unlike my xml-defined attempts.
row.setOrientation(LinearLayout.HORIZONTAL);
row.setWeightSum(1.0f);
if(i%2 == 0){
row.setBackgroundColor(getResources().getColor(R.color.listview_red_backgr_color));
}
for (int j = 0; j < columns; j++) {
int index = (i*columns)+j;
if(formations.size() > index){
Button btnTag = new Button(this);
btnTag.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
btnTag.setText(formations.get(index).getName());
btnTag.setTextColor(getResources().getColor(R.color.black_overlay));
btnTag.setId(formations.get(index).getId());
row.addView(btnTag);
}
}
layout.addView(row);`
Try to use TableLayout. Each Row will enforce the entire elements to match the parent with the same wights. You can control number of Buttons into each Row programatically with counter. Loop for end of Counter adding your buttons then add new Table Row
TableLayout tbl=new TableLayout(context);//create table
TableRow tr=new TableRow(context);//create table row
tr.addView(view);//add your button instead of the view
tbl.addView(tr);//add the row into the Table
In the XML file
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/keypad"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:stretchColumns="*">
<TableRow>
<Button android:id="#+id/keypad_1" android:text="#string/_1"></Button>
<Button android:id="#+id/keypad_2" android:text="#string/_2"></Button>
<Button android:id="#+id/keypad_3" android:text="#string/_3"></Button>
</TableRow>
</TableLayout>

Force Close When Dynamically Creating Widget from XML in Android

I'm attempting to create a few radio buttons and add them a RadioGroup dynamically. When I use the LayoutInflater method of pulling in the xml and adding it to the current view, everything works fine. The correct radio buttons show up.
However when I try to cast the View that LayoutInflater.inflate returned to a RadioButton (so I can setText), I get a force close with a java.lang.ClassCastException.
for (int i = 0; i < options.length(); i++) {
JSONObject option = options.getJSONObject(i);
View option_view = vi.inflate(R.layout.poll_option, radio_group, true);
option_view.setId(i);
RadioButton rb = (RadioButton) option_view.findViewById(i);
rb.setText(option.getString("response"));
}
poll_option.xml:
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
android:text="RadioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
The problem is you're not getting the views you think you're getting. LayoutInflater.inflate() called with a supplied root view means the view returned to you is THAT root view (not the inflated view). The method in which you are calling it inflates a new RadioButton and attaches it to the Group, but the return value (option_view) is the group itself, not the individual item. Since you need to play with the view before attaching it to the group, I'd recommend code like this (which works):
//I added these for posterity, I'm sure however you get these references is fine
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RadioGroup radio_group = new RadioGroup(this);
//Get the button, rename it, then add it to the group.
for(int i = 0; i < options.length(); i++) {
JSONObject option = options.getJSONObject(i);
RadioButton option_view = (RadioButton)vi.inflate(R.layout.poll_option, null);
option_view.setText(option.getString("response"));
radio_group.addView(button);
}
Editorial Note:
Just my $0.02, for such a simple layout, running this inflation process over and over in a loop may be a bit too much (inflation is expensive). You could easily create the same RadioButton in code, and add it with your LayoutParams, like:
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
for (int i = 0; i < options.length(); i++) {
RadioButton option_view = new RadioButton(this);
option_view.setText(option.getString("response"));
radio_group.addView(option_view, params);
}
This code I didn't test, but it should be pretty close :p
Hope that Helps!
You probably want to use findViewById and locate the radio button in the inflated view. Something like:
RadioButton rb = (RadioButton)option_view.findViewById(R.id.yourButtonId);
See http://developer.android.com/reference/android/view/View.html#findViewById(int)
you want to radiobutton.setId(INT)
and then later get it by findViewById() to get the button.
The setID(Int) should be used when you dynamically create the button. You can now access it later with findViewById.

Strange behaviour in Expandablelistview - Android

Im trying to implement an activity that uses ExpandableListView and I have gotten so far but now I have found some strange behavior.
My activity is meant to record food intake as specified by the user. they have a choice of menus (breakfast, lunch and dinner - the outer group) which expand to show their contents.
when a user clicks on an inner menu item a dialog appears asking them for the qty. once they enter a qty and dismiss the dialog the text on the menu item changes to reflect the quantity of that item that has been consumed
The above image shows the list in a closed state.
below is the list after I have opened the lunch menu and clicked on 'Potato Chips' and indicating a Quantity of 1. As you can see the 'Potato' itemtext has now been changed to reflect the Qty of 1.
The strange part happens now. if I click on 'Lunch' and close the list and then click on it again re-opening it, the 'Qty X 1' text has jumped to another item (Milk)
each time I open and close the list it jumps back and forth between the two items. Also if I open up other items, such as breakfast, I find that they too have now gotten items with 'Qty X 1' even though I havent clicked them.
The bits of code that are relevant are as such:
The XML for a child element:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/childname"
android:paddingLeft="50dip"
android:textSize="14dip"
android:textStyle="italic"
android:layout_width="200dip"
android:textColor="#color/black"
android:layout_height="40dip"/>
<TextView android:id="#+id/qty_display"
android:text="-"
android:textSize="14dip"
android:textStyle="italic"
android:layout_width="50dip"
android:textColor="#color/black"
android:layout_height="wrap_content"/>
</LinearLayout>
The code thats triggered on clicking a child element:
public boolean onChildClick(
ExpandableListView parent,
View v,
int groupPosition,
int childPosition,
long id) {
// open the dialog and inflate the buttons
myDialog = new Dialog(this);
myDialog.setTitle("Food Item Qty");
myDialog.setContentView(R.layout.food_intake_dialog);
final Button ok = (Button)myDialog.findViewById(R.id.fi_ok_but);
Button cancel = (Button)myDialog.findViewById(R.id.fi_cancel_but);
//the id for this item is stored as a hash key in a map (say, item_id01)
String key = "item_id"+groupPosition+""+childPosition;
current_selected_food_item_id = Integer.parseInt(itemMap.get(key));
// inflate the textview that shows the qty for this item on the expandablelist
barQty = (TextView) v.findViewById(R.id.qty_display);
// set the ok button to record teh quantity on press
ok.setOnClickListener(new OnClickListener() {
public void onClick(View viewParam) {
//inflate the input box that receives quantity from user
EditText fiQty = (EditText) myDialog.findViewById(R.id.fiQty);
// get the quantity and append the text on hte list item
String qty = fiQty.getText().toString();
barQty.setText("Qty X "+qty);
//open the database and save state
FoodIntake.this.application.getFoodIntakeHelper().open();
FoodIntake.this.application.getFoodIntakeHelper().storeFoodIntakeLog(current_selected_food_item_id,qty,visit_id,remote_visit_id);
String log = FoodIntake.this.application.getFoodIntakeHelper().getFoodIntakeLog(visit_id);
FoodIntake.this.application.getFoodIntakeHelper().close();
// append the main food intake list and close the dialog
list.setText("Food Intake Log:\n\n"+log);
myDialog.cancel();
}
});
The above code opens a dialog, accepts a value for quantity, appends the list element to reflect this, also saves to database and sets a textview with the selected item and quantity.
Sorry to just dump a whole load of code, but this has me stumped and hopefully someone can help.
Thanks
Kevin
Android reuses dialogs. So the behavior you are seeing could be a result of that. You could use a activity managed dialog and use onPrepareDialog() to update dialog contents.
I don't think the problem is with the dialogs. I had the same problem in my project and couldn't fix it. I think the ExpandableListView has a bug when opening children. I had only one child per group and when I expand a group, the child moves to another group. After testing, I found out that when I expand the children are reloaded.

Categories