Android. Scrolling 2 Listviews Together

Android. Scrolling 2 listviews together

OK. I have an answer now. The problem being that .setSelectionFromTop() would only work if the listview was in the top layout (ie. not nested). Afters some head scratching I realised that I could make my layout a RelativeLayout and get the same look but without having to nest layouts for the checkbox and listview. This is the new layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recordViewLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<CheckBox android:id="@+id/checkBoxTop"
android:text="Check All"
android:layout_width="160dp"
android:layout_height="wrap_content"/>

<ListView android:id="@+id/engNameList"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_below="@+id/checkBoxTop"/>

<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/checkBoxTop">

<LinearLayout android:id="@+id/scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<include layout="@layout/record_view_line" android:id="@+id/titleLine" />

<ListView
android:id="@android:id/list"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>

</LinearLayout>

</HorizontalScrollView>

</RelativeLayout>

This basically is the code that goes with the layout.

In onCreate()

engListView=getListView();
engListView.setOnTouchListener(this);

recordListView=(ListView)findViewById(R.id.recordList);
recordListView.setOnScrollListener(this);

and the listener methods:

public boolean onTouch(View arg0, MotionEvent event) {
recordListView.dispatchTouchEvent(event);
return false;
}

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
View v=view.getChildAt(0);
if(v != null)
engListView.setSelectionFromTop(firstVisibleItem, v.getTop());
}

How to scroll two listview together

The most simple way how to do it using CWAC MergeAdapter - https://github.com/commonsguy/cwac-merge

This library gives you a possibility to add two different adapters to one - MergeAdapter, and this MergeAdapter to one Listview.

MergeAdapter mergeAdapter = new MergeAdapter();
mergeAdapter.addAdapter(yourFirstAdapter);
mergeAdapter.addAdapter(yourSecondAdapter);
mYourListView.setAdapter(mergeAdapter);

Scrolling ListViews Together

I created a rough class that does basically what I wanted to do. It's not smart enough to handle if the 2nd list is longer than the 1st or if the orientation changes, but it's good enough to get the concept down.

To set it up:

list1.setOnScrollListener(new SyncedScrollListener(list2));
list2.setOnScrollListener(new SyncedScrollListener(list1));

SyncedScrollListener.java

package com.xorbix.util;

import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;

public class SyncedScrollListener implements OnScrollListener{
int offset;
int oldVisibleItem = -1;
int currentHeight;
int prevHeight;
private View mSyncedView;

public SyncedScrollListener(View syncedView){

if(syncedView == null){
throw new IllegalArgumentException("syncedView is null");
}

mSyncedView = syncedView;
}

public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {

int[] location = new int[2];

if(visibleItemCount == 0){
return;
}

if(oldVisibleItem != firstVisibleItem){

if(oldVisibleItem < firstVisibleItem){
prevHeight = currentHeight;
currentHeight = view.getChildAt(0).getHeight();

offset += prevHeight;

}else{
currentHeight = view.getChildAt(0).getHeight();

View prevView;
if((prevView = view.getChildAt(firstVisibleItem - 1)) != null){
prevHeight = prevView.getHeight();
}else{
prevHeight = 0;
}

offset -= currentHeight;
}

oldVisibleItem = firstVisibleItem;
}

view.getLocationOnScreen(location);
int listContainerPosition = location[1];

view.getChildAt(0).getLocationOnScreen(location);
int currentLocation = location[1];

int blah = listContainerPosition - currentLocation + offset;

mSyncedView.scrollTo(0, blah);

}

public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub

}
}

Multiple ListViews inside a ScrollView

It can be done, although you should not put a listview inside a scrollview but sometimes this is the easier way: https://stackoverflow.com/a/3495908/1117338

Scrolling with Multiple ListViews for Android

I haven't done this yet, but I've been thinking about it since I'll probably need to do it. I can think of three options: use only one list with the contents of all lists. You can make a ListAdapter that does that and inserts some kind of header. This could probably be something very re-usable.

The other idea is to make a list of lists. But that sounds like asking for trouble.

Two ListViews (different element height) scrolling and positioning

Well after a lot trial and error, I found the best way to make synchronised scrolling work, so I'll share the idea and can elaborate if needed.

The first approach was to count the scroll delta of any list and use smoothScrollBy(delta / aspectRatio) with aspect ratio (and I needed to count aspect ratio in every step, since my element height of the left list can be different). But this way makes lists go out of sync soon after scrolling, so it was discarded.

The second approach that is currently working is calculating the center of the listview, calculating the middle child (current child hitting the listview center) and current distance between listview center and middle child center middleElement.getTop() + middleElement.getHeight() /2;. Then i use middlePoistion = listView.getPositionForView(middleElement);to get the position currently in the middle and move the list so the same element with middlePosition would be at the center of the screen but with offset of distance from element center to listview center : otherListView.setSelectionFromTop(middlePoistion, otherListView.getHeight / 2 - otherListViewMiddleElement.getHeight() / 2 + distanceFromcenter); and distance from center can be either negative or positive. If someone needs more explanation or code snippets, just ask.

Sync 2 ListViews by Scrolling

Try something like

if( this.getScrollY() != otherList.getScrollY() )
otherList.setScrollY( this.getScrollY() );

In the onScroll method of the onScrollListener. The above is pretty rough.



Related Topics



Leave a reply



Submit