0

我想填充一個sqlite數據庫的列表視圖,到目前爲止,我想我已經正確地創建/添加項目到數據庫。我不知道如何獲取這些項目並將它們放入我的列表視圖中。使用sqlite db填充listview

這裏是我的數據庫創建(RecordsDatabase.java):

public class RecordsDatabase extends SQLiteOpenHelper { 

public static final int DATABASE_VERSION = 1; 

public RecordsDatabase(Context context) { 
    super(context, RecordContract.RecordInfo.DATABASE_NAME, null, DATABASE_VERSION); 
    Log.d("Database operations", "Database created"); 
} 

@Override 
public void onCreate(SQLiteDatabase db) { 
    db.execSQL("CREATE TABLE " + RecordContract.RecordInfo.TABLE_NAME + " (" 
        + RecordContract.RecordInfo.RECORDS_DATE + " TEXT NOT NULL," 
      + RecordContract.RecordInfo.RECORDS_SQUAT + " TEXT NOT NULL," 
      + RecordContract.RecordInfo.RECORDS_BENCH + " TEXT NOT NULL," 
      + RecordContract.RecordInfo.RECORDS_DEAD + " TEXT NOT NULL," 
      + RecordContract.RecordInfo.RECORDS_TOTAL + " TEXT NOT NULL)" 

    ); 
    Log.d("Database operations", "Table created"); 

} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

} 

public void putInformation(RecordsDatabase rdb, String date, String squat, String bench, String dead, String total) { 
    SQLiteDatabase SQ = rdb.getWritableDatabase(); 
    ContentValues contentValues = new ContentValues(); 
    contentValues.put(RecordContract.RecordInfo.RECORDS_DATE, date); 
    contentValues.put(RecordContract.RecordInfo.RECORDS_SQUAT, squat); 
    contentValues.put(RecordContract.RecordInfo.RECORDS_BENCH, bench); 
    contentValues.put(RecordContract.RecordInfo.RECORDS_DEAD, dead); 
    contentValues.put(RecordContract.RecordInfo.RECORDS_TOTAL, total); 
    long k = SQ.insert(RecordContract.RecordInfo.TABLE_NAME, null, contentValues); 
    Log.d("Database operations", "Record added(1 row)"); 

} 

public Cursor getRecords(RecordsDatabase rdb) { 
    SQLiteDatabase SQ = rdb.getReadableDatabase(); 
    String[] columns = {RecordContract.RecordInfo.RECORDS_DATE, RecordContract.RecordInfo.RECORDS_SQUAT, RecordContract.RecordInfo.RECORDS_BENCH 
    , RecordContract.RecordInfo.RECORDS_DEAD, RecordContract.RecordInfo.RECORDS_TOTAL}; 
    Cursor CR = SQ.query(RecordContract.RecordInfo.TABLE_NAME, columns,null, null, null, null, null); 
    return CR; 

} 

這是我上按一下按鈕(MyMaxes.java)添加按鈕:

mButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); 
      SharedPreferences.Editor editor = pref.edit(); 
       if (mEditTextBench.getText().length() > 0 && mEditTextDead.getText().length() > 0 && mEditTextSquat.getText().length() > 0) { 
       maxBenchDB = mEditTextBench.getText().toString(); 
       maxSquatDB = mEditTextSquat.getText().toString(); 
       maxDeadDB = mEditTextDead.getText().toString(); 
       maxTotalDB = mTxtTotal.getText().toString(); 

       DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); 
       Date today = Calendar.getInstance().getTime(); 
       reportDate = df.format(today); 

       RecordsDatabase DB = new RecordsDatabase(mContext); 
       DB.putInformation(DB, reportDate, maxSquatDB, maxDeadDB, maxBenchDB, maxTotalDB); 
       Toast.makeText(getBaseContext(), "added", Toast.LENGTH_LONG).show(); 

這裏是我有我listview,我想填充使用SQLite數據庫和我的custom.xml(MyProgress.java):

