10.5. ViewBinder: TimelineAdapter之外的更好选择

优质
小牛编辑
122浏览
2023-12-01

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; //

}

};

...

  1. 将一个自定义的ViewBinder实例交给对应的Adapter。VIEW_BINDER的定义在后面给出。
  2. ViewBinder的实现部分。留意它是一个内部类,外面的类不可以使用它,因此不必把它暴露在外。同时留意下static final表明它是一个常量。
  3. 我们需要实现的唯一方法即setViewValue()。它在每条数据与其对应的View绑定时调用。
  4. 首先检查这个View是不是我们关心的,也就是表示消息创建时间的那个TextView。若不是,返回false,Adapter也就按其默认方式处理绑定;若是,则按我们的方式继续处理。
  5. 从cursor中取出原始的timestamp数据。
  6. 使用上个例子相同的辅助函数DateUtils.getRelativeTimeSpanString()将时间戳(timestamp)转换为人类可读的格式。这也就是我们扩展的业务逻辑。
  7. 更新对应View中的文本。
  8. 返回true,因此SimpleCursorAdapter不再按照默认方式处理绑定。