2014-10-30 141 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