2011-07-23 60 views
0

我試圖從Android開發人員指南實施記事本教程的修改,但我的應用程序在啓動時意外停止。這裏是我的代碼:Android記事本教程修改 - 應用程序在啓動時意外停止 - 佈局/視圖問題?

我呼籲啓動主要方法...

public class MyList extends ListActivity 
{ 
    private MyListDBAdapter listDBHelper; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate (Bundle savedInstanceState) 
    { 
    super.onCreate (savedInstanceState); 
    setContentView (R.layout.home_layout); 

    listDBHelper = new MyListDBAdapter (this); 
    listDBHelper.open(); 
    fillData(); 

    Button btnAddItem = (Button) findViewById (R.id.add_item_button); 
    btnAddItem.setOnClickListener (new OnClickListener() 
    { 
     @Override 
     public void onClick (View v) 
     { 
     Intent goToAddItem = new Intent (MyList.this,AddItem.class); 
     startActivity(goToAddItem); 
     } 
    }); 
    } 

    private void fillData() 
    { 
    // Get all of the items from the database and create the item list 
    Cursor allItems = listDBHelper.fetchAllItems(); 
    startManagingCursor (allItems); 

    String [] from = new String [] {MyListDBAdapter.FIELD_ATTR1, 
            MyListDBAdapter.FIELD_ATTR2, 
            MyListDBAdapter.FIELD_ATTR3}; 
    int [] to = new int [] {R.id.list_attr1, R.id.list_attr2, 
        R.id.list_attr3}; 

    // Now create an array adapter and set it to display using the item_record_view layout 
    SimpleCursorAdapter items = new SimpleCursorAdapter(this,R.layout.item_record_view, 
                 allItems, from, to); 
    setListAdapter(items); 
    } 
} 

它的佈局XML文件...

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
android:id = "@+id/home_layout" 
android:layout_width = "wrap_content" 
android:layout_height = "wrap_content" 
xmlns:android = "http://schemas.android.com/apk/res/android"> 
<Button android:id = "@+id/add_item_button" 
     android:layout_width = "fill_parent" 
     android:layout_height = "wrap_content" 
     android:text = "@string/add_item"/> 
<ListView android:id = "@android:id/list" 
      android:layout_width = "wrap_content" 
      android:layout_height = "wrap_content"/> 
<TextView android:id = "@android:id/empty" 
      android:layout_width = "wrap_content" 
      android:layout_height = "wrap_content" 
      android:text = "@string/no_items"/> 
</LinearLayout> 

...和我試圖使用ListView顯示我的項目...

<?xml version="1.0" encoding="utf-8"?> 
<ListView 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<TextView android:id = "@+id/list_attr1" 
      android:layout_width = "wrap_content" 
      android:layout_height = "wrap_content" 
      android:layout_alignParentLeft = "true" 
      xmlns:android="http://schemas.android.com/apk/res/android"/> 
<TextView android:id = "@+id/list_attr2" 
      android:layout_width = "wrap_content" 
      android:layout_height = "wrap_content" 
      android:paddingLeft = "60dip" 
      xmlns:android="http://schemas.android.com/apk/res/android"/> 
<TextView android:id = "@+id/list_attr3" 
      android:layout_width = "wrap_content" 
      android:layout_height = "wrap_content" 
      android:paddingLeft = "160dip" 
      android:gravity = "left" 
      xmlns:android="http://schemas.android.com/apk/res/android"/> 
</ListView> 

爲MyListDBAdapter代碼...

public class MyListDBAdapter 
{ 
    private static final String TABLE_ITEMS = "MyList"; 
    public static final String FIELD_RECORD_ID = "_ID"; 
    public static final String FIELD_TYPE = "Type"; 
    public static final String FIELD_ATTR1 = "Attr1"; 
    public static final String FIELD_ATTR2 = "Attr2"; 
    public static final String FIELD_ATTR3 = "Attr3"; 
    public static final String FIELD_MY_RATING = "MyRating"; 
    public static final String [] COLUMNS = {FIELD_RECORD_ID, FIELD_TYPE, FIELD_ATTR1, 
              FIELD_ATTR2, FIELD_ATTR3}; 

    private static final String TAG = "MyListDBHelper"; 
    private DatabaseHelper listDBHelper; 
    private SQLiteDatabase itemDB; 

    /** 
    * Database creation sql statement 
    */ 
    private static final String DATABASE_CREATE = ("CREATE TABLE IF NOT EXISTS " + 
               TABLE_ITEMS + " (" + FIELD_RECORD_ID + 
               " INTEGER PRIMARY KEY AUTOINCREMENT," 
               + FIELD_TYPE + " TEXT NOT NULL, " + 
               FIELD_ATTR1 + " INTEGER NOT NULL, " + 
               FIELD_ATTR2 + " TEXT" + " NOT NULL," 
               + FIELD_ATTR3 + " TEXT NOT NULL," + 
               FIELD_MY_RATING + " INTEGER);"); 

    private static final String DATABASE_NAME = "Items"; 
    private static final int DATABASE_VERSION = 1; 

    private final Context thisContext; 

    private static class DatabaseHelper extends SQLiteOpenHelper 
    { 
    DatabaseHelper (Context context) 
    { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate (SQLiteDatabase db) 
    { 
     db.execSQL(DATABASE_CREATE); 
    } 

    @Override 
    public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) 
    { 
     Log.w (TAG, "Upgrading database from version " + oldVersion + " to " 
      + newVersion + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS notes"); 
     onCreate(db); 
    } 
    } 

