我正在阅读Android RecyclerView
的源代码,并且正在使用SimpleOnItemTouchListener
并阅读有关此类的文档。但是我不确定我是否理解这个意思:
使用此类的另一个好处是将来的兼容性。由于界面可能会发生变化,我们将始终在此类上提供默认实现,以使您的代码在更新到支持库的新版本时不会中断
这是因为SimpleOnItemTouchListener
实现了OnItemTouchListener
并提供了一些默认行为吗?因此,如果OnItemTouchListener
得到更新,SimpleOnItemTouchListener
仍将返回默认行为。
有关“如果界面可能会更改”的部分。他们是在谈论OnItemTouchListener
吗?
但是,SimpleOnItemTouchListener
似乎只有空方法,而没有其他内容。
答案 0 :(得分:13)
假设您具有此界面:
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
这甚至不是您的错,您没有进行任何更改!只是界面已更改,并且您的代码不是最新的。< / p>
为避免这种情况,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
似乎只有空方法,而没有其他内容。
是的。他们提供的“默认行为”只是“什么都不做”。这只是避免编译失败的一种方法。
您仍然必须以有意义的方式实现这些方法。但是现在,如果引入了新方法,您将拥有一个安全网。
我想说的是您实际上了解它的要旨,只是空的默认实现令人困惑。
答案 1 :(得分:7)
这是因为SimpleOnItemTouchListener实现了OnItemTouchListener并提供了一些默认行为吗?
不,它只是用空方法实现接口。如您所知,实现接口时,需要为所有接口方法添加定义,否则会出现编译错误。但是,如果您扩展了一个类,则无需覆盖所有基本方法(嗯...除非它们不是抽象的-但这不是这里的情况)。
有关界面是否可能更改的部分。他们在谈论OnItemOnTouchListener吗?
是的,他们谈论接口RecyclerView.OnItemTouchListener被更改:
假设它们在RecyclerView.OnItemTouchListener中添加了一个新方法:void foo()
,那么,如果升级支持库并且您已经在类RecyclerView.OnItemTouchListener
中直接实现了该方法,则会遇到编译器错误(您将需要在您的课程中实现foo()
)。在comment you quote中,Android团队承诺他们将在SimpleOnItemTouchListener中实现foo(),因此,如果在MyOnItemTouchListener
中对其进行扩展,它们将已经具有空的实现-因此不会发生编译错误。
答案 2 :(得分:5)
我发现它或多或少是Adapter的实现。随着android的不断发展,交互作用将永远不会相同,并且会随着OS的发展而不断发展。
在这里,可以实现根接口OnItemTouchListener
,以便应用程序可以控制已消耗或正在消耗的触摸事件。用简单的话来说,OnItemTouchListener
说:“ 您要处理触摸事件吗?实施我!但是请准备好处理我为您捕捉到的各种新手势。我很动态“
现在另一个人SimpleOnItemTouchListener
介于中间,并说,“嘿,我可以
您的顾问OnItemTouchListener
。我们可以就要处理的内容达成协议。即使OnItemTouchListener
为新事物着迷,我也会帮助您保持镇定,不要改变。我会忍受的,并确保您不会被打扰”
因此,OnItemTouchListener
的简单用法可能会随着Android的发展而变化。 SimpleOnItemTouchListener
可能会与OnItemTouchListener
一起发展,但不会在任何当前行为中被淘汰或遗迹化。
添加更多内容,因为SimpleOnItemTouchListener
为您提供了默认的实现,因此您的代码看起来很简洁,因为您只需要覆盖所需的内容即可。
答案 3 :(得分:5)
我目前正在为我正在处理的项目开发一个插件框架。我试图通过对界面进行版本控制来解决此问题。我确实有像walen所说的基本实现。但是,我担心实现接口而不是基本实现的人员。当然,如果我更改界面并发布,我只会破坏那些决定不扩展基类的插件。
核心应用程序使用该部分代码所需的任何版本的接口。 V2版本的接口将扩展V1,V3扩展V2,等等。我没有直接调用所有插件,而是有一个可以工作的manager类。这样一来,我可以确保如果尝试执行V3功能,则只能在实现了V3版本插件界面的插件上执行。
如果我只是公开基类并从公共API隐藏接口,那么我可能只需要其他人扩展的基础实现就可以实现。不幸的是,由于该接口也是公共的,因此我必须确保不破坏没有扩展基类的开发人员。