10.4. TimelineAdapter

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

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

}

}

  1. 创建我们自定义的 Adapter,它继承了 Android 提供的 Adapter 类,这里将它命名为 SimpleCursorAdapter。
  2. 跟上个例子一样,这个常量用以指明数据库中我们感兴趣的列。
  3. 这个常量用以指明数据列对应View的ID。
  4. 因为是新定义的类,因此需要一个构造函数。在这里仅仅通过super调用父类的构造函数即可。
  5. 这里只覆盖了一个方法,即bindView()。这个方法在映射每行数据到View时调用,Adapter的主要工作在这里进行了。要重用SimpleCursorAdapter原有的映射操作(数据到View),记得先调用super.bindView()。
  6. 覆盖默认针对timestamp的映射操作,需要先得到数据库中timestamp的值。
  7. 然后找到对应的TextView,它的定义在row.xml。
  8. 最后,依据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); //

}

}

  1. 修改SimpleCursorAdapter为TimelineAdapter。
  2. 新建一个TimelineAdapter的实例,交给它上下文及数据的引用。
  3. 将ListView与这个Adapter关联,从而与数据库绑定。