2012-11-05 23 views
0

我(並已一段時間了),在Android項目,該項目將作爲一個非常基本的課程表應用工作。到目前爲止,我有以下工作:將課程添加到數據庫,從數據庫中刪除課程,顯示具有位置和主題的課程列表,打開「作業」菜單以創建課程作業。寫入到數據庫中第二個表的Android應用程序

的問題是,當我嘗試點擊創建任務菜單上的保存按鈕,它只是不分配添加到列表中。

分配名單是「課程」數據庫(標記lunchlist.db)中的第二個表。下面附上負責處理作業的三個類。

分配列表:

public class AssList extends ListActivity { 
    public final static String ID_EXTRA = "apt.tutorial._ID"; 
    Cursor model = null; 
    AssAdapter adapter = null; 
    AssHelper helper = null; 
    SharedPreferences prefs = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.ass); 

     helper = new AssHelper(this); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 

     helper.close(); 
    } 

    @Override 
    public void onListItemClick(ListView list, View view, int position, long id) { 
     Intent i = new Intent(AssList.this, AssForm.class); 

     i.putExtra(ID_EXTRA, String.valueOf(id)); 
     startActivity(i); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     new MenuInflater(this).inflate(R.menu.ass_option, menu); 

     return (super.onCreateOptionsMenu(menu)); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     if (item.getItemId() == R.id.add_ass) { 
      startActivity(new Intent(AssList.this, AssForm.class)); 

      return (true); 
     } 

     return (super.onOptionsItemSelected(item)); 
    } 

    public void initList() { 
     if (model != null) { 
      stopManagingCursor(model); 
      model.close(); 
     } 

     model = helper.getAll(prefs.getString("sort_order", "name")); 
     startManagingCursor(model); 
     adapter = new AssAdapter(model); 
     setListAdapter(adapter); 
    } 

    private SharedPreferences.OnSharedPreferenceChangeListener prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() { 
     public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, 
       String key) { 
      if (key.equals("sort_order")) { 
       initList(); 
      } 
     } 
    }; 

    class AssAdapter extends CursorAdapter { 
     AssAdapter(Cursor c) { 
      super(AssList.this, c); 
     } 

     @Override 
     public void bindView(View row, Context ctxt, Cursor c) { 
      AssHolder holder = (AssHolder) row.getTag(); 

      holder.populateFrom(c, helper); 
     } 

     @Override 
     public View newView(Context ctxt, Cursor c, ViewGroup parent) { 
      LayoutInflater inflater = getLayoutInflater(); 
      View row = inflater.inflate(R.layout.row, parent, false); 
      AssHolder holder = new AssHolder(row); 

      row.setTag(holder); 

      return (row); 
     } 
    } 

    static class AssHolder { 
     private TextView name = null; 
     private TextView address = null; 
     private ImageView icon = null; 

     AssHolder(View row) { 
      name = (TextView) row.findViewById(R.id.title); 
      address = (TextView) row.findViewById(R.id.address); 
      icon = (ImageView) row.findViewById(R.id.icon); 
     } 

     void populateFrom(Cursor c, AssHelper helper) { 
      name.setText(helper.getName(c)); 
      address.setText(helper.getUrgency(c)); 

      if (helper.getUrgency(c).equals("normal")) { 
       icon.setImageResource(R.drawable.eg); 
      } else if (helper.getUrgency(c).equals("pending")) { 
       icon.setImageResource(R.drawable.ey); 
      } else { 
       icon.setImageResource(R.drawable.er); 
      } 
     } 
    } 
} 

分配形式:

public class AssForm extends Activity { 
    EditText name = null; 
    RadioGroup types = null; 
    AssHelper helper = null; 
    String AssId = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.ass_edit); 

     helper = new AssHelper(this); 

     name = (EditText) findViewById(R.id.assname); 
     types = (RadioGroup) findViewById(R.id.urge); 

     Button save = (Button) findViewById(R.id.save_ass); 
     Button del = (Button) findViewById(R.id.del_ass); 
     save.setOnClickListener(onSave); 
     del.setOnClickListener(onDel); 

     AssId = getIntent().getStringExtra(AssList.ID_EXTRA); 

     if (AssId != null) { 
      load(); 
     } 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 

     helper.close(); 
    } 

    private void load() { 
     Cursor c = helper.getById(AssId); 

     c.moveToFirst(); 
     name.setText(helper.getName(c)); 

     if (helper.getUrgency(c).equals("normal")) { 
      types.check(R.id.normal); 
     } else if (helper.getUrgency(c).equals("pending")) { 
      types.check(R.id.pending); 
     } else { 
      types.check(R.id.due); 
     } 

     c.close(); 
    } 

    private View.OnClickListener onSave = new View.OnClickListener() { 
     public void onClick(View v) { 
      String type = null; 

      switch (types.getCheckedRadioButtonId()) { 
      case R.id.normal: 
       type = "normal"; 
       break; 
      case R.id.pending: 
       type = "pending"; 
       break; 
      case R.id.due: 
       type = "due"; 
       break; 
      } 

      if (AssId == null) { 
       helper.insert(name.getText().toString(), type); 
      } else { 
       helper.update(AssId, name.getText().toString(), type); 
      } 

      finish(); 
     } 
    }; 

    private View.OnClickListener onDel = new View.OnClickListener() { 
     public void onClick(View v) { 
      helper.deleteValue(name.getText().toString()); 

      finish(); 
     } 
    }; 
} 

