作为简化示例,请考虑可以包含子类别和书名的ListView
。如果单击书名,则应开始显示封面图像的新活动。如果单击子类别,则会显示新的书籍和类别列表。
Row
接口定义如下。
interface Row {
void onClick();
void draw(View v);
}
我想知道如何防止ListView
的{{1}}以及ArrayAdapter
实施者onItemClickListener
的实施者的依赖关系(例如, Row
和Book
)。
推动此要求的一个因素是“不要重复自己”(DRY)原则:引入新行类型时,Category
实现不需要更改。
答案 0 :(得分:1)
原谅我下面的鸡抓“UML”,但这就是我的表现方式。
class ListAdapter extends ArrayAdapter<Row<?>> {
...
public View getView(int position, View convertView, ViewGroup parent) {
View view = listViewRowViewRecycler.getView(convertView);
rowProvider.get().getRow(position).draw(view);
return view;
}
}
OnItemClickListener
的实施者有这样的方法:
void onItemClick(AdapterView<?> adapterView, View view, int rowIndex, long rowId)
{
rowProvider.onItemClick(rowIndex);
}
然后RowProvider
有这样的方法:
void onItemClick(int rowIndex) {
rowList.get(rowIndex).onClick();
}
然后Row
接口有一个签名为void onClick()
的方法,Category
和Book
的{{1}}实现提供了必要的行为。
答案 1 :(得分:0)
另一种可能性是在列表中的每个项目的View上使用setTag / getTag方法 - 这允许您将“Book”或“Category”附加到其相应的行。
为此,每个“列出的”项应该实现一个公共接口,该接口具有在单击时调用的适当方法。
例如:
interface Selectable {
void onSelected(); // Add parameters if necessary...
}
在列表适配器中:
public View getView(int position, View convertView, ViewGroup parent) {
View itemView; // Logic to get the appropriate view for this row.
Selectable theObjectBeingRepresented;
//
// Logic to assign a Book/Category, etc to theObjectBeingRepresented.
// In this example assume there is a magic Book being represented by
// this row.
//
Book aMagicBook = new Book();
theObjectBeingRepresented = aMagicBook;
// If all objects that will be contained in your list implement the
// 'Selectable' interface then you can simply call setTag(...) with
// the object you are working with (otherwise you may need some conditional logic)
//
itemView.setTag( SELECTABLE_ITEM_KEY, theObjectBeingRepresented );
}
然后点击某个项目时:
void onItemClick(AdapterView<?> adapterView, View view, int rowIndex, long rowId)
{
Selectable item = (Selectable)view.getTag( SELECTABLE_ITEM_KEY );
// Depending on how you are populating the list, you may need to check for null
// before operating on the item..
if( null != item ) {
item.onClick(); // Appropriate implementation called...
}
}
关于setTag方法的更多细节: setTag documentation
希望这会有所帮助......