public class MyProgress extends BaseActivity { 
@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.my_progress); 
    mToolBar = activateToolbar(); 
    setUpNavigationDrawer(); 
    getSupportActionBar().setTitle("My Progress"); 

    ListView listViewRec = (ListView) findViewById(R.id.listViewRecord); 

d我的繼承人custom_record.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:orientation="vertical" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Date" 
    android:textSize="18sp" 
    android:id="@+id/txtDate" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true"/> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Bench" 
    android:id="@+id/txtBench" 
    android:paddingRight="5dp" 
    android:textSize="18sp" 
    android:layout_gravity="center_horizontal" 
    android:layout_alignParentTop="true" 
    android:paddingLeft="5dp" 
    android:layout_toLeftOf="@+id/txtSquat" 
    android:layout_toStartOf="@+id/txtSquat"/> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Squat" 
    android:textSize="18sp" 
    android:paddingRight="5dp" 
    android:id="@+id/txtSquat" 
    android:layout_alignParentTop="true" 
    android:paddingLeft="5dp" 
    android:layout_toLeftOf="@+id/txtDead" 
    android:layout_toStartOf="@+id/txtDead" 
    /> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Dead" 
    android:paddingRight="5dp" 
    android:textSize="18sp" 
    android:id="@+id/txtDead" 
    android:layout_alignParentTop="true" 
    android:paddingLeft="5dp" 
    android:layout_toLeftOf="@+id/txtTotal" 
    android:layout_toStartOf="@+id/txtTotal"/> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Total" 
    android:textSize="18sp" 
    android:paddingRight="5dp" 
    android:paddingLeft="5dp" 
    android:id="@+id/txtTotal" 
    android:layout_marginRight="34dp" 
    android:layout_marginEnd="34dp" 

    android:layout_alignParentRight="true" 
    android:layout_alignParentEnd="true"/> 

這裏是到目前爲止我的CursorAdapter:

public class TodoCursorAdapter extends CursorAdapter { 

    public TodoCursorAdapter(Context context, Cursor c, int flags) { 
      super(context, c, flags); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
      return LayoutInflater.from(context).inflate(R.layout.custom_record, parent, false); 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
      TextView txtDate = (TextView) view.findViewById(R.id.txtDate); 
      TextView txtSquat = (TextView) view.findViewById(R.id.txtSquat); 
      TextView txtBench = (TextView) view.findViewById(R.id.txtBench); 
      TextView txtDead = (TextView) view.findViewById(R.id.txtDead); 
      TextView txtTotal = (TextView) view.findViewById(R.id.txtTotal); 

      String date = cursor.getString(cursor.getColumnIndexOrThrow("date")); 
      String squat = cursor.getString(cursor.getColumnIndexOrThrow("squat")); 
      String bench = cursor.getString(cursor.getColumnIndexOrThrow("bench")); 
      String dead = cursor.getString(cursor.getColumnIndexOrThrow("dead")); 
      String total = cursor.getString(cursor.getColumnIndexOrThrow("total")); 

      txtBench.setText(bench); 
      txtDate.setText(date); 
      txtDead.setText(dead); 
      txtSquat.setText(squat); 
      txtTotal.setText(total); 
    } 
} 

我不知道我怎麼會去獲取列表視圖使用填充SQLite數據庫..我想我正在添加項目到數據庫正確的方式,雖然。謝謝你的幫助!

+0

您的適配器看起來正確。你只需要創建一個'TodoCursorAdapter'實例並將它發送到'ListView'上的'setAdapter()'。你也可以考慮使用'SimpleCursorAdapter',因爲它完成了你在'TodoCursorAdapter'中所做的一切。 –

+0

你可以舉個例子,當我嘗試在MyProgress.java中創建TodoCursorAdapter的實例時,我不知道應該爲期望的參數「光標」和「標誌」放置什麼 – LBJ33

回答

1

首先,我建議改變了TodoCursorAdapter構造:

public TodoCursorAdapter(Context context, Cursor c) { 
    super(context, c, 0); 
} 

我對標誌參數迷惑自己。尤其是因爲Cursor不帶標誌的構造函數現在已被廢棄一段時間了。從我所知道的情況來看,這裏0的值可以正常工作。

