2010-10-28 43 views
3

我正在處理我的第一個Android應用程序,但無法弄清楚如何讓我的SimpleCursorAdpater填充視圖。我傳入的遊標導致它,所以問題必須在實例化適配器或將其綁定到視圖中。由於沒有拋出異常,我無法將 轉換爲setListAdapter。調試SimpleCursorAdapter

這是我如何得到我的光標在首位:

Searches searches = new Searches(this); 

    SQLiteDatabase db = searches.getReadableDatabase(); 
    //select _id, Name, Search FROM Searches; 
    Cursor c = db.query(
       SearchConstants.TABLE_NAME, 
       FROM, null, null, null, 
       null, null); 
    startManagingCursor(c); 

這是架構做我的DB:

CREATE TABLE Searches (_id INTEGER PRIMARY KEY, Name Text, Search TEXT) 

下面是兩行事情開始土崩瓦解:

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.search, cursor, FROM, TO); 
setListAdapter(adapter); 

我主要佈局是這樣的:

<ListView 
    android:id="@android:id/android:list" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" /> 
<TextView 
    android:id="@android:id/android:empty" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/empty" /> 

這裏是填補與每個結果的看法:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:padding="10sp"> 
    <TextView 
    android:id="@+id/_id" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/> 
    <TextView 
    android:id="@+id/name" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/> 
    <TextView 
    android:id="@+id/colon" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text=": " 
    android:layout_toRightOf="@id/name" /> 
    <TextView 
    android:id="@+id/search" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:ellipsize="end" 
    android:singleLine="true" 
    android:textStyle="italic" 
    android:layout_toRightOf="@id/colon" /> 
</RelativeLayout> 

最後這裏是我使用的靜態變量:

//search query stuff 
private static String[] FROM = {SearchConstants._ID, SearchConstants.NAME_COLUMN, SearchConstants.SEARCH_COLUMN}; 

//where to paste search results 
private static int[] TO = {R.id._id, R.id.name, R.id.search}; 

/** 
* Table name 
*/ 
public static final String TABLE_NAME = "Searches"; 

/** 
* Name Column 
*/ 
public static final String NAME_COLUMN = "Name"; 

/** 
* Search Column 
*/ 
public static final String SEARCH_COLUMN = "Search"; 

我想這是所有相關的代碼。我不知道如何在這一點上進行,所以任何建議都會有所幫助。

感謝, 布賴恩

PS:貌似那裏有很多很好的建議,在這裏 - 我不會無視他們,我只是還沒有過機會呢。感謝您的建議!在某些時候,我會穿過他們所有的人,試着給出一些反饋,告訴我哪些事情對我有好處。

+1

你的模式是什麼樣的,你實際上有一個_ID列嗎?顯示您的模式以及用於填充遊標的實際數據庫查詢。 – schwiz 2010-10-28 02:26:36

+0

我添加了模式和查詢。我傾向於認爲那不是問題,因爲在我創建適配器之前(這裏未顯示),我手動迭代結果,並確定有足夠的東西在那裏。我讀過你必須在你的FROM子句中包含_id,儘管我已經添加了它,這似乎有幫助(沒有例外),但仍然沒有結果。讓我知道,如果有其他事情會有所幫助!謝謝! – 2010-10-28 13:56:48

+1

您確定您提供給SimpleCursorAdapter()的Cursor實例是否與至少有一行相同?您的發佈代碼中有兩個遊標變量,「遊標」和「c」。 – 2010-10-31 17:27:39

回答

3

如果您有源代碼,您可以進入代碼。幸運的是,Android是開源的。爲了容易粘附在Eclipse的源代碼,請參閱:

http://android.opensourceror.org/2010/01/18/android-source/

至於問題本身,你在上面的評論說,在創建適配器之前迭代的所有項目。如果您在迭代後未創建新的遊標,則可能需要將其倒回,否則適配器可能會認爲它是空的。

cursor.moveToFirst() 
+0

真的很好。我會稍後再測試。謝謝! – 2010-11-01 13:34:18

+0

嗯,我給了它一槍,但這沒有辦法。這是值得一試,但感謝您的幫助! – 2010-11-02 01:21:19

+0

那你可以附上完整的源代碼嗎?或者至少是活動?另外,你有沒有嘗試過將源代碼附加到Eclipse並進入setListAdapter()? – kichik 2010-11-02 07:51:54

2

請不要擔心任何內部綁定方面的問題。我確信有一個簡單的出路。請嘗試以下操作: 第一,只是爲了確保你的光標它需要的地方確實得到了數據,放線

System.out.println("cursor.getCount()="+cursor.getCount()); 

setAdapter的呼叫前右()。但是,當然,你已經測試過,以獲得一個行數;-)所以下面可能會更有趣。

要檢查你的綁定失敗,請與測試:代替

android:id="@+id/android:list" 

:在您的main.xml中

android:id="@android:id/android:list" 

。同樣的事情:android:id =「@ + id/android:empty」。

如果你還沒有得到結果,你也可以嘗試使用顯示列表默認XML佈局(如simple_list_item_1管理),這將是這樣的:

