I have noticed that Android code is being executed by chunks, take this code for example
actionButton.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
revealButton.setVisibility(View.VISIBLE);
final LayoutInflater inflater = getLayoutInflater();
for(int i = 0; i <= 50; i++)
{
View child = inflater.inflate(R.layout.item, mainLinear, false);
mainLinear.addView(child, 2);
}
}
});
The Reveal button is not being visible untill the rest of the code is completed and delivered which in this case takes a second or two. So i tried to put it in chunks of code like:
{
revealButton.setVisibility(View.VISIBLE);
}
{
final LayoutInflater inflater = getLayoutInflater();
for(int i = 0; i <= 50; i++)
{
View child = inflater.inflate(R.layout.item, mainLinear, false);
mainLinear.addView(child, 2);
}
}
I have also tried to make a two different static method trying to go too far to get this right which resulted in the same behaviour. The problem comes when i need to do some work but have to update the UI with instant results.
What is it that you're trying to do, exactly?
From the code it looks as if you're trying to render a list of views and show a reveal button to the user. Is that correct?
Either way, it seems to me the reason it's not updating immediately is because all the instructions are being executed on the same thread, which seems to be the Main Thread, so it will only update after it leaves the onClick block.
But I can't be sure on my answer. Could you give more details as to what you want to do, exactly? Is it to render a list of sorts or something else?
Related
I need to add 5 Input fields (EditText) dynamically one by one on button click and want to take values from them and store them into database using Room Persistence with MVVM.
Here I'm adding the view dynamically
private void addEditTextView() {
View inputView = getLayoutInflater().inflate(R.layout.row_edit_text, null, false);
EditText val1 = inputView.findViewById(R.id.input_value_1);
binding.layoutList.addView(inputView);
}
Any suggestion would be very helpful.
Thank you in advance.
Add view based on child count
private void addEditTextView() {
if (binding.layoutList.getChildCount() <= 5) {
View inputView = getLayoutInflater().inflate(R.layout.row_edit_text, null, false);
EditText val1 = inputView.findViewById(R.id.input_value_1);
binding.layoutList.addView(inputView);
}
}
"When I clicked Add button it is adding input field one by one, this code is working but I just want to limit for 5 fields not more not less and take values from them."
If you want to add exactly 5 fields on button click I recommend designing a fragment with the 5 fields in place, then when the button is clicked, inflate the fragment into your parent view. Then code the fragment appropriately with the data you're working with.
Then if you wanted, you could deflate the fragment on button click to clear the view or add some other way to clear the fragment when you want. Much easier than what you're doing currently in my own opinion.
You might as well include a submit button in your fragment assuming this is some kind of form.
You can simply define an integer and increase it every time you add the EditText but you should check if your integer is less than 5 everytime the method is called.
Example
private void addEditTextView() {
int count = 0;
if (count < 5){
View inputView = getLayoutInflater().inflate(R.layout.row_edit_text, null, false);
EditText val1 = inputView.findViewById(R.id.input_value_1);
binding.layoutList.addView(inputView);
count++;
}
}
I've encountered a problem to get all the values from my dynamic view. I need all of the value from each row so I can get the right answer for my calculation. For now, the output for the calculation only read the last value that input by the user and give me the wrong answer. I've tried several solutions but they are not working for me. I really appreciate your help since I'm not an expert.
this is the picture for my problem
int valueActLength = Integer.parseInt(actualLength.getText().toString());
for (int i = 0; i < parentTableLayout.getChildCount(); i++) {
View row = parentTableLayout.getChildAt(i);
EditText lengthInput = row.findViewById(R.id.length_input);
EditText inputQuantity = row.findViewById(R.id.input_qty);
int inputQty = Integer.parseInt(inputQuantity.getText().toString());
int requireLength = Integer.parseInt(lengthInput.getText().toString());
//this is the code for creating new row
public void addView() {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View w = inflater.inflate(R.layout.rod_input, null);
parentTableLayout.addView(w);
I've solve the problem. Thank you
I have an Activity with two layouts, both implemented in R.layout.main. The first one is a Relative Layout with the app's main screen, and the other is a Table Layout, holding a kind of Preferences Screen. Normally, the first one is set to visible, and the second one to gone. By clicking a button I make the Relative Layout gone, and the Table Layout visible.
And here starts my problem, I wanted to set a OnClickListener to that Table Layout (which is actually an array of buttons).
I tried something like:
final TableLayout table = (TableLayout)findViewById(R.id.tab);
table.setOnClickListener(new OnClickListener(){
public void onClick(View arg){
Button clickedButton = (Button)arg;
String t = (String) clickedButton.getTag();
Toast toast = Toast.makeText(getApplicationContext(),t,Toast.LENGTH_SHORT);
toast.show();
}
});
Obviously, it doesn't work.
I'm quite new to Android programming, and I've been looking for a suitable solution for the whole day without any results.
It couldn't work because you are first trying to cast a TableLayout to a button...
if your TableLayout is only containing buttons you could do something like:
TableLayout yourRootLayout = findView....
int count = yourRootLayout.getChildCount();
for(int i = 0; i < count; i++){
View v = yourRootLayout.getChildAt(i);
if(v instanceof TableRow){
TableRow row = (TableRow)v;
int rowCount = row.getChildCount();
for (int r = 0; r < rowCount; r++){
View v2 = row.getChildAt(r);
if (v2 instanceof Button){
Button b = (Button)v2;
b.setOnClickListener(this);
}
}
}
}
and let your activity implement OnClickListener. Just copy your Existing onClick into Activity itself...
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.
I started my own android app a few days ago since I needed a mobile application to store a bunch of data I collect in the hospital.
I'm pretty new to Java and android environment, although it seems easy to understand and very similar to C++.
Anyway, my application has a bunch of "EditText" and radio buttons and my question is:
How can I iterate through all those widgets (EditTexts and radio buttons)?
In .NET you could do a "for each element in container " loop but I can't seem to find a way to do this in Java/android environment.
Note: I don't know how many "widgets" exist in the activity, since some are created dinamicaly, others are hardcoded and some others show if some user preferences are set
Any help or hint would be appreciated.
for (int i = 0; i < rootView.getChildCount(); i++)
rootView.getChildAt(i)
Note that this will return View-s, you will have to check at runtime exactly what type of View you are currently looking at
It works.
Regarding the View type (ie Spinner, radioButton, EditText, etc) we can tag each type we want to parse in the Layout XML file and then add a conditional, ie:
if (Widget_Tag != null){
View Current_Widget = (View) rootView.getChildAt(i);
String Widget_Tag = (String) Current_Widget.getTag();
if (Widget_Tag.equals("MyEdiText")) {
//do something
}
}
the if (Widget_Tag != null){ is to prevent NullPointReferences. You can also doi it with a Try / Catch.
You can try this code:
LayoutInflater inflater = getLayoutInflater();
LinearLayout l = (LinearLayout) inflater.inflate(R.layout.main, null);
ViewGroup Current_Widget = (ViewGroup)l.getRootView();
for (int i = 0; i < Current_Widget.getChildCount(); i++)
Current_Widget.getChildAt(i);