我正在阅读Android的源代码,RecyclerView
并且正在使用SimpleOnItemTouchListener
和阅读有关此类的文档。但是我不确定我是否理解这个意思:
使用此类的另一个好处是将来的兼容性。由于界面可能会发生变化,因此我们将始终在此类上提供默认实现,以便在您更新到支持库的新版本时代码不会中断
这是因为SimpleOnItemTouchListener
实现OnItemTouchListener
并提供了一些默认行为吗?因此,如果OnItemTouchListener
获取更新,SimpleOnItemTouchListener
仍将返回默认行为。
关于“如果界面可能会更改”的部分。他们在谈论什么OnItemTouchListener
吗?
但是,SimpleOnItemTouchListener
公正似乎有空方法,仅此而已。
1> walen..:
假设您有这个介面:
public interface OnItemTouchListener {
boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
}
然后,您决定自己实施:
public class MyOwnOnItemTouchListener implements OnItemTouchListener {
@Override
boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
boolean result = doSomething(e);
return result;
}
@Override
void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
doSomethingElse(rv, e);
doSomethingMore(rv);
}
@Override
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
if (disallowIntercept) {
doADifferentThing();
}
}
}
一切都很好……
直到六个月后,OnItemTouchListener
都进行了修改以引入一种新方法:
public interface OnItemTouchListener {
boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
// New method
void onMultiTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
}
突然之间,您的应用将无法编译
Error: MyOwnOnItemTouchListener is not abstract and does not override abstract method onMultiTouchEvent() in OnItemTouchListener
这甚至不是您的错,您什么也没改变!只是界面已更改,并且您的代码不是最新的。
为了避免这种情况,该API的开发人员为您提供一个“默认”的实现类,SimpleOnItemTouchListener
即是保证始终是最新与接口,并且您可以去继承:
public class SimpleOnItemTouchListener implements OnItemTouchListener {
// empty, override in your class
boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { return false; }
// empty, override in your class
void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {}
// empty, override in your class
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
}
因此,您可以执行以下操作,而不是直接实现接口:
public class MyOwnOnItemTouchListener extends SimpleOnItemTouchListener { //extend Simple instead of implementing interface
@Override
boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
boolean result = doSomething(e);
return result;
}
@Override
void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
doSomethingElse(rv, e);
doSomethingMore(rv);
}
@Override
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
if (disallowIntercept) {
doADifferentThing();
}
}
}
现在,如果API开发人员在六个月内需要引入一种新方法,则可以保证更改两个类:
public interface OnItemTouchListener {
boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
// New method
void onMultiTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
}
public class SimpleOnItemTouchListener implements OnItemTouchListener {
// empty, override in your class
boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { return false; }
// empty, override in your class
void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {}
// empty, override in your class
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
// New method
// empty, override in your class
void onMultiTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {}
}
而现在,尽管这个变化,MyOwnOnItemTouchListener
仍然会进行编译,即使它没有实现onMultiTouchEvent
,因为如果在任何时候MyOwnOnItemTouchListener.onMultiTouchEvent()
被调用它将只使用从其父(空)的实施,SimpleOnItemTouchListener
。
而且您的应用将继续运行
现在,回答您的确切问题:
这是因为SimpleOnItemTouchListener
实现OnItemTouchListener
并提供了一些默认行为吗?
是。尽管这里的“默认行为”是“什么都不做”,所以如果您想实际执行某项操作,则仍然需要在自己的侦听器中实现这些方法。
因此,如果OnItemTouchListener
获取更新,SimpleOnItemTouchListener
仍将返回默认行为。
对,就是这样。
关于“如果界面可能会更改”的部分。他们在谈论什么OnItemTouchListener
吗?
是。
但是,SimpleOnItemTouchListener
公正似乎有空方法,仅此而已。
是。他们提供的“默认行为”只是“什么都不做”。这只是避免编译失败的一种方法。
您仍然必须以有意义的方式实现这些方法。但是现在,如果引入了新方法,您将拥有一个安全网。
我想说您实际上了解它的要点,只是空的默认实现令人困惑。
2> marcinj..:
这是因为SimpleOnItemTouchListener实现了OnItemTouchListener并提供了一些默认行为吗?
不,它只是用空方法实现接口。如您所知,实现接口时,需要为所有接口方法添加定义,否则会出现编译错误。但是,如果您扩展了一个类,则无需覆盖所有基本方法(嗯...除非它们不是抽象的-但这不是这种情况)。
关于界面是否可能更改的部分。他们是在谈论OnItemOnTouchListener吗?
是的,他们谈论接口RecyclerView.OnItemTouchListener被更改:
http://androidxref.com/9.0.0_r3/xref/frameworks/support/v7/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java#OnItemTouchListener
假设它们在RecyclerView.OnItemTouchListener中添加了一个新方法:void foo()
,那么,如果升级支持库并且您已经在类中直接实现了RecyclerView.OnItemTouchListener
,那么您将得到编译器错误(您将需要foo()
在类中实现)。在您引用的评论中, android团队承诺他们将在SimpleOnItemTouchListener中实现foo(),因此,如果在其中进行扩展,MyOnItemTouchListener
它们将已经具有空的实现-因此不会发生编译错误。
3> Kris..:
我发现它或多或少是Adapter实现的。随着android的不断发展,交互作用将永远不会相同,并且会随着OS的发展而不断发展。
在这里,OnItemTouchListener
可以实现根接口,以便应用程序可以控制已消耗或正在消耗的触摸事件。用简单的话说,OnItemTouchListener
“ 您要处理触摸事件吗?实施我!但是要准备好处理为您抓到的各种新手势。我很动态 ”
现在,另一个人走了SimpleOnItemTouchListener
进来,说:“嘿,我可以作为您的顾问OnItemTouchListener
。我们可以就所要处理的问题达成协议。即使OnItemTouchListener
对新事物感到恼火,我也会帮助您保持镇定而不改变我会承受痛苦并确保你不被打扰“
所以它的简单性,OnItemTouchListener
可能会随着Android的发展而不断发展。SimpleOnItemTouchListener
可能会随着一起发展OnItemTouchListener
,但不会在任何当前行为中被弃用或遗忘。
添加更多内容,因为SimpleOnItemTouchListener
它为您提供了默认的实现,因此您的代码看起来很简洁,因为您只需要覆盖所需的内容即可。
4> 小智..:
我目前正在为我正在处理的项目开发一个插件框架。我试图通过对界面进行版本控制来解决此问题。我确实有像walen所说的基本实现。但是,我担心实现接口而不是基本实现的人员。当然,如果我更改界面并发布,我只会破坏那些决定不扩展基类的插件。
核心应用程序使用该部分代码所需的任何版本的接口。V2版本的接口将扩展V1,V3扩展V2,以此类推。我没有直接调用所有插件,而是有一个可以工作的manager类。这使我可以确保,如果V3功能正在尝试执行,那么我只会在实现了V3版本插件界面的插件上执行此操作。
如果我只是公开基类并从公共API隐藏接口,那么我可能只需要其他人扩展的基础实现就可以实现。不幸的是,由于该接口也是公共的,所以我必须确保不破坏没有扩展基类的开发人员。