androidxmlandroid-layoutandroid-include

Access all children elements of included layouts from main layout


I have a activity_main layout which looks like the following layout:

<RelativeLayout
    android:id = "@+id/wrapper"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content"
    android:layout_alignParentBottom = "true"
    android:layout_gravity = "bottom"
    android:gravity = "bottom">
    <include
        android:id = "@+id/call_to_action"
        layout = "@layout/call_to_action_layout"
        android:layout_width = "fill_parent"
        android:layout_height = "wrap_content"/>
    <include
        android:id = "@+id/status"
        layout = "@layout/status_layout"
        android:layout_width = "fill_parent"
        android:layout_height = "wrap_content"/>
</RelativeLayout>

Both of my included layouts look like these:

Here's the call_to_action_layout.xml

<LinearLayout
    android:id = "@+id/action_button_container"
    android:layout_height = "wrap_content"
    android:layout_width = "fill_parent"
    xmlns:android = "http://schemas.android.com/apk/res/android">

    <EditText
        android:id="@+id/edit_text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/edit_text_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />
</LinearLayout>

And the status_layout.xml

<LinearLayout
    android:id = "@+id/another_container"
    android:layout_height = "wrap_content"
    android:layout_width = "fill_parent"
    xmlns:android = "http://schemas.android.com/apk/res/android">

    <EditText
        android:id="@+id/edit_text_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <EditText
        android:id="@+id/edit_text_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />
</LinearLayout>

In MainActivity.java I am trying to set a property of all EditText that are present in my activity_main.xml. For that, I need to loop over and access every EditText present in my layout.

So here's what I've tried so far in MainActivity.java

RelativeLayout container = findViewById(R.id.wrapper);

for (int i = 0; i < container.getChildCount(); i++) {
    Log.d(TAG, "id: " + container.getChildAt(i));

    if (container.getChildAt(i) instanceof EditText) {
        EditText editText =
            (EditText) container.getChildAt(i);
        editText.setKeyListener(null);
    }
}

But because of <include> tag, I am not able to access all of the EditText in this code.

Is there any way to do this?

Note: Basically, all want to do is disable all the EditText present in my layout.


Solution

  • In your loop you're only iterating through first level children of your layout (call_to_action and status).

    You can either do two loops like this:

    ViewGroup call_to_action = findViewById(R.id.call_to_action)
    for (int i = 0; i < call_to_action.getChildCount(); i++)
    {
        Log.d(TAG, "id: " + call_to_action.getChildAt(i));
        if (container.getChildAt(i) instanceof EditText)
        {
            EditText editText =
                (EditText) call_to_action.getChildAt(i);
            editText.setKeyListener(null);
        }
    }
    
    ViewGroup status = findViewById(R.id.status)
    for (int i = 0; i < status.getChildCount(); i++)
    {
        Log.d(TAG, "id: " + status.getChildAt(i));
        if (status .getChildAt(i) instanceof EditText)
        {
            EditText editText =
                (EditText) status.getChildAt(i);
            editText.setKeyListener(null);
        }
    }
    

    Or create a recursive method like this one:

    public void removeKeyListeners(ViewGroup container){
    for (int i = 0; i < container.getChildCount(); i++)
        {
            Log.d(TAG, "id: " + container.getChildAt(i));
            if (container.getChildAt(i) instanceof EditText)
            {
                EditText editText =
                    (EditText) container.getChildAt(i);
                editText.setKeyListener(null);
            } else if (container.getChildAt(i) instanceof ViewGroup) {
                  removeKeyListeners((ViewGroup) container.getChildAt(i));
            }
        }
    }
    

    and call it for your layout:

    removeKeyListeners(container);
    

    Note: using ViewGroup here because all Layouts are subclasses of it.