接下來,您需要從putInformation()getRecords()中刪除RecordsDatabase rdb參數。這個參數是完全不必要的,因爲Java已經自動發送它作爲關鍵字this。但是,您實際上並不需要在任何地方使用this。您只需直接調用您希望使用的任何方法即可。因此,而不是

rdb.getWritableDatabase(); 

只是做

getWritableDatabase(); 

或者,你可以做

this.getWritableDatabase(); 

this如果你把它關掉自動假定。

現在您需要Cursor才能傳遞給TodoCursorAdapter構造函數。你這樣做使用RecordsDatabase延伸SQLiteOpenHelper

public class MyProgress { 
    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     // ...snip 
     RecordsDatabase helper = new RecordsDatabase(this); 
     Cursor c = db.getRecords(); 
     ListView listViewRec = (ListView) findViewById(R.id.listViewRecord); 
     Adapter adapter = new TodoRecordsAdapter(this, c); 
     listViewRec.setAdapter(adapter); 
    } 
} 

此外,你可能會考慮從TodoCursorAdapter構造函數中刪除了Cursor參數。其他選項

  1. TodoCursorAdapter構造
  2. 直接創建Cursor創建MyProgressCursor和適配器上調用changeCursor()
+0

謝謝,我得到這個運行沒有錯誤,但當我點擊「MyProgress」頁面,它崩潰,我得到:java.lang.IllegalArgumentException:列'_id'不存在..不知道它試圖在哪裏檢查是否lol – LBJ33

+0

它將我發送到ToDoCursorAdapter類和MyProgress類,在我的進度中的這一行:TodoCursorAdapter adapter = new TodoCursorAdapter(this,c); – LBJ33

+0

@ LBJ33一些Android API方法期望任何SQLite表都有一個名爲'_id'的列。最簡單的解決方案是將其添加到您的表格中。或者,您可以確定哪些方法需要這些方法並避免使用它們。這似乎需要太多的工作IMO ......這意味着編寫更多的代碼,因爲你將無法依靠API來爲你完成工作。 –

1

您需要創建適配器的對象並將其設置爲ListView的適配器。

在此行之後的活動中。

ListView listViewRec = (ListView) findViewById(R.id.listViewRecord); 

把這段代碼。

首先獲得所有記錄從RecordsDatabase類

Cursor recordsCursor = recordsDatabase.getRecords(); 

然後讓TodoCursorAdapter的對象。

TodoCursorAdapter adapter = new TodoCursorAdapter(getContext(), recordsCursor, 
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); 

根據developer.android.com 關於FLAG_REGISTER_CONTENT_OBSERVER

如果設置適配器將註冊光標內容觀察者並調用onContentChanged()時通知的用武之地。使用本時要小心標誌:您需要從適配器中取消當前光標的設置,以避免由於註冊的觀察者而導致泄漏。使用帶有CursorLoader的CursorAdapter時,不需要此標誌。

然後將此適配器設置爲ListView的適配器。

listViewRec.setAdapter(adapter); 
+0

保留'RecordsAdapter擴展CursorAdapter'而不是將其更改爲'RecordsAdapter extends ArrayAdapter'。這樣,當底層數據庫發生變化時,適配器將自動更新'ListView',而不是需要代碼來查詢數據庫並手動更新'ListView'。而且,Cursor並不像ListView那樣保留內存中的所有記錄。 –

+0

只是在投票時提交更新的答案。請現在看看並調整投票如果答案現在好 –

+0

這更好......假設'getRecords()'被改變爲不帶參數(因爲它應該)。在另一種類型(因爲你把它帶到這裏)......我對「FLAG_REGISTER_CONTENT_OBSERVER」感到困惑。你知道什麼是「內容觀察者」嗎? 'onContentChanged()'的文檔提示它與過時的託管查詢的重新查詢機制有關。如果是這樣,則不應使用此標誌。我認爲這意味着我們應該使用'0'的標誌值,但是我還沒有確認這是否正確。 –