Search code examples
javaandroidscrollviewandroid-constraintlayoutnestedscrollview

NestedScrollView not scrolling when adding TextViews programmatically


I'm including a chess board and pieces on one of the screens in my app, and I want to add a scrollable view underneath it to show the move notation when the user makes a move. I can add the text to the view, but no matter what I try, the view will not scroll.

I've researched the trouble other users have had with this problem extensively. I've included fillViewport="true" and layout_height="wrap_content" but neither of those solutions is working for me. I've played around with the margins of the nestedscrollview to no avail, and I've been having this issue for the past couple days and still haven't figured out what I'm doing wrong.

Here's the xml file:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="@+id/chessBoardScreen"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true"
    android:focusable="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".ChessBoardActivity"
    tools:showIn="@layout/app_bar_chess_board">

    <android.support.constraint.ConstraintLayout
        android:id="@+id/cl_parent"
        android:layout_width="wrap_content"
        android:layout_height="350dp"
        app:layout_constraintBottom_toTopOf="@+id/move_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/board"
            android:layout_width="wrap_content"
            android:layout_height="329dp"
            android:layout_marginTop="8dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/chess_board" />

        <android.support.constraint.ConstraintLayout
            android:id="@+id/cl"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

        </android.support.constraint.ConstraintLayout>

    </android.support.constraint.ConstraintLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/move_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:fillViewport="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/cl_parent">

        <android.support.constraint.ConstraintLayout
            android:id="@+id/move_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </android.support.constraint.ConstraintLayout>
    </android.support.v4.widget.NestedScrollView>

</android.support.constraint.ConstraintLayout>

And here's where I call the xml file in my application, this code is executed every time the user successfully makes a move on the chess board:

ConstraintLayout ml = findViewById(R.id.move_list);
        TextView tv = new TextView(ChessBoardActivity.this);

        float left = 34*density;
        float top;
        if(move == 'b') left += screenX/2.0;
        top = (-30+30*turns)*density;

        tv.setWidth((int)(screenX/2-34*density));
        tv.setHeight((int)(30*density));
        tv.setTranslationX(left);
        tv.setTranslationY(top);
        tv.setText(moveString);
        ml.addView(tv);

Any help figuring out this problem would be appreciated! Thank you :)

I expect the nestedscrollview to be scrollable when the textviews draw beyond the screen but within the limits of the view, but it's not scrolling at all.


Solution

  • EDIT:
    I just noticed the actual problem in the code. You are manually setting position using translation, doing so will NOT UPDATE height of parent layout that's why scrollview won't scroll. You should use LinearLayout so you don't have to calculate position and in case of two columns you can use GridLayout.

    OLD ANSWER: Call scrollView.invalidate() so scrollview can adjust to changes. If it doesn't work then call invalidate() on ConstraintLayout as well. If it still doesn't work, then also call requestLayout() as well.

     ml.addView(tv);
     ml.invalidate();
     NestedScrollView scrollView = findViewById(R.id.move_view);
     scrollView.invalidate();
     scrollView.requestLayout();