2014-10-30 8 views
29

Ich verwende ListViewDraggingAnimation von DevBytes, aber es scheint auf Android Lollipop Entwickler Vorschau 2 (LPX13D) gebrochen. Wenn ich eine Zeile über andere Zeilen ziehe, verschwinden diese Zeilen und werden nicht mehr anklickbar (siehe unten). Ich habe versucht, Hardwarebeschleunigung für die Listview zu deaktivieren, aber es hatte keine Auswirkungen.ListViewDraggingAnimation auf Android 5 Lollipop

Example

Hat jemand das gleiche Problem erlebt? Irgendwelche Hinweise? Danke :)

Antwort

15

Um ehrlich zu sein, ich weiß nicht, was das Problem verursacht, aber diese Korrektur macht keine visuellen Fehler mehr auf jeder Version. Und weil alles, was sich geändert hat, nur Sichtbarkeit ist, sollte es meiner Meinung nach keine neuen funktionalen Probleme schaffen.


Ersetzen Sie den Code in der Funktion handleCellSwitch() in Klasse DynamicListView:

mobileView.setVisibility(View.VISIBLE); 
switchView.setVisibility(View.INVISIBLE); 

für

if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.KITKAT){ 
    mobileView.setVisibility(View.VISIBLE); 
    switchView.setVisibility(View.INVISIBLE); 
} else{ 
    mobileView.setVisibility(View.INVISIBLE); 
    switchView.setVisibility(View.VISIBLE); 
} 

Ich habe versucht mit dem Code gebastelt und am Ende fand ich eine Art und Weise, wie um es so darzustellen, wie es vorher war. Wenn das Problem für Lollipop behoben wurde, trat das gleiche Problem stattdessen bei KitKat und früheren Versionen auf. Also habe ich das Update nur für Android-Versionen höher als KitKat angewendet.

Meine Vermutung ist, dass diese beiden Ansichten in dem Prozess aus irgendeinem Grund auf der neuen Lollipop-Version ausgetauscht wird. In der Tat wird eine der Ansichten immer angezeigt, während die andere immer ausgeblendet wird. Wäre schön zu wissen, wo und was in der Lollipop Android-Code geändert wurde, obwohl ...

+3

Danke für Ihre Korrektur, es funktioniert meistens, aber es gibt immer noch einen Fehler. Wenn Sie ein Element über den unteren Rand der Liste ziehen, scrollt die Liste automatisch nach unten. Wenn Sie jetzt den gleichen Eintrag nach oben ziehen, ohne ihn freizugeben, scrollt die Liste nach oben, aber es erscheint ein leerer Eintrag. – Venator85

+1

Für mich, mit Lollipop funktioniert es gut in beide Richtungen, wenn ich den 'else' Teil komplett entferne. Mit anderen Worten, für Lollipop ändert sich die Sichtbarkeit von mobileView oder switchView nicht. – Ridcully

+0

guten job, thx !!! – exequielc

40

Ich habe das Problem gefunden. Es kam von dieser Flagge. StableArrayAdapter.hasStableId.

Es beheben alle Probleme aus dieser Sicht auf Lollipop.

@Override 
public boolean hasStableIds() 
{ 
    return android.os.Build.VERSION.SDK_INT < 20; 
} 
+10

Sie sollten Konstanten wie folgt verwenden: Build.VERSION.SDK_INT KvTvK

+0

Sie sind ein Lebensretter. Hatte ein ähnliches Problem mit Swipe-Liste von 47deg.com. – grebulon

+0

Danke Jeremie .... – amity

8

