2012-05-05 6 views
0

CursorAdapter 사용자 지정을 구현했습니다. 이 어댑터는 Cursor에서 데이터를 가져 와서 대부분을 ListView에 저장합니다. ListView의 필드 중 하나에 다른 테이블의 데이터가 필요하므로 뷰에 해당 부분을 설정하려면 데이터베이스를 다시 쿼리해야합니다. 내 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); 

편집 : 팀의 일정을 표시하도록되어 사용자 정의 어댑터를 호출 활동 여기에이 어댑터에 내 전화가

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

    } 
} 

입니다 : 여기 내 사용자 지정 어댑터입니다. 먼저 팀을 선택하는 대화 상자를 표시 한 다음 적절한 시즌을 선택할 수있는 또 다른 대화 상자를 표시합니다. 그런 다음 db에 일치하는 teamID 및 seasonID가있는 일정을 쿼리합니다. 사용자 지정 어댑터의 이유는 일정이 상대 외래 키를 정수 외래 키로 표시하기 때문에 어댑터의 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 클래스

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

ScheduleAdapter에서보기를 팽창, 사용중인 getScheduleCursor() 메소드입니다 루트보기에 연결하지 않는 inflate()의 버전 :

참고 : teamName을 원래 커서에 포함하거나 (mOppFK 대체) 데이터베이스에 새로운 연결을 작성하는 대신보기를 바인딩 할 때 가져 오는 것이 더 좋을 것입니다. 새 연결을 만들고 있기 때문입니다. ListView에 추가 된 모든 항목에 대해 DB를 쿼리하십시오.

편집 : 일들이 당신 향상시킬 수

A) 대신 당신이 setOnItemClickListener에 전달해야하는 경우, 익명 형식을 사용) OnItemClickListener (다른 인터페이스를 구현하는 활동했다 :

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

       } 
      }); 

B) 당신을 구축하기 위해 SQLiteQueryBuilder를 사용) 수행합니다 JOIN (어댑터 내부 열린 새 연결을 방지하려면 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)); 

, 당신은 컨텍스트로 전달할 this을 사용할 수 없습니다를 t 활동을 참조하십시오).

Context context; 

OnCreate에 초기화 :

this.context = this; 

을 그리고 당신은 단순히 context를 호출하여, 필요할 때마다 그것을 사용 등의 경우에는 활동에 atributte을 선언 할 수 있습니다.

+0

글쎄, 나는 그것을 시도하고 그것은 작동하지 않았다. 그런 다음 에뮬레이터에서 데이터를 지우려고했습니다. 응용 프로그램을 다시 실행하면 DB 클래스에서 일찍 발생한 nullPointExcep가 발생합니다. 그렇게 초조하게하는 것! !! 몇 가지 코드를 재 배열하고 DB 클래스에 내 원래 문제와 관련된 숨겨진 문제가 있는지 살펴 보겠습니다. – g2gsr

+0

오, 그건 나쁜거야 : ([MatrixCursor] (http://developer.android.com/reference/android/database/MatrixCursor.html)를 사용하면 실제 커서를 조롱하고 DB에서 추상화 할 수 있습니다. 그런 다음 문제가 DB 클래스 또는 어댑터 (또는 다른 곳)에 있는지 확인하십시오. – Chopin

+0

글쎄, 난 그냥 내 이전 의견에서 말한 시도하고 어댑터가 잘 작동하지만 ('try .. catch .. ''bindView' 내부에서 차단하고 내 'MatrixCursor'에서 직접 팀 이름을 얻었습니다.) 또한 내 대답에 게시 한 것은 어댑터가 작동해야한다는 것입니다. 따라서 newView 메소드가 테스트에서 호출 된 적이없는 것 같습니다. – Chopin

관련 문제