Non-scrollable ListView inside ScrollView
Asked Answered
G

5

76

I'm trying to make a layout like this:

The problem is that I don't want the ListViews to be scrollable. I want them to be as high as they need to and make the whole screen be scrollable. If I set the height of the ListView to wrap_content, that doesn't work. The only way to make it work is to set a specific height - but I don't know how many items will be in the ListView.

I know that I should not put ListView inside ScrollView - but I don't want the ListView to be scrollable, just to show all items.

Maybe there is a better way to make it work?

Grimbly answered 15/9, 2013 at 14:8 Comment(0)
T
163

You Create Custom ListView Which is non Scrollable

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();    
    }
}

In Your Layout Resources File

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fadingEdgeLength="0dp"
    android:fillViewport="true"
    android:overScrollMode="never"
    android:scrollbars="none" >

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

        <!-- com.Example Changed with your Package name -->

        <com.Example.NonScrollListView
            android:id="@+id/lv_nonscroll_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </com.Example.NonScrollListView>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/lv_nonscroll_list" >

            <!-- Your another layout in scroll view -->

        </RelativeLayout>
    </RelativeLayout>

</ScrollView>

In Java File

Create a object of your customListview instead of ListView like :
NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);

Tman answered 8/7, 2014 at 10:21 Comment(8)
When swapping this into an existing codebase, it's likely only the XML needs to be modified after the new class is added; most existing references casting the instance to (ListView) should still work fine.Spikelet
your logic is working perfectly for me.But when i enter into the layout that contains nonscrollListview ,that list is showing prior to the details that is displayed above the listview.So the user is compelled to scroll down to view the details that is displayed above the listview.Any solution???Randell
actually i am using nonscrollable ln my cart layout.The Cart layout contains this nonscrollable listview in middle and other details are showing above and below the listview.But when ever the layout is loaded, this list is projecting first and we have to scroll up and down to view the other details..hope you get it..Randell
What makes this custom listview non scrollable? I don't see any code that shuts off scrolling.Malchy
@Dedaniyahirenkumar, When android displays a layout containing the NonScrollListView, the parent ScrollView is scrolled to the top of the NonScrollListView, rather than the top of the ScrollView. (The user must scroll up to the ScrollView contents that come before the NonScrollListView.) This happens for EXACTLY and AT_MOST measurement modes, and for any integer height passed to makeMeasureSpec()Unscramble
@Dedaniyahirenkumar, However, if the measurement mode is switched to UNSPECIFIED, the parent ScrollView stays at scroll Y=zero (the expected behaviour). Obviously the NonScrollListView does not display its entire contents in this case, however.Unscramble
NonScrollListView didn't notify adapter every time i scrolled the scrollview top and down, eg, when i put time change with seconds when scroll the listview this time will change , but in this NonScrollListView the time not change, programmatically this NonScrollListView didn't recycle it's viewChem
I tried this approach but failed. However, I could succed only after I replaced ScrollView with NestedScrollView.Bohemian
S
12

There is no need to use a listview at all.

If you really think about it, a listview can be replaced with a LinearLayout in your case. The Adapter would be the same, however instead of attaching the adapter with your listview, simply call the getView function of the adapter in a for loop on your data and add the retrieved views to your vertical linearlayout.

However this approach is only recommended if you have a small number of items in your list and your display representation of those items is not memory intensive.

Saez answered 15/9, 2013 at 15:14 Comment(3)
i use linear layout instead of list view, it work but items that there are not space do not seen! i use linear layout in parentRelativity
LinearLayout isn't a fair replacement for ListView when you want to use the goodness behind AbsListView.CHOICE_MODE_MULTIPLE_MODAL - to avoid reinventing the wheel, see the NonScrollListView solutionSpikelet
I think that replacing ListView with LinearLayout seems logic, but also you lose the ability of recycling that is inherent to a ListView. Try to have a LinearLayout and charge it dynamically by inflating a lot of views inside it. Garbage collector will go nutsMonahon
P
2

The best way to do this (in 2017) is to use a RecyclerView with a NestedScrollView.

No hacks required and it works out of the box like you want it to.

Psycho answered 22/2, 2017 at 18:58 Comment(1)
Whilst that is a nice solution, I don't think it is what the OP wanted as The problem is that I don't want the ListViews to be scrollableTailstock
L
0

Well, there is a cool Android guy named Mark Murphy a.k.a. CommonsWare and he built a very useful component named CWAC Merge Adapter that allows you to do what you need. You'll need to add the views dynamically and not from XML; but considering your simple UI, that shouldn't be a problem. I'm using it for these kind of cases when I have no idea on what kind of data I'm supposed to scroll.

If you don't want to use it (for licensing reasons maybe), you can have a single listview there (instead of those 2 consecutive list-views) and override getItemViewsCount, getItemViewType and getView in order to give above layout. If you search android listview different rows on Google you'll find useful info. For example this link, or this one.

However, I would go for merge-adapter.

Lathrop answered 15/9, 2013 at 14:22 Comment(2)
Thank you. The problem is that I want the ImageView and the TextView TO BE scrollable - if I scroll down they'll go up and the items in the ListView will appear.Grimbly
Then use the merge adapter and add the ImageView and TextView in there. Even with multiple listtypes you can do the same thing by setting view type for ImageView and TextView as 1 and 2. For the rest of the types you could have 3 and 4.Lathrop
C
0

I have a easy solution if it's possible to calculate your item height/wide ... You just need to create a parent Linearlayout of ListView and then fixed parent Height from Java.

enter image description here

Suppose you need to design this view... Now Parent layout size is defining from java...

final LinearLayout parent=(LinearLayout)findViewById(R.id.parent);
final ListView  listview=(ListView)findViewById(R.id.listview);
parent.setLayoutParams(new LinearLayout.LayoutParams(parent.getLayoutParams().width, dpToPx( number_of_item_in_list * per_item_size_in_dp )));
//number_of_item_in_list is list side ~ listArray.size();
//per_item_size_in_dp = calculate item size in dp. Ex: 80dp

public static int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

that's all :)

Comic answered 20/3, 2016 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.