分配助手:

class AssHelper extends SQLiteOpenHelper { 
    private static final String DATABASE_NAME = "lunchlist.db"; 
    private static final int SCHEMA_VERSION = 1; 

    public AssHelper(Context context) { 
     super(context, DATABASE_NAME, null, SCHEMA_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL("CREATE TABLE assignments (_id INTEGER PRIMARY KEY AUTOINCREMENT, assname TEXT, urge TEXT);"); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // no-op, since will not be called until 2nd schema 
     // version exists 
    } 

    public Cursor getAll(String orderBy) { 
     return (getReadableDatabase().rawQuery(
       "SELECT _id, assname, urge FROM assignments ORDER BY " 
         + orderBy, null)); 
    } 

    public Cursor getById(String id) { 
     String[] args = { id }; 

     return (getReadableDatabase().rawQuery(
       "SELECT _id, assname, urge FROM assignments WHERE _ID=?", 
       args)); 
    } 

    public void insert(String name, String type) { 
     ContentValues cv = new ContentValues(); 

     cv.put("assname", name); 
     cv.put("urge", type); 

     getWritableDatabase().insert("assignments", "assname", cv); 
    } 

    public void deleteValue(String value) { 
     SQLiteDatabase db = getWritableDatabase(); 

     String whereClause = "assname" + "=?"; 
     String[] whereArgs = new String[] { String.valueOf(value) }; 
     db.delete("assignments", whereClause, whereArgs); 
     db.close(); 
    } 

    public void update(String id, String name, String type) { 
     ContentValues cv = new ContentValues(); 
     String[] args = { id }; 

     cv.put("assname", name); 
     cv.put("urge", type); 

     getWritableDatabase().update("assignments", cv, "_ID=?", args); 
    } 

    public String getName(Cursor c) { 
     return (c.getString(1)); 
    } 

    public String getUrgency(Cursor c) { 
     return (c.getString(2)); 
    } 
} 

我知道這是一個很大讀通過,但我真的很憋屈這是我的項目的最後一部分。這三個班級(所有意圖和目的)幾乎與三門課程相同。唯一的區別是變量名稱被改變並且類別引用被切換以匹配賦值類別。任何幫助或批評都非常受歡迎。提前感謝您花時間閱讀我的問題。

回答

1

後,您的修改或條目保存到數據庫中,你需要重新加載你的光標,並呼籲notifydatasetchanged()你的列表視圖來告訴它刷新。由於提交表單和ListView在不同的活動,一個必須在另一個的上面,我覺得最直接的方法就是做這些對你的清單活動的OnResume()方法,或許還有一個條件策動意圖避免無用的提神。更直白的是簡單地確保列表活動總是在視圖之外「完成」,以便每次看到它時都是新實例並因此重置光標。

一個很好的方法來檢查上面是正確的,是完全關閉了該應用程序,看看您的編輯或條目拿出上的應用程序重新啓動。


編輯:以及您的問題irking我的好奇心了一下,最終我沉着應戰,只是跑了完整的代碼我自己和測試此解決方案自己。不能相信我們都錯過了,但問題不在於那些東西沒有添加到你的列表視圖中,而是你的列表視圖根本沒有顯示出來。問題是你的listview從來沒有連接到遊標適配器。這裏就是你需要:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.ass); 
     helper = new AssHelper(this);   
     loadListview();  
    } 

    private void loadListview() { 
     Cursor c = helper.getAll("urge"); 
     mAdapter = new AssAdapter(c); 
     setListAdapter(mAdapter); 
    } 

我做的僅僅3行代碼一個單獨的方法,仍然會造成你的ListView其實並不需要在回到活動被刷新。你可能不想做這種方式,但因爲我懶,我選擇做下列方式:

@Override 
protected void onResume() { 
    super.onResume(); 
    loadListview(); 
} 

我的這個個人問題是,光標的第一個實例從來沒有得到機會被關閉,這是一個不合宜的imo。順便說一句,這與這個問題無關,但是你的代碼會使用不贊成使用的方法(例如不贊成使用的遊標構造函數,startManagingCursor ...),你可能會也可能不想考慮修改這些部分。還記得當你完成後關閉你的遊標和數據庫。

+0

當我完全關閉程序時,分配不會出現在列表中。這是否意味着需要不同的解決方案?對於慢速回復,我一直在使用我學校的網絡,因爲我的地區電力損失。 – Mike

+0

我修改了我的帖子,我爲這個錯誤道歉。 – mango

+0

非常感謝您的幫助。我很感激你通過我的業餘代碼。 – Mike

1

作爲一種替代方法,您可以將數據庫包裝到ContentProvider中,然後使用CursorLoader來管理光標。 CursorLoader在後臺線程(yay!)上運行,並在底層數據更改時自動重新加載Cursor。

ContentProvider提供了一些開銷,但它隱藏了很多凌亂的數據庫內容,否則您必須自行處理。雖然文檔說明您不需要使使用內容提供程序來使用數據庫,但內容提供程序有時會更好。這通常更好,因爲它可以節省您的時間。我懷疑大多數應用程序的性能大體上不受使用內容提供商的影響。

+0

如何以及在哪裏實施ContentProvider?我沒有任何經驗。 – Mike

相關問題