在Android 5棒棒糖上损坏的ListViewDraggingAnimation

我正在使用DevBytes的 ListViewDraggingAnimation ,但它似乎打破了Android棒棒糖开发人员预览2(LPX13D)。 当我在其他行上拖动一行时,这些行将消失,不再可点击(见下文)。 我试图禁用硬件加速的列表视图,但没有任何效果。

例

有没有人遇到同样的问题? 任何提示? 谢谢 :)

Related of "在Android 5棒棒糖上损坏的ListViewDraggingAnimation"

我发现了这个问题。 它来自这面旗帜。 StableArrayAdapter.hasStableId

它从棒棒糖的这个观点解决了所有的问题。

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

说实话,我不是什么原因造成的问题,但是这个修复在任何版本上都不会造成视觉上的错误。 而且因为所有这一切都只是看法的可见性,我相信它不应该产生任何新的function问题。


在类DynamicListView中的函数handleCellSwitch()中replace此代码:

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

我试着修改代码,最后我find了一个如何使它像之前一样显示的方法。 但是修复棒棒糖的问题使得KitKat和之前的版本出现相同的问题。 所以我只适用于比KitKat更高的android版本。

我的猜测是这两个观点在新的棒棒糖版本中由于某种原因而被交换。 实际上,其中一个视图始终显示,而另一个始终隐藏。 将很高兴知道在哪里和棒棒糖android代码中更改了什么…

正确的解决scheme是在再循环之前将该视图的可见性重新打开,然后在绘制之前将其closures。

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

稳定的解决scheme是错误的。 这些ID是稳定的,并告诉它们不是错误的。 它只是简单地使系统回收旧的方式的意见。 事实上,这是一个糟糕的做法,并被固定在棒棒糖。 这是一个更正确的解决scheme。 而不是预测.notifyDataSetChanged将如何影响视图,并打开和closures正确的元素给你使用的任何版本。 这一个将在所有情况下打开可见性。 然后在预览监听器中再次查找视图,并在绘制之前将其变为不可见,并在其处于适当状态之后。

如果这个观点是一样的,或者有一些不同的方式,或者一个不能真正回收视图的糟糕的适配器,那么这并不重要。稳定的Ids或者非稳定的(标记不稳定,他们仍然必须是稳定的,但这是很容易解决的),这是正确的做法和未来的方法。

这里的问题是,你将要得到的回收视图实际上并不清楚(毕竟它们是半垃圾回收视图),而不是你可以安全地存储属性的东西。在棒棒糖中改变了行为以保持稳定的视图稳定,如果可以的话,你可以检查在适配器function和回收视图可能已经有你的数据,因为它会给你同样的看法,最大限度地经常。 这是你想要的,这就是为什么棒棒糖这样做。

这里的问题是,代码说mobileView应该是可见的(你正在移动的),并且switchView应该是不可见的(你正在切换的那个)。 但是,这些将被回收,所以他们在技术上模糊不清哪一个你会回来,完全取决于系统如何回收的意见,它是完全可以改变这种行为,更好,并做到了。

PS。 我麻烦检查null,因为我个人在中途交换了视图,如果你把事情做得恰到好处,有时候最终会变成null。

  int deltaYTotal = (mHoverCellOriginalBounds.bottom + mHoverCellOriginalBounds.top) / 2 + mTotalOffset + deltaY; ... boolean isBelow = (belowView != null) && (deltaYTotal > belowView.getTop()); boolean isAbove = (aboveView != null) && (deltaYTotal < aboveView.getBottom()); 

您需要在适配器通知之前显示mobileView和switchView。 这是为我工作。

  mobileView.setVisibility(View.VISIBLE); switchView.setVisibility(View.INVISIBLE); ((BaseAdapter) getAdapter()).notifyDataSetChanged(); mDownY = mLastEventY; final int switchViewStartTop = switchView.getTop(); updateNeighborViewsForID(mMobileItemId);