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.

Community
  • 1
  • 1
Kgrover
  • 2,106
  • 2
  • 36
  • 54
  • Apparently Pinterest uses a layout like this, you can find various approaches if you search here on Stack Overflow for ["android pinterest"](http://stackoverflow.com/search?q=[android]+pinterest). – Sam Feb 27 '13 at 00:29
  • 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, https://github.com/vladexologija/PinterestListView, but I don't think it solves my problem of differentiating onItemClicks and TouchEvents relevant to scrolling. – Kgrover Feb 27 '13 at 00:32
  • 1
    I have never used the Pinterest app, but when someone asked: [Android. Scrolling 2 listviews together](http://stackoverflow.com/q/12342419/1267661) I came up with a solution that might help you. (It handles the clicks like you want, but sometimes the synchronization breaks...) – Sam Feb 27 '13 at 00:41
  • [StaggeredGridView](http://www.androidviews.net/2013/01/pinterest-like-adapterview/) has good click handling, and looks fine for what you're asking. – Geobits Feb 27 '13 at 01:00
  • I cannot implement scroll listener with this. Thanks for the suggestion. – Kgrover Feb 27 '13 at 02:45
  • @Sam, I think that might work. i'm looking into it. – Kgrover Feb 27 '13 at 02:46
  • 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); –  Apr 06 '13 at 15:24
  • @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? – Kgrover Apr 08 '13 at 04:14

2 Answers2

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.

Kgrover
  • 2,106
  • 2
  • 36
  • 54
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.

Jose L Ugia
  • 5,960
  • 3
  • 23
  • 26
  • 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. – Kgrover Apr 01 '13 at 22:52
  • Also- what exactly does your code do? Does it scroll _2_ lists in a parallel fashion? – Kgrover Apr 01 '13 at 22:53
  • 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. – Jose L Ugia Apr 02 '13 at 07:30
  • So what's missing? What's the result? It's not moving anything at all? – Jose L Ugia Apr 07 '13 at 21:25
  • yeah, I can't seem to get them parallel with this- it moves, but it's very inconsistent. – Kgrover Apr 08 '13 at 04:01