10.5. ViewBinder: TimelineAdapter之外的更好选择
10.5.ViewBinder: TimelineAdapter之外的更好选择
除去继承一个 TimelineAdapter 并覆盖bindView()方法外,我们也可以直接为 SimpleCursorAdapter 添加业务逻辑。这样既能保留原先的bindView()所做的工作,又省去一个类,更加简便。
SimpleCursorAdapter提供了一个setViewBinder()方法为它的业务逻辑提供扩展,它取一个ViewBinder的实现作为参数。ViewBinder是个接口,里面声明了一个setViewValue()方法,也就是在这里,它将具体的日期元素与View真正地绑定起来。
同样,我们可以在官方文档中发现这一特性。
如下即针对TimelineAdapter的最后一轮迭代,在此实现一个自定义的ViewBinder作为常量,并把它交给SimpleCursorAdapter。
例 10.8. TimelineActivity.java with ViewBinder
...
@Override
protected void onResume() {
...
adapter.setViewBinder(VIEW_BINDER); //
...
}
// View binder constant to inject business logic that converts a timestamp to
// relative time
static final ViewBinder VIEW_BINDER = new ViewBinder() { //
public boolean setViewValue(View view, Cursor cursor, int columnIndex) { //
if (view.getId() != R.id.textCreatedAt)
return false; //
// Update the created at text to relative time
long timestamp = cursor.getLong(columnIndex); //
CharSequence relTime = DateUtils.getRelativeTimeSpanString(view
.getContext(), timestamp); //
((TextView) view).setText(relTime); //
return true; //
}
};
...
- 将一个自定义的ViewBinder实例交给对应的Adapter。VIEW_BINDER的定义在后面给出。
- ViewBinder的实现部分。留意它是一个内部类,外面的类不可以使用它,因此不必把它暴露在外。同时留意下static final表明它是一个常量。
- 我们需要实现的唯一方法即setViewValue()。它在每条数据与其对应的View绑定时调用。
- 首先检查这个View是不是我们关心的,也就是表示消息创建时间的那个TextView。若不是,返回false,Adapter也就按其默认方式处理绑定;若是,则按我们的方式继续处理。
- 从cursor中取出原始的timestamp数据。
- 使用上个例子相同的辅助函数DateUtils.getRelativeTimeSpanString()将时间戳(timestamp)转换为人类可读的格式。这也就是我们扩展的业务逻辑。
- 更新对应View中的文本。
- 返回true,因此SimpleCursorAdapter不再按照默认方式处理绑定。