Non-scrollable ListView inside ScrollView
AndroidAndroid ListviewScrollviewAndroid Problem Overview
I'm trying to make a layout like this:
http://i.stack.imgur.com/cEDjE.png" width="300"/>
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?
Android Solutions
Solution 1 - Android
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);
Solution 2 - Android
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.
Solution 3 - Android
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.
Solution 4 - Android
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.
Solution 5 - Android
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][1]][1]
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 :) [1]: http://i.stack.imgur.com/5yWHb.png
Solution 6 - Android
Choose the ListView that's you want to be Scrollable, and after that add the method 'setOnTouchListener' to automatically the system insert the scroll inside the ListView
final ListView listview = (ListView) findViewById(R.id.list);
listview.setOnTouchListener(new ListView.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
int action = event.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle ListView touch events.
v.onTouchEvent(event);
return true;
}
});
listview.setClickable(true);
I hope that works for you
Solution 7 - Android
-
How to scroll listView In scrollView
listViewName.setOnTouchListener(new ListView.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // Disallow ScrollView to intercept touch events. v.getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_UP: // Allow ScrollView to intercept touch events. v.getParent().requestDisallowInterceptTouchEvent(false); break; } // Handle ListView touch events. v.onTouchEvent(event); return true; } }); listViewName.setClickable(true);