2

I know that ListView objects shouldn't be put into a ScrollView. However, I can't come up with a proper approach to this situation: I have two layouts, both including a ListView, one directly below the other. I want all elements of both lists to be output; naturally, that should take more than the screen can offer, so I want to make the result scrollable, so, as I thought, I should put both into a ScrollView, but this doesn't work well with ListView (they only display one item each) and is considered a bad practice. How do I go about this?

Here's a mock up of what I mean:

enter image description here

Two lists, and the entirety of the second list can't fit into the screen, so I'd like to scroll it, and when I do, the second header ('Example2') scrolls up and doesn't stay in place, as opposed to the default behaviour of having the second list content scrolled.

What I have now is:

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="vertical">

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/example1_header"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <ListView
                android:id="@+id/example1_list_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/example1_header" />

        </RelativeLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/example2_header />

            <ListView
                android:id="@+id/example2_list_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </LinearLayout>

    </LinearLayout>
Karan Mehta
  • 1,442
  • 13
  • 32
ugh nope
  • 23
  • 6

3 Answers3

1

hi i think you should use NestedScrollView instead of using ScrollView and it will solve your problem

  • I don't quite get it. I have put my entire layout inside an `androidx.core.widget.NestedScrollView` tag. Now each `ListView` displays only one item; on top of that, neither of those `ListView`s is scrollable, which they both would be had I put them inside a `ScrollView`. I don't think it's important but I'm testing this in an emulator. – ugh nope Feb 20 '20 at 14:35
  • @ughnope Make sure your `list_item_row` layout's height to `wrap_content` or any user defined size? – mixin27 Feb 21 '20 at 04:43
  • @ODxNorm I have set it to `wrap_content` for both lists, still only getting one item in each list. – ugh nope Feb 21 '20 at 09:31
  • @ughnope huh? Why you don't use `RecyclerView`? I want to advice to use it. Try again by using `RecyclerView` instead of `ListView`. – mixin27 Feb 21 '20 at 09:34
1

Maybe you can use NonscrollListView custom class that extends ListView.

public class NonScrollListView extends ListView {
    public NonScrollListView(Context context) {
        super(context);
    }
    public NonScrollListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
}

After that you can use it, inside your Scrollview. For example (or you can put another Widget on Scrollview):

<ScrollView
    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_toBottomOf="@+id/textView">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <com.unicode.teslibrary.NonScrollListView
            android:id="@+id/bankList"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </com.unicode.teslibrary.NonScrollListView>

        <com.unicode.teslibrary.NonScrollListView
            android:id="@+id/bankSecondList"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </com.unicode.teslibrary.NonScrollListView>
    </LinearLayout>

</ScrollView>
Rembulan Moon
  • 338
  • 3
  • 11
0
If you put inside ScrollView then all content inside this will scroll.

If I understood your problem correctly then you can try this. This divides your screen by 50/50 for 2 2 linear layouts

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_weight="2"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/example1_header"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Example1" />

        <ListView
            android:id="@+id/example1_list_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/example1_header"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="example2_header" />

        <ListView
            android:id="@+id/example2_list_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp" />

    </LinearLayout>

</LinearLayout>
Kishan Maurya
  • 3,356
  • 8
  • 21
  • This results in 2 scrollable lists, which is nice, but what I'd like is 2 lists which are already expanded and displaying every element there is, and when I scroll, I don't scroll each list separately, I scroll the entire layout that contains them. Imagine there was text instead of lists. When I scroll the text down, I want the text from the 'Example1' section to disappear, the 'Example2' header to move up and for the rest of 'Example2' section text to appear. I want the same behavior with lists. Also since my outer layout already has a weight, wouldn't it be better to avoid nested weights? – ugh nope Feb 20 '20 at 14:52
  • Okay... Just do one thing.... Put both list inside NestedScrollView and make scrolling of both list disable... By using tag nestedScrollingEnable false. – Kishan Maurya Feb 20 '20 at 15:16
  • Alright, but this leaves only one item displayed in each `ListView`, and I want them both expanded. I tried to use a method from this answer: https://stackoverflow.com/a/3495908 but it just displays the first list in its entirety, allows it to be scrolled (in the way that I expect it, not just the `ListView` object itself but the entire layout, so the `NestedScrollView` must've helped, thanks) but doesn't display neither the second `ListView` nor even the second header. – ugh nope Feb 20 '20 at 16:03
  • Please share the layout you are inflating in listview. – Kishan Maurya Feb 20 '20 at 16:07
  • Um, I'm not sure how I should go about posting code in the comments, so I put it on pastebin. For example1: https://pastebin.com/XM3vvxKe, for example2: https://pastebin.com/PB4uiAX2. Hope I understood you correctly: you mean the layout that is used for each item in the adapter, right? – ugh nope Feb 20 '20 at 16:28
  • make in both layout. – Kishan Maurya Feb 20 '20 at 16:30
  • This didn't change anything for me, still one item in each list, and also I don't quite get how modifying a layout for a single item in the adapter would affect how much elements get displayed? – ugh nope Feb 20 '20 at 16:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/208200/discussion-between-kishan-maurya-and-ugh-nope). – Kishan Maurya Feb 20 '20 at 17:01