    /** 
    * Constructor - takes the context to allow the database to be 
    * opened/created 
    * 
    * @param context the Context within which to work 
    */ 
    public MyListDBAdapter (Context context) 
    { 
     this.thisContext = context; 
    } 

    /** 
    * Open the items database. If it cannot be opened, try to create a new 
    * instance of the database. If it cannot be created, throw an exception to 
    * signal the failure 
    * 
    * @return this (self reference, allowing this to be chained in an 
    *   initialization call) 
    * @throws SQLException if the database could be neither opened or created 
    */ 
    public MyListDBAdapter open() throws SQLException 
    { 
     listDBHelper = new DatabaseHelper (thisContext); 
     itemsDB = listDBHelper.getWritableDatabase(); 
     return this; 
    } 

    public void close() 
    { 
     listDBHelper.close(); 
    } 

    /** 
     * Create a new item entry using the information provided. If the item is 
     * successfully created return the new record ID for that item, otherwise return 
     * a -1 to indicate failure. 
     * 
     * @param Type the type of the item 
     * @param attr1 
     * @param attr2 
     * @param attr3 
     * @return rowId or -1 if failed 
     */ 
     public long addItem (String type, int attr1, String attr2, String attr3) 
     { 
     ContentValues initialValues = new ContentValues(); 
     initialValues.put (FIELD_TYPE, type); 
     initialValues.put (FIELD_ATTR1, attr1); 
     initialValues.put (FIELD_ATTR2, attr2); 
     initialValues.put (FIELD_ATTR3, attr3); 

     return itemsDB.insert (TABLE_ITEMS, null, initialValues); 
     } 

     public long addItem (String type, int attr1, String attr2, String attr3, 
          int myRating) 
     { 
     ContentValues initialValues = new ContentValues(); 
     initialValues.put (FIELD_TYPE, type); 
     initialValues.put (FIELD_ATTR1, attr1); 
     initialValues.put (FIELD_ATTR2, attr2); 
     initialValues.put (FIELD_ATTR3, attr3); 
     initialValues.put (FIELD_MY_RATING, myRating); 

     return itemsDB.insert (TABLE_ITEMS, null, initialValues); 
     } 

     /** 
     * Delete the item with the given record ID 
     * 
     * @param _ID ID of item to delete 
     * @return true if deleted, false otherwise 
     */ 
     public boolean deleteItem (long recordID) 
     { 
     return (itemsDB.delete (TABLE_ITEMS, FIELD_RECORD_ID + "=" + recordID, 
       null) > 0); 
     } 

     /** 
     * Return a Cursor over the list of all items in the database 
     * 
     * @return Cursor over all notes 
     */ 
     public Cursor fetchAllItems() 
     { 
      return itemsDB.query (TABLE_ITEMS, COLUMNS, null, null, null, null, null); 
     } 

     /** 
     * Return a Cursor positioned at the item that matches the given record ID 
     * 
     * @param _ID ID of item to retrieve 
     * @return Cursor positioned to matching item, if found 
     * @throws SQLException if item could not be found/retrieved 
     */ 
     public Cursor fetchItem (long recordID) throws SQLException 
     { 
      Cursor itemCursor = itemsDB.query (true, TABLE_ITEMS, COLUMNS, 
         FIELD_RECORD_ID + "=" + recordID, null, null, null, null, null); 
      if (itemCursor != null) 
      { 
      itemCursor.moveToFirst(); 
      } 

      return itemCursor; 
     } 

     /** 
      * Update the item using the details provided. The item to be updated is 
      * specified using the record ID, and it is altered to use the values passed in 
      * 
      * @param _ID ID of item to update 
      * @param type type value to set item type to 
      * @param attr1 
      * @param attr2 
      * @param attr3 
      * @return true if the item was successfully updated, false otherwise 
      */ 
      public boolean updateItem (long recordID, String type, int attr1, 
            String attr2, String attr3) 
      { 
      ContentValues editVals = new ContentValues(); 
      editVals.put (FIELD_TYPE, type); 
      editVals.put (FIELD_ATTR1, attr1); 
      editVals.put (FIELD_ATTR2, attr2); 
      editVals.put (FIELD_ATTR3, attr3); 

      return (itemsDB.update (TABLE_ITEMS, editVals, FIELD_RECORD_ID + "=" + 
        recordID, null) > 0); 
      } 
} 

我不認爲問題是與我的AddItem類或其關聯的佈局,我真的厭倦格式化這篇文章的代碼。任何人都可以幫我看看出了什麼問題嗎?

+0

如果你發佈的logcat日誌使用堆棧跟蹤,這將是更容易幫助。 – MByD

+0

我不知道有關logcat,但它絕對有用...感謝提及它! –

回答

1

你必須MyListDBAdapter重命名FIELD_RECORD_ID_id

光標必須包含一個名爲「_id」列或這個類將無法正常工作。

文檔here

+0

是的!這是問題...非常感謝你。起初有點令人沮喪,因爲我更改了代碼中的變量,但應用程序仍然從我的AVD上的舊數據文件中讀取。一旦我清除了所有的東西,它就像一個魅力! –