Search code examples
javaandroidandroid-layoutandroid-fragmentsandroid-constraintlayout

Unable to scroll a Fragment added dynamically (Java)


I am developing an app where I need to use 2 fragments in an activity. Based on the choice made on the first fragment, the second one will be shown. The problem is that the second fragment is not scrolling down, being cut off by the end of the screen.

Here is the XML of the activity that contains the "fixed" and the the dynamically inserted fragments (activity_inspection.xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.InspectionActivity"
    android:padding="@dimen/margins">

    <fragment
        android:id="@+id/chooseItemMemorial"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        class="com.xxxx.xxxxx.fragments.InspectionMemorial"/>

    <FrameLayout
        android:id="@+id/show_fragment_selected"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/chooseItemMemorial"
        android:layout_marginTop="@dimen/top_margins"/>

</androidx.constraintlayout.widget.ConstraintLayout>

And here is a snippet of one of the fragments that I want to insert dinamically into my activity: (fragment_external_access.xml)

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="vertical"
    tools:context=".fragments.ExternalAccessFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
/** here goes the rest of the code**/

EDIT: What I want to achieve is for the first fragment, added via the <fragment> tag, to stay fixed on the screen while the second one, added dynamically via code, is able to be scrolled if necessary.

I've tried to use ScrollView and NestedScrollView without success. But that might be for some silly mistake, like forgetting to add a tag. Since I am new to android programming, every single bit of help will be appreciated.

To end this (and because it might be related), this is the java code I am using to add this fragment:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_external_access, container, false);
    }

Solution

  • The problem is that the top fragment (First Fragment) can be greedy so that it can take up the entire screen and the reason is that its height is wrap_content, so it can take as much as it contains as it lacks of a bottom constraints.

    And in this case the bottom fragment can be partially shown or even hidden beneath the screen.

    The same applies if the bottom fragment has bigger content, the top fragment will be partially/totally hidden due to the wrap_content of the bottom fragment.

    So you need to limit the height of both fragments to not use wrap_content.

    Here I will use app:layout_constraintHeight_max attribute for the top fragment, but you have to handle if its contents can be greater than that value; a ScrollView is one of the possible options like you did in the Bottom fragment (Second Fragment).

    And set the height of both fragments to match constraints.

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="@dimen/margins"
        tools:context=".activities.InspectionActivity">
    
        <fragment
            android:id="@+id/chooseItemMemorial"
            class="com.xxxx.xxxxx.fragments.InspectionMemorial"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHeight_max="100dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <FrameLayout
            android:id="@+id/show_fragment_selected"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_marginTop="@dimen/top_margins"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/chooseItemMemorial" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>