2

我仍然圍繞着ContentProviders,Loaders和SimpleCursorAdapters(我發現使用舊的startManagingCursor方法更容易)。實質上,我有一個ListView活動,當點擊一個列表項時,會打開一個新的活動,其中所有字段都填充了來自數據庫的數據。用戶可以刪除記錄,或更改字段並保存更改。我會提前道歉這篇文章的長度,但我不確定什麼可能/可能不相關。從ArrayList <>更改爲SimpleCursorAdapter後使用onItemClickListener

我會爲您提供舊代碼(這是正常工作)第一名:

public class FuncLogbook extends DashMenuActivity implements OnItemClickListener { 

private ListView list_LogbookResults; 
private ListAdapter list_LogbookAdap; 
private ArrayList<DBDetails> LogbookArrayList; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView (R.layout.dash_logbook); 

    list_LogbookResults = (ListView) findViewById(R.id.list_logbook); 
    list_LogbookResults.setOnItemClickListener(this); 

    LogbookArrayList = new ArrayList<DBDetails>(); 
    list_LogbookAdap = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList()); 
    list_LogbookResults.setAdapter(list_LogbookAdap); 
} 

@SuppressWarnings("deprecation") 
public List<String> populateList() { 
    List<String> BGLResultsList = new ArrayList<String>(); 

    DBProvider mDBLogbook = new DBProvider(); 
    AddDBHelper logbook = new AddDBHelper(this); 
    logbook.open(); 
    Cursor cur = logbook.getEntries(); 
    Cursor cur = mDBLogbook.query(DBProvider.CONTENT_URI, null, null, null, null); 
    startManagingCursor(cur); 

    while (cur.moveToNext()) { 
     String RowID = cur.getString(0); 
     String Time = cur.getString(1); 
     String Date = cur.getString(2); 
     String BGL = cur.getString(5); 

     DBDetails detailsClass = new DBDetails(); 
     detailsClass.setuRow(RowID); 
     detailsClass.setuTime(Time); 
     detailsClass.setuDate(Date); 
     detailsClass.setuBGL(BGL);   

     LogbookArrayList.add(detailsClass); 
     BGLResultsList.add("BGL: " + BGL + "\nRow ID: " + RowID 
       +"\nDate: " + Date +"\nTime: " + Time); 
    } 
    return BGLResultsList; 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    LogbookArrayList = new ArrayList<DBDetails>(); 
    list_LogbookAdap = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList()); 
    list_LogbookResults.setAdapter(list_LogbookAdap); 
} 

@Override 
protected void onStart() { 
    super.onStart(); 
    LogbookArrayList = new ArrayList<DBDetails>(); 
    list_LogbookAdap = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList()); 
    list_LogbookResults.setAdapter(list_LogbookAdap); 
} 

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {  
    Intent UpdateDBDetails = new Intent(this, UpdateDBDetails.class); 

    DBDetails clickedObject = LogbookArrayList.get(arg2); 
    Bundle dataBundle = new Bundle(); 
    dataBundle.putString("clickeduRowId", clickedObject.getuRow()); 
    dataBundle.putString("clickeduTime", clickedObject.getuTime()); 
    dataBundle.putString("clickeduDate", clickedObject.getuDate()); 
    dataBundle.putString("clickeduBGL", clickedObject.getuBGL()); 

    UpdateDBDetails.putExtras(dataBundle); 
    startActivity(UpdateDBDetails); 
} 

NEW CODE:

public class FuncLogbook extends ListActivity implements 
LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener { 

private SimpleCursorAdapter adapter; 
private ArrayList<DBDetails> LogbookArrayList; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView (R.layout.dash_logbook);  
    this.getListView().setDividerHeight(2); 
    fillData(); 

    ListView list = getListView(); 
    list.setOnItemClickListener(this); } 

protected void onActivityResult(int requestCode, int resultCode, Intent intent) { 
    super.onActivityResult(requestCode, resultCode, intent); 
} 

private void fillData() { 
    String[] from = new String[] { AddDBHelper.KEY_BGL, AddDBHelper.KEY_ROWID, 
      AddDBHelper.KEY_CATEG, AddDBHelper.KEY_TIME }; 
    int[] to = new int[] {R.id.logBGL, R.id.logRowID, R.id.logCateg, R.id.logTime }; 

    getLoaderManager().initLoader(0, null, this); 
    adapter = new SimpleCursorAdapter(this, R.layout.logbook_item, null, from, to, 0); 

    setListAdapter(adapter);   
} 

public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    String[] projection = { AddDBHelper.KEY_ROWID, AddDBHelper.KEY_BGL, 
      AddDBHelper.KEY_CATEG, AddDBHelper.KEY_TIME }; 
    CursorLoader cl = new CursorLoader(this, DBProvider.CONTENT_URI, 
      projection, null, null, null); 
    return cl; 
} 

public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    adapter.swapCursor(data); 
} 

public void onLoaderReset(Loader<Cursor> loader) { 
    adapter.swapCursor(null); 
} 