Die richtige Lösung ist, die Sichtbarkeit dieser Ansicht wieder einzuschalten, bevor sie recycelt ist und es dann ausschalten zurück, bevor sie gezogen wird.

 ((BaseAdapter) getAdapter()).notifyDataSetChanged(); 

     mDownY = mLastEventY; 

     final int switchViewStartTop = switchView.getTop(); 

     mobileView.setVisibility(View.VISIBLE); 
     switchView.setVisibility(View.INVISIBLE); 

     updateNeighborViewsForID(mMobileItemId); 

     final ViewTreeObserver observer = getViewTreeObserver(); 
     observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
      public boolean onPreDraw() { 
       observer.removeOnPreDrawListener(this); 

mit ersetzen,

 mobileView.setVisibility(VISIBLE); 
     ((BaseAdapter) getAdapter()).notifyDataSetChanged(); 


     mDownY = mLastEventY; 

     final int switchViewStartTop = switchView.getTop(); 

     updateNeighborViewsForID(mMobileItemId); 

     final ViewTreeObserver observer = getViewTreeObserver(); 
     observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
      public boolean onPreDraw() { 
       observer.removeOnPreDrawListener(this); 

       View mobileView = getViewForID(mMobileItemId); 
       if (mobileView != null) mobileView.setVisibility(INVISIBLE); 

Die stableid Lösung ist falsch. Die IDs sind stabil und sagen, dass sie nicht fehlerhaft sind. Es klickt einfach das System an, um die Ansichten auf die alte Art zu recyceln. Was war in der Tat eine schlechte Art, es zu tun und wurde in Lollipop behoben. Dies ist eine viel genauere Lösung. Anstatt vorherzusagen, wie sich das .notifyDataSetChanged auf die Ansichten auswirkt und die richtigen Elemente bei der von Ihnen verwendeten Version ein- und ausschaltet. Dieser wird die Sichtbarkeit in allen Fällen einschalten. Dann im Predraw-Listener, um die Ansicht wieder zu finden und sie unsichtbar zu machen, bevor sie gezeichnet wird und nachdem sie in ihrem richtigen Zustand ist.

Und es spielt keine Rolle, ob diese Ansicht die gleiche ist oder nicht, oder eine zukünftige Version mit einer anderen Methode, oder ein schlechter Adapter, der die Ansichten nicht recycelt, usw. Stabile IDs oder nicht-stabile IDs (markiert nicht stabil, sie müssen immer noch stabil sein, aber das ist leicht zu reparieren), es ist der Weg, um es richtig und zukunftssicher zu machen.

Das Problem hier ist, dass die recycelte Ansicht, die Sie bekommen, nicht wirklich klar ist (sie sind halb Müll wieder aufbereitete Ansichten), nicht Dinge, in denen Sie Eigenschaften sicher speichern können. Das Verhalten wurde in Lollipop geändert Halten Sie stabile Ansichten tatsächlich stabil, wenn sie können, könnten Sie in der Adapterfunktion einchecken und die wiederverwertete Ansicht wird wahrscheinlich bereits Ihre Daten haben, weil es Ihnen die gleiche Ansicht wieder oft wiedergibt. Welches ist was du willst, weshalb Lollipop es so macht.

Das Problem hier ist, dass der Code besagt, dass mobileView sichtbar gemacht werden sollte (die, die Sie bewegen), und die SwitchView sollte unsichtbar gemacht werden (die, die Sie mit wechseln). Aber diese werden recycelt werden, so dass sie technisch mehrdeutig sind, was man zurückbekommt, und hängt vollständig davon ab, wie das System die Ansichten recycelt, und es ist völlig erlaubt, dieses Verhalten zum Besseren zu ändern, und tat es auch.

Ps. Ich sorge mich darum, nach Null zu suchen, weil ich persönlich die Ansichten in der Mitte vertausche und es kann manchmal am Ende Null sein, wenn man die Dinge richtig trifft.

int deltaYTotal = (mHoverCellOriginalBounds.bottom + mHoverCellOriginalBounds.top)/2 
      + mTotalOffset + deltaY; 

... 

     boolean isBelow = (belowView != null) && (deltaYTotal > belowView.getTop()); 
     boolean isAbove = (aboveView != null) && (deltaYTotal < aboveView.getBottom()); 
+1

Ich habe eigentlich die gesamte Klasse neu geschrieben. Weil es eine Menge Sachen gemacht hat, die ich gehasst habe, wie die Koppelung der Arraylist und die Sichtweise und die wirklich lähmende Anforderung, alles zu wechseln. https://www.youtube.com/watch?v=aae7Kyz3S00 – Tatarize

+0

https://github.com/tatarize/DynamicRecyclingView Grundsätzlich war die ursprüngliche Klasse ziemlich verrückt. Habe ein paar Tage verbracht und es repariert. – Tatarize

0

Sie müssen die mobileView und switchView vor dem Adapter benachrichtigen. Das ist Arbeit für mich.

mobileView.setVisibility(View.VISIBLE); 
switchView.setVisibility(View.INVISIBLE); 

((BaseAdapter) getAdapter()).notifyDataSetChanged(); 

    mDownY = mLastEventY; 

    final int switchViewStartTop = switchView.getTop(); 

    updateNeighborViewsForID(mMobileItemId); 
+0

Wenn jemand das in Versionen vor Lollypop testet, werden sie sehen, dass diese Antwort alle Vor-L-Versionen zum Scheitern bringt. Der ursprüngliche Code ist falsch, dass Sie die Ansicht verwenden können, um Informationen zu speichern, während sie recycelt werden.Sie müssen sie beide sichtbar setzen und dann einen Predraw-Listener hinzufügen, um den richtigen vor dem Zeichnen unsichtbar zu machen. – Tatarize

+0

ich versuchte in L-Version und seine Arbeit ... für mich. – Khushbu

+0

Das Problem ist, wenn Sie in K versuchen, wird alles fubar sein. Ich sagte vor L. L + es wird gut. – Tatarize