22

can anyone help me with coding a method to get all EditTexts in a view? I would like to implement the solution htafoya posted here: How to hide soft keyboard on android after clicking outside EditText?

Unfortunately the getFields() method is missing and htafoya did not answer our request to share his getFields() method.

Community
  • 1
  • 1
Reto
  • 1,660
  • 3
  • 19
  • 31

5 Answers5

37

EDIT

MByD pointed me to an error, thus making my answer almost identical to that of blackbelt. I have edited mine to the correct approach.


You could do a for-each loop and then check if each view is of the type EditText:

ArrayList<EditText> myEditTextList = new ArrayList<EditText>();

for( int i = 0; i < myLayout.getChildCount(); i++ )
  if( myLayout.getChildAt( i ) instanceof EditText )
    myEditTextList.add( (EditText) myLayout.getChildAt( i ) );

You could also, instead of having a list of EditTexts, have a list of ID's and then just add the id of the child to the list: myIdList.add( child.getId() );


To access your layout you need to get a reference for it. This means you need to provide an ID for your layout in your XML:

<LinearLayout android:id="@+id/myLinearLayout" >
   //Here is where your EditTexts would be declared
</LinearLayout>

Then when you inflate the layout in your activity you just make sure to save a reference to it:

LinearLayout myLinearLayout;

public void onCreate( Bundle savedInstanceState ) {
   super( savedInstanceState );
   setContentView( R.layout.myLayoutWithEditTexts );

   ...

   myLinearLayout = (LinearLayout) findViewById( R.id.myLinearLayout );
}

You then have a reference to your the holder of your EditTexts within the activity.

kaspermoerch
  • 16,127
  • 4
  • 44
  • 67
  • Are you sure this line is a valid one: `for( View child : myLayout )` ? – MByD Oct 17 '11 at 07:29
  • It appears I was a bit hasty in my response - as MByD says, the for-each loop is not valid for a View/Layout. – kaspermoerch Oct 17 '11 at 07:37
  • I am feeling like a noop right now, I cannot get your suggestion to work. I have coded several pages of android/java code so far but I am stuck here. I found out that I have to include java.util.list for the list type. But then Eclipse tells me that the `new List()` is not valid... And also I am wondering if the list type is compatible with the array `[]` htafoya's solution is expecting. Is this the same or do I have to change this to a list too? Thanks for your help! – Reto Oct 18 '11 at 07:50
  • Hmm, the `List` problem might be my error. Try changing it to an `ArrayList`. If you need an array instead of the list, you simply use `myList.toArray()` after you're done adding/removing from the list. The advantages of the list, is that it is dynamical which means there is no need for a fixed size like with a normal array. – kaspermoerch Oct 18 '11 at 07:55
  • Hopefully my last question: How can I access the layout? – Reto Oct 19 '11 at 06:17
  • Thanks! It is finally working for me. I could use your solution as posted and just had to replace `myEditTextList` by `textFields` – Reto Oct 20 '11 at 19:15
  • if you have more `EditText` elements, and you switch from one to other, your code causes a "screen jump", as the keyboard is rolling out and back on. Leaving focus sometimes (based on position of the element on screen) causes another type of "screen jump". Check my answer/solution for some improvements that help to prevent such unwanted behavior. – Ωmega Mar 16 '18 at 22:22
10

Here's a method I wrote to recursively check all EditText children of a ViewGroup, handy for a long sign-up form I had to do and probably more maintainable.

private EditText traverseEditTexts(ViewGroup v)
{
    EditText invalid = null;
    for (int i = 0; i < v.getChildCount(); i++)
    {
        Object child = v.getChildAt(i); 
        if (child instanceof EditText)
        {
            EditText e = (EditText)child;
            if(e.getText().length() == 0)    // Whatever logic here to determine if valid.
            {
                return e;   // Stops at first invalid one. But you could add this to a list.
            }
        }
        else if(child instanceof ViewGroup)
        {
            invalid = traverseEditTexts((ViewGroup)child);  // Recursive call.
            if(invalid != null)
            {
                break;
            }
        }
    }
    return invalid;
}

private boolean validateFields()
{   
    EditText emptyText = traverseEditTexts(mainLayout);
    if(emptyText != null)
    {
        Toast.makeText(this, "This field cannot be empty.", Toast.LENGTH_SHORT).show();
        emptyText.requestFocus();      // Scrolls view to this field.
    }
    return emptyText == null;
}
sleep
  • 4,855
  • 5
  • 34
  • 51
6

You can do it by calling View#getFocusables, which will return an arraylist of all focusable views in a View.

Then you can either check if they are EditTexts, with (instanceof) or act on all of them.

MByD
  • 135,866
  • 28
  • 264
  • 277
4

This Methods walks recursively through all ViewGroups and collects their TextViews. I use this to assign a new Color to all TextViews (even those embedded in predefined Widgets like Switch etc that make use of TextViews)

private HashSet<TextView> getTextViews(ViewGroup root){
    HashSet<TextView> views=new HashSet<>();
    for(int i=0;i<root.getChildCount();i++){
        View v=root.getChildAt(i);
        if(v instanceof TextView){
            views.add((TextView)v);
        }else if(v instanceof ViewGroup){
            views.addAll(getTextViews((ViewGroup)v));
        }
    }
    return views;
}
lynx
  • 479
  • 4
  • 10
0

Get all Edit Text in any type of layout.

public List<EditText> getAllEditTexts(ViewGroup layout){
        List<EditText> views = new ArrayList<>();
        for(int i =0; i< layout.getChildCount(); i++){
            View v =layout.getChildAt(i);
            if(v instanceof EditText){
                views.add((EditText)v);
            }
        }
        return views;
    }
NJY404
  • 349
  • 3
  • 14