2013-02-27 8 views
7

Ich versuche, zwei nebeneinander zu machen ListViews wirken wie ein GridView in gewissem Umfang. Der Grund, warum ich GridView nicht verwende, ist, dass es keinen Support für einen gestaffelten Look gibt. Wie auch immer, ich habe den folgenden Code so weit:Synchronisieren von zwei ListViews Seite an Seite Android

< - Alte, jetzt irrelevant Code ->

EDIT:

Ich tat, wie @ Sam vorgeschlagen und verwendet, um den folgenden Code ein:

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

Ich benutze auch eine Header auf einer der Listen, um einen gestaffelten Effekt zu erstellen, und ich muss diesen Staffelung um jeden Preis zu halten. Dies funktioniert meistens (der obige Code), aber es führt zu einem großen Teil der Zeit. Ich habe herausgefunden, dass dies nur passiert, wenn ich kleine kurze Wischbewegungen habe. Ich bin mir nicht sicher, warum, und ich kann keine gute Lösung finden. Es scheint mir, dass die obige Logik funktionieren sollte.

Auch, wenn es darauf ankommt, verwende ich UniversalImageLoader, um Fotos und eine einfache EndlessScroll-Logik zu laden, um mehr Fotos (direkt aufrufen adapter.notifyDataSetChanged()) zu laden. Dieses Zeug scheint jedoch nicht so relevant zu sein. Selbst wenn Fotos geladen sind, kann ich immer noch sehen, dass es unsynchronisiert.

Ich möchte klar sein: wenn ich kurze Swipes (und manchmal nur im allgemeinen wiederholtes Scrollen) mache, kann ich die Listen nach Belieben synchronisieren.

Jede Hilfe wird geschätzt. Vielen Dank.

EDIT 2:

Noch eine gute Lösung zu finden. Hier sind die Lösungen, die ich gefunden habe, die nicht ganz funktioniert:

Irgendwelche Ideen? Vielen Dank.

+0

Anscheinend Pinterest verwendet ein Layout wie folgt, Sie können verschiedene Ansätze finden, wenn Sie hier auf Stack Overflow für ["android pinterest"] (http://stackoverflow.com/search?q= [android] + pinterest) suchen. – Sam

+0

Ja, das ist mir klar. Ich habe das auch viel recherchiert. Ich habe tatsächlich einen Teil dieser Quelle von einer anderen Antwort auf Pinterest Style Grids bekommen, https://github.com/vladexologija/PinterestListView, aber ich glaube nicht, dass es mein Problem löst, onItemClicks und TouchEvents zu unterscheiden, die für Scrolling relevant sind. – Kgrover

+1

Ich habe noch nie die Pinterest App benutzt, aber als jemand fragte: [Android. 2 Listenansichten zusammen scrollen] (http://stackoverflow.com/q/12342419/1267661) Ich habe eine Lösung gefunden, die Ihnen helfen könnte. (Es behandelt die Klicks wie Sie wollen, aber manchmal die Synchronisation bricht ...) – Sam

Antwort

2

Okay, also endete ich mit der Linear Layout Method (Siehe Frage) und verwendet setTag, um den onItemClickListener zum Laufen zu bringen, und eine CustomScrollView-Implementierung, um die unendliche Liste zum Laufen zu bringen.

Im Grunde genommen sind zwei linearLayouts in einem Scrollview horizontal gestapelt. Es funktioniert ziemlich gut und lädt viel schneller.

Auch, um meine Bilder SmartImageView zu laden, wenn das half.

Wenn jemand den Code möchte, könnte ich Teile davon veröffentlichen.

+0

Schön! Gut das zu hören –

1

Anstatt onTouch zu hören, scrollen Sie Listen im onScroll-Listener von ListViews. Das ist, was ich in dieser Bibliothek benutze, mit einer Art Spur eines ListView ähnlich und es funktioniert wie ein Zauber. Schau dir diese Datei an. https://github.com/JlUgia/list_moving_container/blob/master/src/com/ugia/listmovingcontainer/fragment/BottomListMovingContainerFragment.java

Achten Sie besonders auf 81 (vergessen Sie nicht, den globalen Layout Updater Listener hinzuzufügen) und 89 (mit dem onScroll Listener). Auf diese Weise können Sie auch die Klick-Hacks vergessen.

UPDATE

Ich würde es die folgende Art und Weise codieren.

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 macht bereits Ihre Liste ungültig.

** Beachten Sie, dass ich den Code nicht getestet habe. Obwohl es einfach genug sein sollte.

+0

Ich werde es versuchen. Könnten Sie mir mehr Feedback dazu geben, wie ich dies in meinem derzeitigen System umsetzen kann? Es fällt mir schwer zu entziffern, was genau in Ihrem Code passiert und wie ich damit parallele Listen erstellen kann. Danke für die Antwort, dieser ist ein Stumper. – Kgrover

+0

Auch was genau macht dein Code? Scrollt sie _2_ Listen parallel? – Kgrover

+0

Nein, es scrollt eine Ansicht (die Fußzeile der Liste) basierend auf einer Funktion abhängig von der Scroll-Position der Liste. Für Ihren Fall würde ich beide Listener (globalLayoutListener und onScrollListener) für beide Ihre ListViews implementieren die Aktualisierung der anderen Liste in jedem von ihnen. Lassen Sie mich meine Antwort mit einem Beispiel aktualisieren. –