Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Custom class for setting the max height of a NestedScrollView does not work (there is no scrollbar)

I am creating a custom class to set the max height of a NestedScrollView, based on the answer provided in this StackOverflow question:

How to set the Maximum Height for a NestedScrollView in Android?

However, when I include the custom class (MaxHeightNestedScrollView) in my activity_main.xml code layout, there is no scrollbar appearing when the TextView inside the MaxHeightNestedScrollView exceeds the defined max height. Below is the code for MaxNestedScrollView:

import android.content.Context;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.NestedScrollView;

public class MaxHeightNestedScrollView extends NestedScrollView {

    private int maxHeight = -1;

    public MaxHeightNestedScrollView(@NonNull Context context) {
        super(context);
    }

    public MaxHeightNestedScrollView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MaxHeightNestedScrollView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public int getMaxHeight() {
        return maxHeight;
    }

    public void setMaxHeight(int maxHeight) {
        this.maxHeight = maxHeight;
    }

    public void setMaxHeightDensity(int dps){
        this.maxHeight = (int)(dps * getContext().getResources().getDisplayMetrics().density);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

Below is the code for the attrs.xml file in the values folder:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MaxHeightNestedScrollView">
        <attr name="maxHeight" format="dimension" />
    </declare-styleable>
</resources>

Below is the code for activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff"
        android:layout_weight="1"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <TextView
                android:id="@+id/textView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Lorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
\nLorem ipsum\nLorem ipsum\nLorem ipsum" />

            <com.example.testgradle.MaxHeightNestedScrollView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                app:maxHeight="130dp">
                <TextView
                    android:id="@+id/textView2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textSize="20dp"
                    android:textColor="#000000"
                    android:text="Lorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
\nLorem ipsum\nLorem ipsum\nLorem ipsumLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
\nLorem ipsum\nLorem ipsum\nLorem ipsum" />
            </com.example.testgradle.MaxHeightNestedScrollView>

            <TextView
                android:id="@+id/textView3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Lorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
\nLorem ipsum\nLorem ipsum\nLorem ipsum" />
        </LinearLayout>
    </ScrollView>
</LinearLayout>
like image 268
Adam Lee Avatar asked Jan 14 '20 04:01

Adam Lee


People also ask

How to add scroll view android?

In order to place multiple views in the scroll view, one needs to make a view group(like LinearLayout) as a direct child and then we can define many views inside it. A ScrollView supports Vertical scrolling only, so in order to create a horizontally scrollable view, HorizontalScrollView is used.

How to make scrollable view in android studio?

To add multiple views within the scroll view, make the direct child you add a view group, for example LinearLayout , and place additional views within that LinearLayout. Scroll view supports vertical scrolling only. For horizontal scrolling, use HorizontalScrollView instead.

How do I use NestedScrollView?

NestedScrollView is just like ScrollView, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. It is enabled by default. NestedScrollView is used when there is a need for a scrolling view inside another scrolling view.

What is difference between nested ScrollView and NestedScrollView?

Nested scrolling is enabled by default. Show activity on this post. NestedScrollView is just like ScrollView, but in NestedScrollView we can put other scrolling views as child of it, e.g. RecyclerView. But if we put RecyclerView inside NestedScrollView, RecyclerView's smooth scrolling is disturbed.

Why use nestedscrollview instead of ScrollView for vertical scrolling in Android?

Android Engineeres are recommending that you use NestedScrollView instead of ScrollView for vertical scrolling. This is because the latter offers greater user interface flexibility and support for the material design scrolling patterns. A scrollview as a class resides in the android.widget package and derives from FrameLayout:

How to add a linearlayout inside a nestedscrollview?

Add the NestedScrollView and inside NestedScrollView add a LinearLayout and inside LinearLayout add two TextView to display the strings which are created inside the strings.xml file and one Button between the TextView. Here is the code for the activity_main.xml file. One can add as many views inside the NestedScrollView’s LinearLayout

How can I adjust the scrollbar For every increment of scroll?

Even with items only varying in height a small amount, the scrollbar thumb can be jarring. To adjust how the scrollbar behaves for every increment of scroll for the solution we pursued, we have to use a custom LayoutManager.

Can Android scrollbars handle dynamically-sized items in recyclerview?

As an Android developer on The Wall Street Journal, handling lists with content of varying heights is a common use case on Android. Unfortunately, a scrollbar that doesn’t behave erratically is not well supported out of the box when working with dynamically-sized items in a RecyclerView.


1 Answers

Your MaxHeightNestedScrollView is incomplete, as it does not specify how to use maxHeight attribute from xml. Use below modified MaxHeightNestedScrollView class(Difference are commented out).

MaxHeightNestedScrollView.java

public class MaxHeightNestedScrollView extends NestedScrollView {

private int maxHeight = -1;

public MaxHeightNestedScrollView(@NonNull Context context) {
    this(context, null, 0); // Modified changes
}

public MaxHeightNestedScrollView(@NonNull Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0); // Modified changes
}

public MaxHeightNestedScrollView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context, attrs, defStyleAttr); // Modified changes
}

 // Modified changes
private void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr){
    final TypedArray a = context.obtainStyledAttributes(
            attrs, R.styleable.MaxHeightNestedScrollView, defStyleAttr, 0);
    maxHeight = 
    a.getDimensionPixelSize(R.styleable.MaxHeightNestedScrollView_maxHeight, 0);
    a.recycle();
}

public int getMaxHeight() {
    return maxHeight;
}

public void setMaxHeight(int maxHeight) {
    this.maxHeight = maxHeight;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (maxHeight > 0) {
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}


Also to show scrollbar in NestingScrollView just add android:scrollbars="vertical" attribute to your MaxHeightNestedScrollView view in xml.
After changes your layout file will look like.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:layout_weight="1"
    android:fillViewport="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Lorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
            \nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem 
            ipsum\nLorem ipsum
            \nLorem ipsum\nLorem ipsum\nLorem ipsum" />

        <com.example.testgradle.MaxHeightNestedScrollView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:scrollbars="vertical" // Modified changes
            app:maxHeight="130dp">
            <TextView
                android:id="@+id/textView2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                android:textColor="#000000"
                android:text="Lorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
                \nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
                \nLorem ipsum\nLorem ipsum\nLorem ipsumLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
                \nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
                \nLorem ipsum\nLorem ipsum\nLorem ipsum" />
        </com.example.testgradle.MaxHeightNestedScrollView>

        <TextView
            android:id="@+id/textView3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Lorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
            \nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum\nLorem ipsum
            \nLorem ipsum\nLorem ipsum\nLorem ipsum" />
    </LinearLayout>
</ScrollView>
</LinearLayout>

Hope this help.

like image 83
Akhilesh Kumar Avatar answered Oct 21 '22 23:10

Akhilesh Kumar