10.4. TimelineAdapter
10.4.TimelineAdapter
TimelineAdapter就是我们自定义的Adapter。虽说SimpleCursorAdapter映射起数据来倒也直白,但是我们在这里还有个Unix时间戳(timestamp)需要特殊处理。这也属于TimelineAdapter的工作:加入业务逻辑,将Unix时间戳转换为相对时间。可知SimpleCursorAdapter是在bindView()里面处理View的显示,因此覆盖这个方法,在数据显示之前处理一下即可。
一般来讲,若不清楚类里需要覆盖的方法是哪个,查阅相关的官方文档即可。在这里,可以参阅http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html。
例 10.6. TimelineAdapter.java
package com.marakana.yamba5;
import android.content.Context;
import android.database.Cursor;
import android.text.format.DateUtils;
import android.view.View;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
public class TimelineAdapter extends SimpleCursorAdapter { //
static final String[] FROM = { DbHelper.C_CREATED_AT, DbHelper.C_USER,
DbHelper.C_TEXT }; //
static final int[] TO = { R.id.textCreatedAt, R.id.textUser, R.id.textText }; //
// Constructor
public TimelineAdapter(Context context, Cursor c) { //
super(context, R.layout.row, c, FROM, TO);
}
// This is where the actual binding of a cursor to view happens
@Override
public void bindView(View row, Context context, Cursor cursor) { //
super.bindView(row, context, cursor);
// Manually bind created at timestamp to its view
long timestamp = cursor.getLong(cursor
.getColumnIndex(DbHelper.C_CREATED_AT)); //
TextView textCreatedAt = (TextView) row.findViewById(R.id.textCreatedAt); //
textCreatedAt.setText(DateUtils.getRelativeTimeSpanString(timestamp)); //
}
}
- 创建我们自定义的 Adapter,它继承了 Android 提供的 Adapter 类,这里将它命名为 SimpleCursorAdapter。
- 跟上个例子一样,这个常量用以指明数据库中我们感兴趣的列。
- 这个常量用以指明数据列对应View的ID。
- 因为是新定义的类,因此需要一个构造函数。在这里仅仅通过super调用父类的构造函数即可。
- 这里只覆盖了一个方法,即bindView()。这个方法在映射每行数据到View时调用,Adapter的主要工作在这里进行了。要重用SimpleCursorAdapter原有的映射操作(数据到View),记得先调用super.bindView()。
- 覆盖默认针对timestamp的映射操作,需要先得到数据库中timestamp的值。
- 然后找到对应的TextView,它的定义在row.xml。
- 最后,依据timestamp的值设置textCreatedAt的值为相对时间。通过DateUtils.getRelativeTimeSpanString()。
前面将Adapter相关的一些细节移入了TimelineAdapter,因此可以进一步简化TimelineActivity类。
例 10.7. TimelineActivity.java, version 3
package com.marakana.yamba5;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.ListView;
public class TimelineActivity3 extends Activity {
DbHelper dbHelper;
SQLiteDatabase db;
Cursor cursor;
ListView listTimeline;
TimelineAdapter adapter; //
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.timeline);
// Find your views
listTimeline = (ListView) findViewById(R.id.listTimeline);
// Connect to database
dbHelper = new DbHelper(this);
db = dbHelper.getReadableDatabase();
}
@Override
public void onDestroy() {
super.onDestroy();
// Close the database
db.close();
}
@Override
protected void onResume() {
super.onResume();
// Get the data from the database
cursor = db.query(DbHelper.TABLE, null, null, null, null, null,
DbHelper.C_CREATED_AT + " DESC");
startManagingCursor(cursor);
// Create the adapter
adapter = new TimelineAdapter(this, cursor); //
listTimeline.setAdapter(adapter); //
}
}
- 修改SimpleCursorAdapter为TimelineAdapter。
- 新建一个TimelineAdapter的实例,交给它上下文及数据的引用。
- 将ListView与这个Adapter关联,从而与数据库绑定。