Syncing Two ListViews side by side Android
Asked Answered
H

2

7

I'm trying to make two side by side ListViews act like a GridView to an extent. The reason I'm not using GridView is because there's no support for a Staggered Look. Anyways, I have the following code so far:

<- Old,now irrelevant code ->

EDIT:

I did as @Sam suggested and used the following code:

lv1.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (touchSource == null) {
                    touchSource = v;
                }

                if (v == touchSource) {
                    lv2.dispatchTouchEvent(event);
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        clickSource = v;
                        touchSource = null;
                    }
                }

                return false;
            }
        });

        lv1.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                if (parent == clickSource) {
                               //my own code here

                }
            }
        });

        lv1.setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                if (view == clickSource) {


                }
                boolean loadMore = /* maybe add a padding */
                firstVisibleItem + visibleItemCount + 10 >= totalItemCount;

                if (loadMore) {
                    //add items, load more
                }
            }

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
            }
        });

        lv2.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (touchSource == null) {
                    touchSource = v;
                }

                if (v == touchSource) {
                    lv1.dispatchTouchEvent(event);
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        clickSource = v;
                        touchSource = null;
                    }
                }

                return false;
            }
        });
        lv2.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                if (parent == clickSource) {
                }
            }
        });

        lv2.setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                if (view == clickSource) {

                }
                boolean loadMore = /* maybe add a padding */
                firstVisibleItem + visibleItemCount + 2 >= totalItemCount;

                if (loadMore) {

                }

            }

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
            }
        });

I am also using a header on one of the lists to create a Staggered Effect and I need to keep this stagger at all costs. This is mostly working (the above code) but it unsyncs a lot of the time. I have figured out this is only when I have small short swipes. I'm not sure why, and I can't find a good solution. It seems to me that the above logic should work.

Also, just in case it matters, I am using UniversalImageLoader to load photos and a simple EndlessScroll logic to load more photos (directly calling adapter.notifyDataSetChanged()). This stuff doesn't seem too relevant though. Even when photos are loaded, I can still see it unsyncing.

I want to be clear: if I do short swipes (and sometimes just in general repeated scrolling) I can unsync the lists at will.

Any help is appreciated. Thanks.

EDIT 2:

Yet to find a good solution. Here are the solutions that I have found that don't quite work:

Any ideas? Thanks.

Hardihood answered 27/2, 2013 at 0:24 Comment(8)
Apparently Pinterest uses a layout like this, you can find various approaches if you search here on Stack Overflow for "android pinterest".Cornall
Yes, I realize that. I've been researching this a lot too. I actually got part of this source from another answer on Pinterest style grids, github.com/vladexologija/PinterestListView, but I don't think it solves my problem of differentiating onItemClicks and TouchEvents relevant to scrolling.Hardihood
I have never used the Pinterest app, but when someone asked: Android. Scrolling 2 listviews together I came up with a solution that might help you. (It handles the clicks like you want, but sometimes the synchronization breaks...)Cornall
StaggeredGridView has good click handling, and looks fine for what you're asking.Thorlie
I cannot implement scroll listener with this. Thanks for the suggestion.Hardihood
@Sam, I think that might work. i'm looking into it.Hardihood
Just thinking, why not add clickListeners to the code from the Linear Layout Method you linked? ImageView iv = new ImageView(this); iv.setImageResource(R.id.icon); iv.setOnClickListener(this);Incandescent
@YekhezkelYovel if you're online in the next 15 minutes, I guess I could give you the bounty. You were rather close to what I ended up doing. I can't give it to myself. er, so post an answer maybe?Hardihood
H
2

Okay, so I ended up using the Linear Layout Method(See the Question) and used setTag to get the onItemClickListener working, and a CustomScrollView implementation to get the infinite List working.

Basically, two linearLayouts stacked horizontally, inside a scrollview. It works rather well, and loads much faster.

Also, to load my images SmartImageView if that helped.

If someone wants the code, I might be able to post parts of it.

Hardihood answered 8/4, 2013 at 4:11 Comment(0)
C
1

Instead of listening to onTouch why don't you scroll lists in the onScroll listener of ListViews. That's what I'm using in that library with sort of tracks the scroll of a ListView similarly and it works like a charm. Check out this file. https://github.com/JlUgia/list_moving_container/blob/master/src/com/ugia/listmovingcontainer/fragment/BottomListMovingContainerFragment.java

Pay attention specially to 81 (don't forget to add the global layout updater listener) and 89 (with the onScroll Listener). That way you can forget about the click hacks as well.

UPDATE

I'd code it the following way.

lv1.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        updateListPosition(lv2, lv1);
    }
});

lv1.setOnScrollListener(new AbsListView.OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        updateListPosition(lv2, lv1);
    }
});

lv2.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        updateListPosition(lv1, lv2);
    }
});

lv2.setOnScrollListener(new AbsListView.OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        updateListPosition(lv1, lv2);
    }
});

private void updateListPosition(ListView updatedList, ListView scrolledList){
    updatedList.setScrollY(scrolledList.getScrollY());

}

** setScrollY already invalidates your list.

** Note that I didn't test the code. Although it should be simple enough.

Crossquestion answered 1/4, 2013 at 21:15 Comment(5)
I will try it. Could you give me more feedback on how to implement this in my current system? I'm having a hard time decoding what exactly is happening in your code and how I can use it to accomplish parallel lists. Thanks for the answer though, this one is a stumper.Hardihood
Also- what exactly does your code do? Does it scroll 2 lists in a parallel fashion?Hardihood
No it scrolls a view (the footer of the list) based on a function dependent of the scrolling position of the list. For your case I'd implement both listener (globalLayoutListener and onScrollListener) for both of your listViews updating the other list in each of them. Let me update my answer with an example.Crossquestion
So what's missing? What's the result? It's not moving anything at all?Crossquestion
yeah, I can't seem to get them parallel with this- it moves, but it's very inconsistent.Hardihood

© 2022 - 2024 — McMap. All rights reserved.