I have two ListViews
. Is there any way to synchronize the position of ListViews
when I scroll any one of the Lists. Im implementing an AbsListView.OnScrollListener
, registering to the ListView
. When the ListView
is scrolled, the onScroll()
method of OnScrollListener
will be triggered, then i call `smoothScrollToPosition()'. But it doent work properly. Can someone provide me any code example for this?
Asked
Active
Viewed 5,248 times
3

arkmetal
- 681
- 3
- 11
- 25
-
Why two lists? Why not put all the data into one list? – Barak Aug 10 '12 at 17:59
-
Because im trying to create my own Compound Control that has to be implemented with 2 listView and with other components as well. – arkmetal Aug 10 '12 at 18:09
-
I guess I just don't understand the purpose, If the lists always scroll together, it belongs together and can go in a single list with multiple lines or columns (IMO). Or is this something where you set the positions relative.to each other THEN lock the scrolling? – Barak Aug 10 '12 at 18:49
-
Ok maybe i explain it in the wrong way, the other listview can be scrollable vertically and horizontally, but when i want to scroll it vertically, it has to move with other listview as well, then when you scroll it horizantally you can scroll only that list view horinzally and the other stays fixed. – arkmetal Aug 10 '12 at 19:00
-
Listview only scrolls vertically, to scroll on the horizontal you can use a ScrollView. – Marcio Covre Aug 10 '12 at 19:33
-
what??? in order to scroll horizontally you use HorizontalScrollView. – arkmetal Aug 10 '12 at 19:39
-
Another sollution is [here][1], It works for me [1]: https://stackoverflow.com/questions/12342419/android-scrolling-2-listviews-together – shyam.y Jun 17 '14 at 12:28
2 Answers
5
Here is a working code sample of what nininho is suggesting
MainActivity
public class MainActivity extends Activity {
public static String[] Cheeses = new String[] { "Abbaye de Belloc", "Abbaye du Mont des Cats",
"Abertam", "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis",
"Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre", "Allgauer Emmentaler", "Alverca",
"Ambert", "American Cheese", };
ListView list1;
ListView list2;
boolean isLeftListEnabled = true;
boolean isRightListEnabled = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
Cheeses);
list1 = (ListView) findViewById(R.id.list1);
list1.setAdapter(adapter);
list2 = (ListView) findViewById(R.id.list2);
list2.setAdapter(adapter);
// IF YOU DO NOT OVERRIDE THIS
// ONLY THE ONE THAT IS TOUCHED WILL SCROLL OVER
list1.setOverScrollMode(ListView.OVER_SCROLL_NEVER);
list2.setOverScrollMode(ListView.OVER_SCROLL_NEVER);
list1.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// onScroll will be called and there will be an infinite loop.
// That's why i set a boolean value
if (scrollState == SCROLL_STATE_TOUCH_SCROLL) {
isRightListEnabled = false;
} else if (scrollState == SCROLL_STATE_IDLE) {
isRightListEnabled = true;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
View c = view.getChildAt(0);
if (c != null && isLeftListEnabled) {
list2.setSelectionFromTop(firstVisibleItem, c.getTop());
}
}
});
list2.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_TOUCH_SCROLL) {
isLeftListEnabled = false;
} else if (scrollState == SCROLL_STATE_IDLE) {
isLeftListEnabled = true;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
View c = view.getChildAt(0);
if (c != null && isRightListEnabled) {
list1.setSelectionFromTop(firstVisibleItem, c.getTop());
}
}
});
}
}
the XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:splitMotionEvents="true">
<ListView android:id="@+id/list1"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1" />
<ListView android:id="@+id/list2"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>

EvertvdBraak
- 1,033
- 1
- 12
- 20
-
-
No... well it does work but you probably won't have the effect that you would like to have. But it's a bit out dated. If i were you i would check out the RecyclerView. Here's a good explanation of how it works http://wiresareobsolete.com/2014/09/building-a-recyclerview-layoutmanager-part-1/ – EvertvdBraak Feb 10 '15 at 08:53
1
If the position is visible smoothScrollToPosition() won't scroll. You can thought use scrollTo or scrollBy on the other list that is not scrolling at the moment, but be careful to not enter a recursion with each list calling the other to scroll.

Marcio Covre
- 4,556
- 2
- 22
- 24
-
But in that case, if i use scrollTo or scrollBy, is gonna move only the rendered items but it doesnt work as an adapter. – arkmetal Aug 13 '12 at 20:45
-
No, it's not on the adapter, the scroll is on the view, so you can have a scroll that shows only part of the item. You may also try public void smoothScrollToPositionFromTop (int position, int offset) to force scroll the item to top, but to be the two lists in sync you need to call this on both lists. – Marcio Covre Aug 14 '12 at 12:13