s1ni5t3r s1ni5t3r - 3 months ago 14
Android Question

Android. Scrolling 2 listviews together

OK. What I'm trying to achieve is a layout that does the same effect as frozen panes in Excel. That is I want a header row that scrolls horizontally with the main ListView and a left hand ListView that scrolls vertically with the main ListView. The header row and the left hand listview should remain stationary when scrolling in the other dimension.

Here is the xml layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">
<LinearLayout android:layout_width="160dp"
android:layout_height="match_parent"
android:orientation="vertical">

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


<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">

<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>
</LinearLayout>


I'm then using this code in the ListActivity

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
View v = recordsListView.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();

((ListView)findViewById(R.id.engNameList)).setSelectionFromTop(firstVisibleItem, top);
}


This should cause the left hand ListView to scroll when the right hand one is scrolled by the user. Unfortunately it doesn't.

I've had a bit of a google about and it seems the setSelectionFromTop() function will not work on a ListView that is nested inside more than one layout.

If this is the case can anyone suggest a way to get them to scroll together or a different way to set up the layout or a different technique altogether.

Answer

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());
}