androidandroid-fragmentsandroid-4.4-kitkatandroid-5.1.1-lollipopchild-fragment

ChildFragmentManager.findFragmentByID() returns null on android 4.4.2


I developed an app, that uses Fragments as part of a Fragment.

public class LoginFragment extends Fragment
   EditTextWithCameraButtonFrag userNameFrag;
   EditTextWithCameraButtonFrag passwordFrag;

 public void onActivityCreated(Bundle savedInstanceState) {
     super.onActivityCreated(savedInstanceState);
     userNameFrag = (EditTextWithCameraButtonFrag)getChildFragmentManager()
            .findFragmentById(R.id.fragment_username);
     passwordFrag = (EditTextWithCameraButtonFrag) getChildFragmentManager()
            .findFragmentById(R.id.fragment_password);

EditTextWithCameraButtonFrag is a subtype of Fragment. This code works like a charm, running on android 5.1.1. However, running it on Android 4.4.2 returns in userNameFrage and passwordFrag being null. So it seems, that the returned Child FragmentManager does not find the fields.

Is there any thing to consider when using getChildFragmentManager()with 4.4.3?

Thanks in advance!

EDIT: This is the main fragment's XML:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/huge"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/login_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:gravity="center"
        android:textColor="@color/white"
        android:textSize="40dp" />

    <fragment
        android:id="@+id/fragment_username"
        android:name="com.example.app.fragments.EditTextWithCameraButtonFrag"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <fragment
        android:id="@+id/fragment_password"
        android:name="com.example.app.fragments.EditTextWithCameraButtonFrag"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />



    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginEnd="@dimen/huge"
        android:layout_marginStart="@dimen/huge"
        android:layout_marginTop="@dimen/normal"
        android:padding="@dimen/half"
        android:text="Login" />
</LinearLayout>

And this the sub fragment's:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/editText_with_button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<EditText
    android:id="@+id/text_input_field"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:alpha="0.75"
    android:background="@drawable/edit_text_login_top"
    android:inputType="text"
    android:padding="@dimen/normal" />

<Button
    android:id="@+id/scan_text_view"
    android:layout_width="wrap_content"
    android:background="@android:color/transparent"
    android:layout_height="wrap_content"
    android:layout_alignEnd="@+id/text_input_field"
    android:layout_alignTop="@+id/text_input_field"
    android:layout_alignBottom="@+id/text_input_field"
   />

</RelativeLayout>

Solution

  • I just solved it- kinda. After a LOT of reading it seems like it's possible to declare nested fragments via XML, but is not best practice.

    So I decided to include FrameLayouts in the XML, and add the nested Fragments via FragmentTransaction.

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center" >
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/huge"
        android:orientation="vertical" >
    
        <TextView
            android:id="@+id/login_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:gravity="center"
            android:textColor="@color/white"
            android:textSize="40dp" />        
    
        <FrameLayout 
            android:id="@+id/fragment_username"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <FrameLayout
            android:id="@+id/fragment_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/login_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/huge"
            android:layout_marginStart="@dimen/huge"
            android:layout_marginTop="@dimen/normal"
            android:padding="@dimen/half"
            android:text="Login" />
    </LinearLayout>
    
    </RelativeLayout>
    

    And in the main fragment's onCreate:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // create userNameFrag
        EditTextWithCameraButtonFrag userfragment = new EditTextWithCameraButtonFrag();     
        getChildFragmentManager().beginTransaction().replace(R.id.fragment_username, userfragment).commit();
        // create passwordFrag
        EditTextWithCameraButtonFrag passfragment = new EditTextWithCameraButtonFrag();     
        getChildFragmentManager().beginTransaction().replace(R.id.fragment_password, passfragment).commit();
    
    }
    

    This seems to work pretty good and- another plus- I also got rid of the the duplicate id bug.