35

I'm completely stumped on this one. I have three different lists that need to be displayed on the screen. It's completely possible that the lists will extend past the bottom edge of the screen, so I would need scrolling.

I've tried using a ScrollView with a LinearLayout child, and putting my ListViews in the LinearView, but all of the ListViews lock to a fixed height with scroll bars. Using other kinds of Layouts means no scrolling.

Does anyone have any suggestions, or will I need to programmatically add the list items to some layout and hope for the best?

MDMalik
  • 3,951
  • 2
  • 25
  • 39
Andrew Burgess
  • 5,300
  • 5
  • 30
  • 37

4 Answers4

12

Forward touch event from touched view to other views. All your views will be synchronized expand/collapsed too.

OnTouchListener mOnTouch = new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {            
        MotionEvent newEvent = MotionEvent.obtain(event);

        switch(event.getAction()) {  
            case MotionEvent.ACTION_MOVE:
                if(mTouched == null) {
                    mTouched = v;
                }
                mMovingFlag = true;
                break;
            case MotionEvent.ACTION_UP:
                if(mMovingFlag==false) {
                    newEvent.setAction(MotionEvent.ACTION_CANCEL);
                }
                mMovingFlag = false;
                break;
            default:
                mMovingFlag = false;
                if(mTouched != null && mTouched.equals(v)) {
                    mTouched = null;
                }
                break;
        }

        if(mTouched == null || mTouched.equals(v)) {
            int items = mLayoutWithListViews.getChildCount();
            for(int i = 0; i < items; i++) {
                AbsListView listView = mLayoutWithListViews.getChildAt(i));
                if(listView != v) {
                    listView.onTouchEvent(newEvent);
                }
            }
        }

        return false;
    }
};
SerjantArbuz
  • 982
  • 1
  • 12
  • 16
Richard
  • 423
  • 3
  • 9
  • 1
    I'm sorry, but I don't know how to implement this answer. are mTouched, mMovingFlag global variables? Do they belong to the other listviews? Is in this example mLayoutWithListViews the other listview that we want to synchronize? Thanks. – Graph Sep 19 '15 at 18:58
8

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.

Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622
  • 2
    What's the third option? Because I'm interested in that topic too and I tried to do the ListViews in a ListView approach for question http://stackoverflow.com/questions/1526831/android-scrollview-layout-problem (altough I haven't seen your answer before). Talking with the guys on #android-dev, putting ListViews in a ListView is even worse than putting them in a ScrollView. (And so were my results.) Because your post war written quite long time ago, have you tried the all in a list solution by now? – svens Oct 06 '09 at 20:31
6

I had a similar problem save that I had two GridViews and one ListView to scroll. I solved it by manually setting the height of the ListViews and GridView:

ListAdapter listAdapter = listView.getAdapter();
    
int rows = listAdapter.getCount() / columns;
int height = 60 * rows; // Insert the general cell height plus the dividers.

ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = height;
listView.setLayoutParams(params);
listView.requestLayout();

Hope I could help someone.

SerjantArbuz
  • 982
  • 1
  • 12
  • 16
hgllnt
  • 338
  • 2
  • 10
3

Although this answer is for scroll view's instead of list view's, the problem is the same and this solution worked well for me. Scrolling the left scrollview will scroll the right scrollview and viceversa.

public class MainActivity extends Activity implements OnTouchListener {

    private ScrollView scrollViewLeft;
    private ScrollView scrollViewRight;
    private static String LOG_TAG = MainActivity.class.getName();
    private boolean requestedFocus = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        scrollViewLeft = (ScrollView) findViewById(R.id.scrollview_left);
        scrollViewRight = (ScrollView) findViewById(R.id.scrollview_right);

        scrollViewLeft.setOnTouchListener(this);
        scrollViewRight.setOnTouchListener(this);
        
        scrollViewLeft.setFocusableInTouchMode(true);
        scrollViewRight.setFocusableInTouchMode(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        Log.d(LOG_TAG, "--> View, event: " + view.getId() + ", " + motionEvent.getAction() + ", " + view.isFocused());
        Log.d(LOG_TAG, "--> " + scrollViewLeft.isFocused() + ", " + scrollViewRight.isFocused());
        
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && requestedFocus == false) {
            view.requestFocus();
            requestedFocus = true;
        } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
            requestedFocus = false;
        }
    
        if (view.getId() == R.id.scrollview_left && view.isFocused()) {
            scrollViewRight.dispatchTouchEvent(motionEvent);
        } else if (view.getId() == R.id.scrollview_right && view.isFocused()) {
            scrollViewLeft.dispatchTouchEvent(motionEvent);
        }
        
        return super.onTouchEvent(motionEvent);
    }
}
SerjantArbuz
  • 982
  • 1
  • 12
  • 16
Kevin Parker
  • 16,975
  • 20
  • 76
  • 105