Android 为每个ListView行实现onClickListener而不是onItemClickListener是否存在缺点?

Android 为每个ListView行实现onClickListener而不是onItemClickListener是否存在缺点?,android,listview,android-listview,android-arrayadapter,onclicklistener,Android,Listview,Android Listview,Android Arrayadapter,Onclicklistener,对于我来说,为列表视图中的每一行注册一个唯一的OnClickListener会更方便,但我想确保这是一种可接受的做法。My是一种相当复杂的方法,可以将OnClickListener的关注点与每种行类型分开 原因是我在列表视图中有多类行。每个班级都有完全不同的责任和行为。例如,考虑一个可以包含子类别和书名的 ListVIEW < /代码>。如果单击书籍标题,则应启动显示封面图像的新活动。如果单击子类别,将显示新的书籍和类别列表 我希望行本身维护关于其自身身份和责任的知识,而不是必须泄漏关于onIt

对于我来说,为
列表视图
中的每一行注册一个唯一的
OnClickListener
会更方便,但我想确保这是一种可接受的做法。My是一种相当复杂的方法,可以将
OnClickListener
的关注点与每种行类型分开

原因是我在
列表视图中有多类行。每个班级都有完全不同的责任和行为。例如,考虑一个可以包含子类别和书名的<代码> ListVIEW < /代码>。如果单击书籍标题,则应启动显示封面图像的新活动。如果单击子类别,将显示新的书籍和类别列表

我希望行本身维护关于其自身身份和责任的知识,而不是必须泄漏关于
onItemClickListener
的实现者要维护的每一行的知识

我还想知道这样做与实现我自己的逻辑以找出如何处理点击相比,对性能的影响是什么

对于每个
ListView
ArrayAdapter
行,而不是
onItemClickListener
,实现
onClickListener
是否存在缺点?我在寻找具体的数据和具体的缺点,而不是含糊不清的建议


我是否认为内存使用、初始化时间或稳态速度(如滚动列表)会受到显著影响?

您没有解释为什么每行需要单独的单击侦听器,但我建议不要这样做。看看如何使用
View.setTag(Object)
/
View.getTag()
传递特定于行的自定义数据,通过这些数据可以自定义(共享)单击侦听器的响应

编辑

我从您的示例中了解到,为什么要将不同的
OnClickListener
s附加到行中。我的印象是,您希望为每一行提供一个单独的
OnClickListener
实例。(这是我反对的主要原因。)如果你有两种类型的行(类别和标题)和数百行,你只需要两种类型的响应,而不是数百种。我也理解分离关注点的意义

尽管如此,我认为重写
ListActivity.onListItemClick()
(或者如果不使用
ListActivity
,则调用
ListView.setOnItemClickListener()
)会更干净,并且不太可能干扰列表视图的操作。您可以为此使用委托模式,如下所示

定义抽象类或接口:

public interface MyClickHandler {
    public void onItemClick(ListView l, View v, int position, long id);
}
然后为每种类型的行数据创建一个实现此接口的对象实例(而不是每行一个实例)。在适配器中,使用
setTag(Object)
将每行的标记初始化为相应的
MyClickHander
实例。在
ListActivity.onListItemClick()
override中,使用以下逻辑:

protected void onListItemClick(ListView l, View v, int position, long id) {
    Object tag = v.getTag();
    if (tag instanceof MyClickHandler) {
        ((MyClickHandler) tag).onItemClick(l, v, position, id);
    } else {
        // default processing (if any)
    }
}

+1非常感谢Ted的详细回复。您是否碰巧在Android API中有任何数据或建议可以证明您的建议是针对每行一个侦听器的,或者您是基于更多的直觉吗?使用基于标记的解决方案时,需要注意的一点是确保您在每次调用
getView()
/
bindView()
时都更新标记。经典的“视图持有者”模式仅在行膨胀时设置标记,但这是因为“持有者”仅保存与UI相关的内容(例如,行中的小部件)。在这里描述的模式中,标记需要保留绑定到模型数据的东西,因此会随着每个位置而改变。尽管如此,我还是推荐这样的方法,而不是每行使用单独的单击侦听器。Ted,请参阅my,它描述了我比较喜欢的方法来分离不涉及
instanceof
的关注点,并将信息泄漏到
onListItemClick
方法中。您回答这个问题的原因不是问如何做到这一点,而是问注册单个行侦听器的后果。@glenviewjeff-您在后续问答中概述的方法知道UI泄漏到模型中。与我概述的方法相比,关注的分离更少。我同意使用
instanceof
有点令人不快,但视图标记的匿名性迫使这种方法如此。(如果可以假设非空标记总是MyClickHandler的实例,那么MyClickHander的
实例可以替换为
!=null
和一个cast。(仍然不干净,但可能不那么脏。)@Commonware感谢您指出了关键角色
getView()/bindView()
我在回答中提到了这一点,但这一点还不清楚。