ListAdapter adapter = new SimpleCursorAdapter(this, 
    // Use a template that displays a text view 
    android.R.layout.simple_list_item_1, 
    // Give the cursor to the list adapter 
    cursor, 
    // Map the NAME column in your database to... 
    new String[] {SearchConstants.NAME_COLUMN} , 
    // ...the "text1" view defined in the R.layout.simple_list_item_1 
    new int[] {android.R.id.text1} 
); 

只要複製粘貼到你的活動,看看會發生什麼。 希望你完成了!

+0

酷我下班回家時會刺傷。感謝您的輸入! – 2010-11-02 13:53:24

+0

仍然沒有運氣,不幸的是... – 2010-11-03 01:30:30

0

好吧,我注意到您使用的列名以大寫字母。確保在數據庫方案中使用確切的標識符(sqlite列名稱區分大小寫)。但是在你提供的列標識符匹配的代碼中。

所以,如果你真的使用光標已經拿到了數據,嘗試先創建SimpleCursorAdapter上面的代碼(而不是一些自定義佈局),它應該工作。下面是活動代碼的另一個小例子(因爲我不知道你的):

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.dbManager = new DatabaseManager(this); 

    setContentView(R.layout.main); 
    registerForContextMenu(getListView()); // catch clicks 

    if (!showList()) { 
     TextView tv = new TextView(this); 
     tv.setText(getString(R.string.txt_list_empty)); 
     setContentView(tv); 
    } 
} 

private boolean showList() { 
    final Cursor c = dbManager.fetchListData(); 
    startManagingCursor(c); // when the Activity finishes, the cursor is closed 

    if (!c.moveToFirst()) 
     return false; 

    final SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(
      this, android.R.layout.simple_list_item_2, c, 
      new String[]{"name"} , new int[]{android.R.id.text1}); 

    setListAdapter(myAdapter); 
    return true; 
} 

之前花了很多的,你遇到問題的時候,而啓動那裏的東西都還在工作,採取小步驟進行功能擴展。如果讓它們保持簡單,那麼在使用適配器方面沒有太大的魔力。

0

你可以嘗試將用於調試的ViewBinder。您可以使用它來檢查SimpleCursorAdaptor中哪些視圖正在傳遞哪些值。或者只是用它來自己手動進行綁定。

像這樣的東西應該工作:

adapter.setViewBinder(new SimpleCursorBinder()); 

然後

public class SimpleCursorBinder implements SimpleCursorAdpater.ViewBinder { 
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) { 
     /* set breakpoints and examine incoming data. */ 
     // returning false, causes SimpleCursorAdapter to handing the binding 
     boolean bound = false; 

     String columnName = cursor.getColumnName(columnIndex); 
     TextView bindingView = null; 
     int viewId = view.getId(); 

     // could just use this opportunity to manually bind 
     if (columnName.equals(SearchConstants._ID)) { 
      bindingView = (TextView)(viewId == R.id._id ? view : null); 
     } else if (columnName.equals(SearchConstants.NAME_COLUMN)) { 
      bindingView = (TextView)(viewId == R.id.name ? view : null); 
     } else if (columnName.equals(SearchConstants.SEARCH_COLUMN)) { 
      bindingView = (TextView)(viewId == R.id.search ? view : null); 
     } 

     if (bindingView != null) { 
      bindingView.setText(cursor.getString(columnIndex)); 
      bound = true; 
     } 

     return bound; 
    } 
} 
0

它看起來並不像你做錯了什麼,你還沒有,但這樣它顯示的所有代碼可能很難發現任何錯誤。

不知道是否行startManagingCursor(C)爲您完成此,但在我的例子,我有以下行我的查詢完成後。鑑於你的例子看起來非常好,它可能是你的光標需要重置爲第一項。

(啊,只注意到kichik指出了這一點,但我會離開我的例子。)

if (c != null) { 
     c.moveToFirst(); 
    } 

我的查詢往往是這樣的:

public Cursor getQueryCursor() 
    { 
    Cursor c; 
    c = null; 
    try{ 
     c = myDataBase.query(TABLE_MYTABLE, new String[] { 
      COLUMN_ID,COLUMN_LABEL, COLUMN_TEXT}, 
       null, 
       null, 
       null, 
       null, 
       null); 

     if (c != null) { 
      c.moveToFirst(); 
     } 

    }catch(Exception ec) 
    { 
     Log.w("MY_APP", ec.getMessage()); 

    } 
    return c; 
    } 

然後將你的我的查詢結果時,還經常在它周圍放置try/catch語句,並在這些點上添加斷點(有時getMessage()返回null,但異常的其他屬性會突出顯示這個問題。用以下方法解決我的問題的根源。

try{ 
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.search, cursor, FROM, TO); 
    setListAdapter(adapter); 
}catch(IllegalStateException e) 
{ 
    Log.w("MyApp", e.getMessage()); 
}catch(Exception es) 
{ 
    Log.w("MyApp", es.getMessage()); 
} 
0

請檢查您的SQLite數據庫,它必須有一個列「_id」作爲主鍵。 我有同樣的問題,並最終找出這個...

1

剛剛得到同樣的問題,並發現如何讓Simplecursoradapter創建不會失敗。

在你的遊標中,即使你不需要它,數據庫的查詢也必須包含表主鍵!如果沒有它會失敗和崩潰...

希望它會幫助其他人有同樣的問題!