2014-10-30 138 views

回答

15

說實話,我不是什麼原因造成的問題,但是這個修復在任何版本上都沒有任何視覺錯誤。而且因爲所有這些改變只是視野的可見性,我相信它不應該產生任何新的功能問題。


DynamicListView類替換功能handleCellSwitch()驗證碼:

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

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

我試圖與代碼並在年底擺弄我找到了一種方法如何使其顯示爲以前的樣子。但是修復棒棒糖的問題使得KitKat和以前的版本出現相同的問題。所以我只將修補程序應用於比KitKat更高的Android版本。

我的猜測是這兩個視圖在這個過程中由於某種原因在新的棒棒糖版本中進行了交換。實際上,其中一個視圖始終顯示,而另一個始終隱藏。很高興知道棒棒糖android代碼中哪裏和哪些地方發生了變化......

+3

感謝您的修復,它主要工作,但仍有一個小故障。當您將某個項目拖到列表底部時,該列表會自動開始向下滾動。如果現在向上拖動相同的項目而不釋放它,列表將開始向上滾動,但會出現一個空白項目。 – Venator85 2014-11-03 18:03:20

+1

對我來說,如果我完全刪除'else'部分,在棒棒糖的情況下,它可以在兩個方向上正常工作。換句話說,棒棒糖不會改變mobileView或switchView的可見性。 – Ridcully 2014-11-22 19:30:55

+0

不錯,thx !!! – exequielc 2015-09-10 17:30:34

40

我發現了這個問題。它來自這面旗幟。 StableArrayAdapter.hasStableId

它修復了棒棒糖上這個視圖的所有問題。

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

您應該使用常量,像這樣:Build.VERSION.SDK_INT KvTvK 2014-12-15 17:57:38

+0

你拯救生命。 47deg.com有一個類似的滑動列表問題。 – grebulon 2015-03-12 11:41:54

+0

謝謝傑勒米...... – amity 2015-04-14 12:01:38

8

正確的解決方案是在再利用之前將該視圖的可見性重新打開,然後在繪製之前將其關閉。

 ((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); 

與更換,

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

的stableid解決方案是錯誤的。這些ID是穩定的,並告訴它它們不是錯誤的。它只是簡化系統,以舊的方式回收視圖。事實上,這是一個糟糕的做法,並被固定在棒棒糖中。這是一個更正確的解決方案。而不是預測.notifyDataSetChanged如何影響視圖,並根據您使用的任何版本打開和關閉適當的元素。這一個將在所有情況下啓用可見性。然後在predraw監聽器中再次查找視圖,並在繪製之前以及在其適當狀態之後將其變爲不可見。

這並不重要,如果該視圖是相同的或不相同的,或者某種未來版本具有某種不同的方式,或者沒有實際回收視圖的錯誤適配器等。穩定ID或非穩定的ID(標記爲不穩定,它們仍然必須是穩定的,但這很容易解決),這是正確實施和未來驗證的方法。

這裏的問題是,你將要得到的再循環視圖實際上並不清晰(畢竟它們是半垃圾回收視圖),而不是你可以安全地存儲屬性的東西。行爲在Lollipop中更改爲保持穩定的視圖實際上是穩定的,如果可以的話,你可以檢查適配器功能,並且回收的視圖可能已經有了你的數據,因爲它會最大限度地經常給你同樣的視圖。這是你想要的東西,這就是爲什麼棒棒糖這樣做。

的這裏的問題是,代碼表示的MobileView應可見(一個你正在移動),以及SWITCHVIEW應不可見(一個你與開關)。但是,這些將被回收,所以他們在技術上模糊不清哪一個你會回來,並完全取決於系統如何回收視圖,並且完全允許改變這種行爲以實現更好的效果。

Ps。我麻煩檢查null,因爲我個人在中途交換了視圖,如果你把事情做得恰到好處,它有時最終會變爲空。

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

... 

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

我實際上基本上重寫了整個班級。因爲它做了一堆我討厭的東西,比如數組列表和視圖的耦合以及切換一切的真正殘酷的要求。 https://www.youtube.com/watch?v=aae7Kyz3S00 – Tatarize 2015-09-29 08:35:06

+0

https://github.com/tatarize/DynamicRecyclingView基本上原來的類是相當扭曲。花了幾天時間並修復它。 – Tatarize 2016-07-09 07:38:38

0

您需要在適配器通知之前顯示mobileView和switchView。 這是我的工作。

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

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

    mDownY = mLastEventY; 

    final int switchViewStartTop = switchView.getTop(); 

    updateNeighborViewsForID(mMobileItemId); 
+0

如果有人在Lollypop之前的版本中進行測試,他們會看到這個答案會導致所有L版本之前的版本失敗。原始代碼錯誤,您可以使用該視圖在信息被回收時存儲信息。您必須正確設置它們都可見,然後添加一個預繪製偵聽器,以便在繪製之前將其設置爲不可見。 – Tatarize 2016-07-02 23:07:48

+0

我試過L版和它的工作...對我來說。 – Khushbu 2016-07-04 06:50:26

+0

問題是如果你嘗試在K中,所有東西都是fubar。我之前說過L + L會沒事的。 – Tatarize 2016-07-05 02:52:16