Skip to content Skip to sidebar Skip to footer

Scrolling Listviews Together

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

Solution 1:

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(newSyncedScrollListener(list2));
list2.setOnScrollListener(newSyncedScrollListener(list1));

SyncedScrollListener.java

package com.xorbix.util;

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

publicclassSyncedScrollListenerimplementsOnScrollListener{
    int offset;
    intoldVisibleItem= -1;
    int currentHeight;
    int prevHeight;
    private View mSyncedView;


    publicSyncedScrollListener(View syncedView){

        if(syncedView == null){
            thrownewIllegalArgumentException("syncedView is null");
        }

        mSyncedView = syncedView;
    }

    publicvoidonScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {

        int[] location = newint[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);
        intlistContainerPosition= location[1];

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

        intblah= listContainerPosition - currentLocation + offset;

        mSyncedView.scrollTo(0, blah);

    }

    publicvoidonScrollStateChanged(AbsListView view, int scrollState) {
        // TODO Auto-generated method stub

    }
}

Solution 2:

I think it is more appropriate to use a GridView with 2 columns, something like this:

<GridView
    android:id="@+id/grid_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:numColumns="2"
    />

Solution 3:

What I would like to do is to listen to the scrolling event for the left listview and then scroll the right listview by an proper offset. Below is my code, I tested it(very simple, just show you my thought) and you may add your code based on it.

package viewTest.example.hy;

import android.app.Activity;

import android.os.Bundle;

import android.widget.AbsListView;

import android.widget.ArrayAdapter;

import android.widget.ListView;

import android.widget.AbsListView.OnScrollListener;

publicclassViewTestActivityextendsActivity {


privateArrayAdapter<String> adapter0;
    privateArrayAdapter<String> adapter1;
    privateString[] array0;
    privateString[] array1;
    privateListView lv0;
    privateListView lv1;


@OverridepublicvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    array0 = getResources().getStringArray(R.array.LV0);//letters from A to O
    array1 = getResources().getStringArray(R.array.LV1);//numbers from 1 to 14

    adapter0 = newArrayAdapter<String>(this, R.layout.item, array0);
    adapter1 = newArrayAdapter<String>(this, R.layout.item, array1);

    lv0 = (ListView) findViewById(R.id.listView1);
    lv1 = (ListView) findViewById(R.id.listView2);

    lv0.setAdapter(adapter0);
    lv1.setAdapter(adapter1);

    lv0.setOnScrollListener(newOnScrollListener() {

        @OverridepublicvoidonScrollStateChanged(AbsListView view, int scrollState) {
            // TODO Auto-generated method stub

        }

        @OverridepublicvoidonScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            lv1.setSelection(firstVisibleItem);//force the right listview to scrollyou may have to do some calculation to sync the scrolling status of the two listview.
        }
    });

}

}

And this is the main.xml layout:

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/layout"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="horizontal" ><ListViewandroid:id="@+id/listView1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:scrollbars="none"></ListView><ListViewandroid:id="@+id/listView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:scrollbars="none" ></ListView></LinearLayout>

Here is my screenshot: enter image description here

Solution 4:

I ended up using the top s/o answer here: Android. Scrolling 2 listviews together

Intercepting and redirecting events seems to be a lot more elegant and consistent than trying to do my own math on the dimensions and state of the listviews.

Post a Comment for "Scrolling Listviews Together"