3

对于我来说,在ListView中为每行注册一个独特的OnClickListener会更方便,但我想确保这是一种可接受的做法。我的current design是一个相当复杂的方式,将OnClickListener与各行类型的问题区分开来。为每个ListView行实现onClickListener而不是onItemClickListener是否有缺点?

原因是我在ListView中有多行的行。每个班级都有完全不同的责任和行为。例如,考虑可包含子类别和书名的ListView。如果点击了书名,应该开始一个显示封面图片的新活动。如果点击了子类别,则会显示新的书籍和类别列表。

我希望行本身能够保持有关其自身身份和责任的知识,而不必泄露关于由onItemClickListener的实施者维护的每行的知识。

我也想知道这样做的性能影响与实现我自己的逻辑来找出如何处理点击。

对于每个ListViewArrayAdapter行而不是onItemClickListener实施onClickListener是否存在缺陷?我在寻找具体数据特定缺点而不是含糊不清的建议。

我应该期待内存使用初始化时间,或稳态速度(如滚动列表)将显著影响?

回答

5

你不解释为什么你需要为每一行单独的点击监听器,但我会建议反对它。看看如何使用View.setTag(Object)/View.getTag()来传递行特定的自定义数据,通过这些自定义数据您可以自定义(共享)点击侦​​听器的响应。

编辑

我从你的例子看,为什么你想连接到你的行不同OnClickListener秒。我的印象是,你想为每一行单独的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()覆盖,使用此逻辑:

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) 
    } 
} 
+0

@glenviewjeff - 我更新了我的答案回复。 – 2012-03-14 22:05:49

+0

+1,非常感谢Ted的详细回复。你有没有可能在Android API中有任何数据或建议,证明你的建议是针对每行一个听众的,或者你是基于更多的预感? – 2012-03-15 13:19:39

+2

使用基于标签的解决方案需要注意的一件事是确保您在每个'getView()'''bindView()'调用上更新标签。传统的“视图持有者”模式仅在行被充值时设置标签,但这是因为“持有者”仅包含与UI相关联的东西(例如,行中的小部件)。在这里描述的模式中,标签需要保存与模型数据相关的东西,因此会随着每个位置而改变。尽管如此,我仍然会推荐每行使用单独的点击监听器。 – CommonsWare 2012-03-15 13:40:04

相关问题