Basically, I have a LinearLayout that holds a random amount of horizontal LinearLayouts, and in each of the horizontal LinearLayouts there's a TextView and an EditText. I want to be able to get the value of each EditText children of the master LinearLayout.
Sorry if it's confusing, I'm no good at explaining things!
Could I just set the same ID for each of the EditTexts then use findViewById, or would that only return the first instance of an EditText?
Thanks,
Alex.
LinearLayout ll = //Your Layout this can be any Linear or Relative layout
//in which you added your spinners at runtime ;
int count = ll.getChildCount();
for(int i =0;i<count;i++)
{
View v = ll.getChildAt(i);
if(v instanceof Spinner)
{
// you got the spinner
EditText s = (EditText) v;
Log.i("Item selected",s.getText().toString());
}
}
findViewById returns only the first view with the given id. You're going to have to traverse the view hierarchy yourself, at least until you get down to each horizontal linear layout. You'll find the methods ViewGroup.getChildCount() and ViewGroup.getChildAt(int) useful for this.
You would need to call findViewById on each of the LinearLayouts. If you do this, you can set the same ID for each EditText.
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 have a lot of textviews in my program .
I want the numbers inside these textviews to be separated by 3 to 3 .
Should I write code for any textview?
Is there a way to write code once and use it for the whole program?
Thank You .
I am not a Java developer, but I'm thinking you could write a class that inherits from the textview class and override the method that sets the text to separate the numbers. Then you'd just need to replace the class of your textview objects with your new class, which should be quite easy.
It dependes on the type of Layout. For example in a simple LinearLayout you can proceed like this :
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.mylayout);
for(int k = 0 ; k < n ; k++){
TextView tView = new TextView(context);
tView.setText(k*3)
linearLayout.addView(tView);
}
Or another way could be iterating on all Views that are TextView setting the text. For example, assuming that mylayout is the parent view :
for(int k=0; k < mylayout.getChildCount(); k++ ){
if( mylayout.getChildAt(k) instanceof TextView ){
((TextView)mylayout.getChildAt(k)).setText(k*3);
}
}
In order to use your own TextView style, you can creat one by extend the TextView class and then use it in the xml activity
See example how to extend:
How to make a custom TextView?
In the constractor of your new TextView, you can add TextWacher by addTextChangedListener method to perform your number seperation.
See example how:
android on Text Change Listener
You have to use DecimalFormat and the grouping pattern
thanks in advance.
I have multiple TableRow objects in an Android app, each of which contains exactly two EditTexts. I want to have the contents and quantity of editTexts saved and restored when I open/close the app and so I need to have a way to set the text of the EditTexts, but this is where the problem is.
Android Studio is saying "Cannot Resolve Symbol 'setText'":
//will loop through each of the TableRows in a tableRowHolder(no problem yet):
for (int i = 0; i < tableRowHolder.getChildCount() && tableRowHolder.getChildAt(i) instanceof android.widget.TableRow; ++i) {
//set tableRow to be the i-th child in tableRowHolder (no problem yet)
TableRow tableRow = (TableRow) tableRowHolder.getChildAt(i);
//where the problem is("setText" is red), I don't think Java recognises that "tableRow.getChildAt(1)" is an EditText, even though it always will be.
tableRow.getChildAt(1).setText();
//this however, is perfectly fine:
EditText et = new EditText(
et.setText("");
}
To recap, I have:
A tableRow object always containing exactly two EditTexts
and my problem is that:
Java seems to not recognise that I am asking for .setText() on a EditText
Thanks so much in advance.
Just like you're casting your TableRow out of the TableRowHolder, you need to cast the View child to an EditText before you can call its methods.
TableRow tableRow = (TableRow) tableRowHolder.getChildAt(i);
((EditText) tableRow.getChildAt(1)).setText("Some Text");
You could optionally wrap your calls inside an instanceof if-block to avoid any ClassCastExceptions if there's any chance that the View may not be an EditText always.
View child = tableRow.getChildAt(1);
if (child instanceof EditText) {
EditText et = (EditText) child;
et.setText("Some Text");
}
Currently I am using a RecyclerView with a LinearLayout Manager and an EditText as HeaderView for filtering the content of the list.
I would like to hide the EditText if the content of the RecyclerView is smaller than the RecyclerView itself.
Is there any way to "ask" the Recyclerview or the LayoutManager if its content can scroll?
Thank you all.
RecyclerView can't scroll anymore when the item at last position is completely visible.
In condition that would sound as:
mRecyclerView.getLayoutManager().findLastCompletelyVisibleItemPosition() == mRecyclerViewAdapter.getItemCount() - 1;
An answer that also accounts for dynamic screen sizes.
mRecyclerView.getViewTreeObserver().addOnScrollChangedListener(() -> {
if (mRecyclerView.canScrollVertically(1) && //still scrolling
mRecyclerView.computeVerticalScrollRange() >= mRecyclerView.getHeight()) { //Big enough for scrolling
return; //we still scrolling so early out.
}
DoMyFunction();
}
do you mean this:
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html#canScrollVertically()
if(recyclerView.getLayoutManager().canScrollVertically()){
// do stuff
} else{
// do other stuff
}
I am adding a View to a RelativeLayout at runtime, which is working fine, but now I would like to display a TextView just to left of this View but I am unable to retrieve the Top or Left of this View in order to calculate the TextView's position.
The code I have is
private void displayGuitar() {
for (GuitarString guitarString: guitar.getGuitarStrings()) {
GuitarStringView guitarStringView = new GuitarStringView(context, attributeSet, guitarString);
this.addView(guitarStringView);
// Add Note name
TextView noteNameView = new TextView(context);
RelativeLayout.LayoutParams noteParams =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
noteParams.addRule(LEFT_OF, guitarStringView.getId());
Log.w("string top", String.valueOf(guitarStringView.getTop()));
Log.w("string left", String.valueOf(guitarStringView.getLeft()));
noteParams.setMargins(0, 0, 2, 0);
noteNameView.setLayoutParams(noteParams);
noteNameView.setText(guitarString.getTunedNote().getNoteName(0));
this.addView(noteNameView);
}
}
This results in the TextViews all appearing on top of each other (in the correct X position) but I can't set the Top margin as both of the Log statements return 0. How can I determine what the Top position of the GuitarStringView is?
EDIT
Following advice from laalto I have now generated ID for the guitarStringView and confirmed it's being assigned. However, if I use LEFT_OF, RIGHT_OF etc the TextViews are not displayed, but if I use ALIGN_PARENT_RIGHT they're displayed fine? Code is now as follows
private void displayGuitar() {
for (GuitarString guitarString: guitar.getGuitarStrings()) {
GuitarStringView guitarStringView = new GuitarStringView(context, attributeSet, guitarString);
int viewId = guitarStringView.generateViewId();
guitarStringView.setId(viewId);
this.addView(guitarStringView);
// Add Note name
TextView noteNameView = new TextView(context);
RelativeLayout.LayoutParams noteParams =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
noteParams.addRule(RelativeLayout.LEFT_OF, viewId);
noteNameView.setLayoutParams(noteParams);
noteNameView.setText(guitarString.getTunedNote().getNoteName(0));
this.addView(noteNameView);
}
}
EDIT 2
The accepted fix didn't work at first as I hadn't override the onMeasure() of my GuitarStringView which according to the documentation defaults to 100x100.
First, your guitarStringView doesn't have an id and getId() will return -1, that is, NO_ID. The LEFT_OF rule therefore doesn't work as it doesn't refer to any actual id. To fix that, just set some id to the view.
Second, the view has not been measured nor laid out yet so that's why size and position come out as zeros.
using addRule with any of LEFT_OF, RIGHT_OF or BELOW the TextView is no longer displayed at all
Possibly the string view is already taking up all horizontal space. Add another constraint such as ALIGN_PARENT_LEFT to make the text view left edge align with parent relative layout's left edge.
You said "at runtime", which means you're potentially invoking this method in onCreate, or onResume. These methods should start behaving as expected in onWindowFocusChanged(boolean).
See this other question:
getRight, getLeft, getTop returning zero