我已实施自定义CursorAdapter
。此适配器从Cursor
获取数据并将其中的大部分存入ListView
。 ListView
中的一个字段需要来自不同表的数据,因此我需要再次查询数据库以在视图中设置该部分。我的ListView
似乎正在工作,就像之前我在数据库中没有数据一样,它正确显示我的空标记"no data in the db"
。现在数据库中有数据,ListView
没有显示任何内容!这是我的自定义适配器:
public class ScheduleAdapter extends CursorAdapter {
private LayoutInflater mInflater;
private int mHomeAway, mOppFK, mLocation, mWhen, mOutcome, mType, mPlayed;
private String teamName;
public ScheduleAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
mHomeAway = c.getColumnIndex(ScoreMasterDB.KEY_SCHHOMEAWAY);
mOppFK = c.getColumnIndex(ScoreMasterDB.KEY_SCHOPPFK);
mLocation = c.getColumnIndex(ScoreMasterDB.KEY_SCHLOCATION);
mWhen = c.getColumnIndex(ScoreMasterDB.KEY_SCHWHEN);
mOutcome = c.getColumnIndex(ScoreMasterDB.KEY_SCHOUTCOME);
mType = c.getColumnIndex(ScoreMasterDB.KEY_SCHTYPE);
mPlayed = c.getColumnIndex(ScoreMasterDB.KEY_SCHPLAYED);
mInflater = LayoutInflater.from(context);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
return mInflater.inflate(R.layout.schedule_main_list, parent);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
TextView homeAway = (TextView) view.findViewById(R.id.tvVsAt);
TextView oppName = (TextView) view.findViewById(R.id.tvScheduleListOpponent);
TextView location = (TextView) view.findViewById(R.id.tvScheduleListLocation);
TextView outcomeWhen = (TextView) view.findViewById(R.id.tvScheduleDateTimeResult);
TextView gameType = (TextView) view.findViewById(R.id.tvScheduleType);
ScoreMasterDB dbInfo = new ScoreMasterDB(context);
try {
dbInfo.open();
teamName = dbInfo.getTeamName(cursor.getInt(mOppFK));
dbInfo.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
homeAway.setText(cursor.getString(mHomeAway));
oppName.setText(teamName);
location.setText(cursor.getString(mLocation));
//set game time or outcome
if(cursor.getInt(mPlayed) == 0){
outcomeWhen.setText(cursor.getString(mWhen));
//set text style for outcome
if(cursor.getInt(mOutcome) == 1){
outcomeWhen.setTextAppearance(context, R.style.greenWinText);
}
}
gameType.setText(cursor.getString(mType));
}
}
以下是我对此适配器的调用:
// get schedule cursor
scheduleInfo = dbInfo.getScheduleCursor(teamID, seasonID);
startManagingCursor(scheduleInfo);
ScheduleAdapter scheduleAdapter = new ScheduleAdapter(ScheduleMain.this, scheduleInfo);
setListAdapter(scheduleAdapter);
编辑: 调用自定义适配器的活动应该显示团队的日程安排。它通过首先显示一个选择团队的对话框,然后显示另一个选择适当季节的对话框来实现。然后,它使用匹配的teamID和seasonID向数据库查询计划。自定义适配器的原因是日程安排会将对手列为整数外键,因此我需要查询适配器中的数据库以获取对手的相应团队名称。
这是活动(相当多的代码)
package com.scoremaster.pro;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class ScheduleMain extends ListActivity implements OnItemClickListener,
OnClickListener, OnItemLongClickListener {
Dialog selectTeam, selectSeason, newSeason;
Cursor teamInfo, seasons, scheduleInfo;
ScoreMasterDB dbInfo;
ListView diaList, diaSeason;
int teamID, seasonID;
String teamNameG;
Button addNewSeason;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.schedule_main);
selectTeam = new Dialog(ScheduleMain.this);
selectTeam.setContentView(R.layout.schedule_main_dialog);
selectTeam.setTitle("Select Team");
dbInfo = new ScoreMasterDB(this);
try {
dbInfo.open();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
teamInfo = dbInfo.getTeamsCursor();
startManagingCursor(teamInfo);
if (teamInfo.getCount() == 0) {
Intent createTeamIntent = new Intent(
"com.scoremaster.pro.CREATETEAM");
createTeamIntent.putExtra("fromSchedule", true);
startActivity(createTeamIntent);
}
String[] columns = { ScoreMasterDB.KEY_TEAMNAME };
int[] to = { R.id.tvTeamSelectList };
//Bundle scheduleBundle = getIntent().getExtras();
//int whatToDo = scheduleBundle.getInt(")
diaList = (ListView) selectTeam.findViewById(R.id.lvScheduleDialog);
SimpleCursorAdapter teamListAdapter = new SimpleCursorAdapter(
ScheduleMain.this, R.layout.team_select_list, teamInfo,
columns, to);
diaList.setAdapter(teamListAdapter);
diaList.setOnItemClickListener(this);
selectTeam.show();
}
// listview onClick events
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
switch (parent.getId()) {
case R.id.lvScheduleDialog:
selectTeam.dismiss();
teamInfo.moveToPosition(position);
// set data on ScheduleMain
TextView teamName = (TextView) findViewById(R.id.tvScheduleTeam);
TextView teamAbbrev = (TextView) findViewById(R.id.tvScheduleAbbrev);
TextView teamLevel = (TextView) findViewById(R.id.tvScheduleLevel);
LinearLayout layTeam = (LinearLayout) findViewById(R.id.layScheduleTeam);
Button bAddSchedule = (Button) findViewById(R.id.bAddGame);
teamNameG = teamInfo.getString(1);
teamName.setText(teamInfo.getString(1));
teamAbbrev.setText(teamInfo.getString(2));
teamLevel.setText(teamInfo.getString(3));
bAddSchedule.setText("Add Game to Schedule");
bAddSchedule.setClickable(true);
teamID = teamInfo.getInt(0);
// set button if no team
if (teamInfo.getCount() == 0) {
}
// set listeners for bAddGame and laySheduleTeam
bAddSchedule.setOnClickListener(this);
layTeam.setOnClickListener(this);
// get season information
selectSeason = new Dialog(ScheduleMain.this);
selectSeason.setContentView(R.layout.schedule_season_dialog);
selectSeason.setTitle("Select Season");
seasons = dbInfo.getSeasonsCursor(teamID);
startManagingCursor(seasons);
String[] columns = { ScoreMasterDB.KEY_SEANAME };
int[] to = { R.id.tvTeamSelectList };
// set select season dialog listview elements
diaSeason = (ListView) selectSeason
.findViewById(R.id.lvSeasonDialog);
SimpleCursorAdapter seasonListAdapter = new SimpleCursorAdapter(
ScheduleMain.this, R.layout.team_select_list, seasons,
columns, to);
diaSeason.setAdapter(seasonListAdapter);
diaSeason.setOnItemClickListener(this);
diaSeason.setOnItemLongClickListener(this);
// set add button listenter
Button addSeason = (Button) selectSeason
.findViewById(R.id.bAddSeason);
addSeason.setOnClickListener(this);
// show dialog
selectSeason.show();
break;
case R.id.lvSeasonDialog:
// get seasonID
selectSeason.dismiss();
seasons.moveToPosition(position);
seasonID = seasons.getInt(0);
// get schedule cursor
scheduleInfo = dbInfo.getScheduleCursor(teamID, seasonID);
startManagingCursor(scheduleInfo);
//scheduleInfo.moveToFirst();
//String[] columns1 = {ScoreMasterDB.KEY_SEANAME};
//int[] to1 = {R.id.tvScheduleAddVsAt};
//SimpleCursorAdapter scheduleAdapter = new SimpleCursorAdapter(ScheduleMain.this, R.layout.schedule_main_list, seasons, columns1, to1);
ScheduleAdapter scheduleAdapter = new ScheduleAdapter(ScheduleMain.this, scheduleInfo);
setListAdapter(scheduleAdapter);
break;
}
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bAddSeason:
selectSeason.dismiss();
newSeason = new Dialog(ScheduleMain.this);
newSeason.setContentView(R.layout.schedule_new_season);
newSeason.setTitle("New Season");
TextView teamName = (TextView) newSeason
.findViewById(R.id.tvNewSeasonTeamName);
teamName.setText("Create new season for the " + teamNameG);
addNewSeason = (Button) newSeason
.findViewById(R.id.bSubmitNewSeason);
addNewSeason.setOnClickListener(this);
newSeason.show();
break;
case R.id.bSubmitNewSeason:
TextView seasonName = (TextView) newSeason
.findViewById(R.id.etNewSeasonName);
String submitSeason = seasonName.getText().toString();
if (submitSeason.equalsIgnoreCase("")) {
Toast.makeText(ScheduleMain.this, "Please enter a season name",
Toast.LENGTH_SHORT).show();
} else {
try {
dbInfo.insertSeason(teamID, submitSeason);
} catch (Exception e) {
e.printStackTrace();
} finally {
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
break;
case R.id.bAddGame:
Intent addGame = new Intent("com.scoremaster.pro.ADDGAME");
addGame.putExtra("teamID", teamID);
addGame.putExtra("seasonID", seasonID);
startActivity(addGame);
break;
case R.id.layScheduleTeam:
selectTeam.show();
break;
}
}
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
if (parent.getId() == R.id.lvSeasonDialog) {
seasons.moveToPosition(position);
int rowID = seasons.getInt(0);
dbInfo.removeSeason(rowID);
selectSeason.dismiss();
Intent intent = getIntent();
finish();
startActivity(intent);
return true;
} else {
return false;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
}
}
这是DB类中的getScheduleCursor()方法
public Cursor getScheduleCursor(int teamID, int seasonID){
String[] columnsSch = {KEY_ROWID, KEY_SCHHOMEAWAY, KEY_SCHOPPFK, KEY_SCHLOCATION, KEY_SCHWHEN, KEY_SCHOUTCOME, KEY_SCHTYPE, KEY_SCHPLAYED};
Cursor c = scoreMasterDB.query(DB_SCHEDULE_TABLE, columnsSch, KEY_SCHTEAMFK + "=" + teamID + " AND " + KEY_SCHSEASON + "=" + seasonID, null, null, null, null);
return c;
}
答案 0 :(得分:1)
在ScheduleAdapter
中,在对视图进行充气时,请使用未附加到根视图的inflate()
版本:
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
return mInflater.inflate(R.layout.schedule_main_list, parent, false);
}
另请注意,如果在原始游标(包括或替换teamName
)中包含mOppFK
而不是在绑定视图时创建与数据库的新连接以获取它,那会更好,因为您正在建立新连接并查询数据库中添加到ListView
的每个项目。
编辑:您可以改进的事项:
A)当您需要将其传递给OnItemClickListener
时,请使用匿名类型而不是让您的活动实现setOnItemClickListener
(以及其他接口):
diaList.setOnItemClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
B)要执行JOIN
(并避免在适配器中打开新连接),请使用SQLiteQueryBuilder
构建查询表达式:
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables("foo LEFT OUTER JOIN bar ON (foo.id = bar.foo_id)")
Cursor cursor = qb.query(...);
C)不确定您在这里尝试做什么:
Intent intent = getIntent();
finish();
startActivity(intent);
您想重新开始活动吗?为什么不再打开第一个对话框?
D)以这种方式创建新Intent
让我感觉更舒服:
Intent createTeamIntent = new Intent(this, CREATETEAM.class));
如果您在侦听器中,则不能使用this
作为上下文传递(因为它不引用该活动)。在这种情况下,您可以在活动中声明atributte:
Context context;
在OnCreate
中初始化:
this.context = this;
然后只需拨打context
即可随时使用。