I have a listview in my scroll view underneath almost a page worth of scroll before that but once my listview gets populated the scrollview moves to the top of the list view. how can I fix this/prevent this from happening?
SCROLL VIEW XML:
<ScrollView
android:id="@+id/tvscrollview"
android:layout_marginTop="8.0dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
layout="@layout/a" />
<include
layout="@layout/b" />
<include
layout="@layout/c" />
<include
layout="@layout/d" />
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
I've tried doing sv.fullScroll(ScrollView.FOCUS_UP); and all that stuff to my scrollview but it doesnt work
All you have to do is set Global Keys for your widgets and call Scrollable. ensureVisible on the key of your widget you want to scroll to. For this to work your ListView should be a finite List of objects. If you are using ListView.
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. Nested scrolling is enabled by default.
ScrollView is used to put different or same child views or layouts and the all can be scrolled. ListView is used to put same child view or layout as multiple items. All these items are also scrollable. Simply ScrollView is for both homogeneous and heterogeneous collection.
To enable or disable scrolling on FlatList with React Native, we can set the scrollEnabled prop. to set the scrollEnabled prop to false to disable scrolling on the FlatList.
We should never put a ListView
inside a ScrollView
.
Work Around : When ScrollView
moves up/down because of listview's notifyDataSetChanged()
,
Then try,
scrollview.setEnabled(false);
listview.setFocusable(false);
adapter.notifyDataSetChanged();
scrollview.setEnabled(true);
Firstly, probably you've already heard about it, but just in case: You should never put a ListView
inside a ScrollView
, as ListView
itself already has got a ScrollView
and this design goes against the whole ListView
idea. If you're convinced you have to use it, probably there's a better approach to use and you may need to simplify your code somehow.
Now, even if you still want to use something like that, you may use something like this:
package your.package.name;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
public class ScrollingListView {
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
}
You simply set your adapter via .setAdapter()
and afterwards call ScrollingListView.setListViewHeightBasedOnChildren(your_listview)
. This should redimension your window accordingly to your ListView
height.
---- EDIT ----
That will be probably the ugliest workaround, but try doing the following:
ScrollView sv = (ScrollView) findViewById(R.id.your_scrollview);
sv.setEnabled(false);
// Populate your ListView
sv.setEnabled(true);
Just Do one thing before add items in your list
listview.setFocusable(false);
after that you can again do that
listview.setFocusable(true);
if needed it will work for sure
Add all the stuff on top as header to the list view.
Now that I see the code.. you can only have one ViewGroup inside a scrollview. So you would warp the two layouts into another one, BUT a ListView automatically has a scroll view in it so that wont really work.
So what you have to do is use the addHeader view in your ListActivity (of fragment) and inflate LinearLayout1 in the activity from a different xml file.
add:
android:transcriptMode="disabled"
in the list you don't want to scroll
From Android Docs
It's not possible to make a scrollable view inside a scrollable view. But as a work around this, and only in case that this listviews doesn't take much memory if all views are loaded. you can use this
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class NonScrollableListView extends ListView {
public NonScrollableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Do not use the highest two bits of Integer.MAX_VALUE because they are
// reserved for the MeasureSpec mode
int heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightSpec);
getLayoutParams().height = getMeasuredHeight();
}
}
Again, it's not good to use this workaround
I would wrap the list and the other layouts in a RelativeLayout
instead of a LinearLayout
<ScrollView
android:id="@+id/tvscrollview"
android:layout_marginTop="8.0dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<include
layout="@layout/a" />
<include
layout="@layout/b" />
<include
layout="@layout/c" />
<include
layout="@layout/d" />
</LinearLayout>
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/container" />
</RelativeLayout>
</ScrollView>
This way the top border of the ListView
is boun to the bottom border of the LinearLayout
and will always stay under everything else.
You cant put the includes directly in the RelativeLayout
! See here for more details.
I have made 2 or 3 changes in your xml file
<ScrollView
android:id="@+id/tvscrollview"
android:layout_marginTop="8.0dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"> // This will let you see the scroll bar of list view
when you scroll your list view.
<include
layout="@layout/a" />
<include
layout="@layout/b" />
<include
layout="@layout/c" />
<include
layout="@layout/d" />
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="300dp" />// Instead of wraping up your list, if you wish
you can give certain height to your list view.
</LinearLayout>
</ScrollView>
Another thing you need is write the given code in your java file.
onCreate()
{
....
ScrollView sView=(ScrollView)findViewById(R.id.tvscrollview);
yourListView.setOnTouchListener(new OnTouchListener()
{
public boolean onTouch(View arg0, MotionEvent arg1)
{
if(arg1.getAction() == MotionEvent.ACTION_DOWN || arg1.getAction() == MotionEvent.ACTION_MOVE)
{
sView.requestDisallowInterceptTouchEvent(true);
}
return false;
}
});
I hope this helps you.
You may want to achieve this by using following:
<LinearLayout
......>
<ScrollView
android:id="@+id/tvscrollview"
android:layout_marginTop="8.0dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
layout="@layout/a" />
<include
layout="@layout/b" />
<include
layout="@layout/c" />
<include
layout="@layout/d" />
</LinearLayout>
</ScrollView>
<ListView
android:id="@+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Wrap your listview outside scrollview and else inside scrollview, because You should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.
Source Android Docs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With