public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {  
    Intent UpdateDBDetails = new Intent(this, UpdateDBDetails.class); 

    /*DBDetails clickedObject = LogbookArrayList.get(pos); 
    Bundle dataBundle = new Bundle(); 
    dataBundle.putString("clickeduRowId", clickedObject.getuRow()); 
    dataBundle.putString("clickeduTime", clickedObject.getuTime()); 
    dataBundle.putString("clickeduDate", clickedObject.getuDate()); 
    dataBundle.putString("clickeduBGL", clickedObject.getuBGL()); 

    UpdateDBDetails.putExtras(dataBundle);*/ 
    startActivity(UpdateDBDetails); 
} 

當運行它,我得到一個NullPointerException在線讀取DBDetails clickedObject = LogbookArrayList.get(pos); 我知道有ArrayList是錯誤的,但唯一的教程我可以找到或者顯示如何使用ArrayList與onItemClick,或者顯示如何在Toast消息中使用選定的ID,但我似乎無法將信息放入Bundle中傳遞給Activity。 任何幫助表示讚賞。

UPDATE

基於Luksprog的回答,我已經修改爲

public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {  
    Intent UpdateDBDetails = new Intent(this, UpdateDBDetails.class); 

    Cursor c = (Cursor) adapter.getItem(pos); 
    Toast.makeText(getApplicationContext(), "Clicked Record Number " + id + " at " + pos, 
      Toast.LENGTH_SHORT).show(); 

    Bundle dataBundle = new Bundle(); 
    dataBundle.putString("clickeduRowId", c.getString(c.getColumnIndex(AddDBHelper.KEY_ROWID))); 
    dataBundle.putString("clickeduTime", c.getString(c.getColumnIndex(AddDBHelper.KEY_TIME))); 
    dataBundle.putString("clickeduDate", c.getString(c.getColumnIndex(AddDBHelper.KEY_DATE))); 
    dataBundle.putString("clickeduBGL", c.getString(c.getColumnIndex(AddDBHelper.KEY_BGL))); 

    UpdateDBDetails.putExtras(dataBundle); 
    startActivity(UpdateDBDetails); 
} 

它拋出一個錯誤,如果我沒有一個投加光標,因此Cursor c = (Cursor) adapter.getItem(pos);

這仍然不起作用。 logcat的節目:

10-21 23:24:02.167: E/CursorWindow(2663): Failed to read row 2, column -1 from a CursorWindow which has 8 rows, 4 columns. 
10-21 23:24:02.178: E/AndroidRuntime(2663): FATAL EXCEPTION: main 
10-21 23:24:02.178: E/AndroidRuntime(2663): java.lang.IllegalStateException: Couldn't read row 2, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.database.CursorWindow.nativeGetString(Native Method) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.database.CursorWindow.getString(CursorWindow.java:434) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.database.CursorWrapper.getString(CursorWrapper.java:114) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at com.rone.glucometer.FuncLogbook.onItemClick(FuncLogbook.java:227) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.widget.AdapterView.performItemClick(AdapterView.java:298) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.widget.AbsListView.performItemClick(AbsListView.java:1086) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.widget.AbsListView$PerformClick.run(AbsListView.java:2855) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.widget.AbsListView$1.run(AbsListView.java:3529) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.os.Handler.handleCallback(Handler.java:615) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.os.Handler.dispatchMessage(Handler.java:92) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.os.Looper.loop(Looper.java:137) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at android.app.ActivityThread.main(ActivityThread.java:4745) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at java.lang.reflect.Method.invokeNative(Native Method) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at java.lang.reflect.Method.invoke(Method.java:511) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
10-21 23:24:02.178: E/AndroidRuntime(2663):  at dalvik.system.NativeStart.main(Native Method) 

UPDATE 我意識到上述logcat的錯誤是由於我沒有列出onCreateLoader內的所有列;爲簡單起見,本例中我只列出了4個,但爲了減小尺寸,我已經接近15列。謝謝,你的代碼工作完美Luksprog

+1

您試圖獲取不在Cursor /數據庫中退出的列。使用'Log.e'語句來查看哪個'c.getColumnIndex()'返回-1(意味着沒有找到列)。 – Luksprog

回答

1

你的第二次嘗試不起作用,因爲你使用相同的ArrayList現在還沒有初始化,因爲你使用基於Cursor的適配器。相反,你應該從它那裏得到從適配器(使用getItem(position)方法,你會得到在正確的行Cursor位置)Cursor和獲取數據:

public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {  
    Intent UpdateDBDetails = new Intent(this, UpdateDBDetails.class); 
    Cursor c = adapter.getItem(position); 
    Bundle dataBundle = new Bundle(); 
    dataBundle.putString("clickeduRowId", c.getString(c.getColumnIndex(the_index_for_this_column_data))); // One of the fields from AddDBHelper.KEY_BGL, AddDBHelper.KEY_ROWID, AddDBHelper.KEY_CATEG, AddDBHelper.KEY_TIME 
    // the same for the other fields. 

    UpdateDBDetails.putExtras(dataBundle); 
    startActivity(UpdateDBDetails); 
} 

同時,爲了安全起見呼叫LoaderManager實例化適配器後。

相關問題