2012-05-05 3 views
0

私はカスタムCursorAdapterを実装しました。このアダプターはCursorからデータを受け取り、そのほとんどをListViewに入れます。 ListViewのフィールドの1つに別のテーブルのデータが必要なので、ビューにそのピースを設定するにはデータベースを再度照会する必要があります。私のListViewは正常に動作しているようですが、以前はdbにデータがなく、空のタグ"no data in the db"が正しく表示されていました。 dbにデータがあるので、ListViewには何も表示されません!カスタムCursorAdapterはデータを表示しません

// get schedule cursor 
      scheduleInfo = dbInfo.getScheduleCursor(teamID, seasonID); 
      startManagingCursor(scheduleInfo); 

      ScheduleAdapter scheduleAdapter = new ScheduleAdapter(ScheduleMain.this, scheduleInfo); 
      setListAdapter(scheduleAdapter); 

EDIT:チームのスケジュールを表示するようになっているカスタムアダプタを呼び出している アクティビティここでは、このアダプターに私の呼び出しは

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

    } 
} 

です:ここに私のカスタムアダプタです。最初にチームを選択するダイアログを表示し、別のダイアログを表示して適切なシーズンを選択します。次に、一致するteamIDとseasonIDを持つスケジュールをdbに照会します。カスタムアダプターの理由は、スケジュールが相手を整数の外部キーとしてリストするので、相手の適切なチーム名を取得するためにアダプターのdbを照会する必要があるからです。

ここここ活性(コードのそのかなり多く)

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()メソッドScheduleAdapterにおいて

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

'getScheduleCursor'のクエリはどんな行を返しますか? – Chopin

+0

startManagingCursor()を使用することをお勧めします。代わりに、LoaderManagerを使用してください。 –

+0

@Chopin、それは行を返す。 – g2gsr

答えて

1

、使用されますルートビューにアタッチしない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に追加されたすべての項目についてDBを照会します。

EDIT:あなたが改善することができもの:

A)の代わりにあなたの活動は、あなたがsetOnItemClickListenerにそれを渡す必要があるとき、匿名型を使用し、OnItemClickListener(および他のインターフェース)を実装するために作ら:

diaList.setOnItemClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 

       } 
      }); 

B)JOINを実行(およびアダプタ内に新しい接続をオープン避けるために)、あなたを構築するためにSQLiteQueryBuilderを使用Rクエリ式:

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

リスナー内であればそれはdoesnのように、あなたは(コンテキストとして渡すthisを使用することはできませんtはアクティビティを参照してください)。このような場合、あなたは活動にatributteを宣言することができます。

Context context; 

OnCreateでそれを初期化します。その後、

this.context = this; 

そして、あなたがそれを必要なときだけでcontextを呼び出すことによって、それを使用します。

+0

さて、私はそれを試して、それは動作しませんでした。それから私はエミュレータでデータを消去しようとしました。アプリをもう一度実行すると、以前はDBクラスのnullPointExcepが発生していましたが、これは数日で触れられていません。だからイライラする!!!私はいくつかのコードを並べ替え、DBクラスに私の元の問題に関連する隠された問題があるかどうかを調べるつもりです。 – g2gsr

+0

ああ、それは悪いです:([MatrixCursor](http://developer.android.com/reference/android/database/MatrixCursor.html)を使って実際のカーソルを模擬し、DBから抽象化することができます。 – Chopin

+0

さて、私は以前のコメントで言ったことを試してみたところ、あなたのアダプタはうまく動作しました(しかし、 'try .. catch ..にコメントしました。 'bindView'内でブロックし、' MatrixCursor'から直接チーム名を取得しました)また、私の答えで投稿したものは、アダプタが動作するために必要だったので、 'newView'メソッドはテストでは一度も呼び出されていないと思います – Chopin