正确的解决方案是在该视图被回收之前重新打开它的可见性,然后在它被绘制之前将其关闭。
((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 将如何影响视图并根据您使用的任何版本打开和关闭适当的元素。这将在所有情况下打开可见性。然后在预绘制侦听器中再次找到视图并将其变为不可见,在它被绘制之前和它处于正确状态之后。
不管该视图是否相同,或者未来版本是否具有不同的执行方式,或者实际上没有回收视图的坏适配器等。稳定的 Ids 或不稳定的 ids(标记为不稳定,它们仍然必须实际上是稳定的,但这很容易修复),这是正确执行此操作和面向未来的方法。
这里的问题是,您将获得哪个回收视图实际上并不清楚(毕竟它们是半垃圾回收视图),而不是您可以安全存储属性的东西。在 Lollipop 中更改了行为以保留如果可以,稳定视图实际上是稳定的,您可以签入适配器功能,并且回收的视图可能已经拥有您的数据,因为它会最大限度地再次为您提供相同的视图。这就是你想要的东西,这就是 Lollipop 这样做的原因。
这里的问题是代码说 mobileView 应该是可见的(你正在移动的那个),而 switchView 应该是不可见的(你正在切换的那个)。但是,这些将被回收,因此它们在技术上是模糊的,您将取回哪个,并且完全取决于系统如何回收视图,并且完全允许将这种行为改变得更好,并且确实做到了。
附言。我费心检查 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());