Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scrolling ListViews Together

Tags:

java

android

I've got two ListView objects that I would like to scroll together. They are side-by-side, so if one scrolls a certain amount, the other scrolls that same amount. I've found some examples on how to do this, but I believe that they rely on the items in the ListView being the same height (correct me if I am wrong). The items in one of my ListView objects are taller than the ones in the other, spanning 2-3 items.

How do I "lock" these 2 ListView objects together?

EDIT: Here's a screenshot of what I have, maybe it will better explain what I'm going for. The left side (red) is a list of items and the right side is a separate list. You can see how the lists don't align perfectly, so it isn't exactly a grid. What I would like to do is have this act like one big list, where scrolling either list will also scroll the other.

App Screenshot

like image 426
compuguru Avatar asked Dec 03 '11 23:12

compuguru


1 Answers

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

    }
}
like image 174
compuguru Avatar answered Oct 23 '22 22:10

compuguru