Причина в том, что для каждой итерации цикла вы устанавливаете значения TextViews в значения для этой итерации, поэтому вы, скорее всего, увидите только последнюю строку.
Вы можете использовать: -
public void viewAll() {
Cursor res = myDb.getAllData();
if (res.getCount() == 0) {
// show error
System.out.println("No Data Found");
return;
}
TextView textViewID = (TextView) findViewById(R.id.textViewID);
textViewID.setText("");
TextView textViewName = (TextView) findViewById(R.id.textViewName);
textViewName.setText("");
TextView textViewDescription = (TextView) findViewById(R.id.textViewDescription);
textViewDescription.setText("");
TextView textViewLocation = (TextView) findViewById(R.id.textViewLocation);
textViewLocation.setText("");
while (res.moveToNext()) {
System.out.println("Id: " + res.getString(0) + "\n");
System.out.println("Title: " + res.getString(1) + "\n");
System.out.println("Description: " + res.getString(2) + "\n");
System.out.println("Location: " + res.getString(4) + "\n\n");
textViewId.setText(textViewID.getText().toString()+res.getString(0) + "\n");
textViewName.setText(textViewName.getText().toString()+"Name: " + res.getString(1) + "\n");
textViewDescription.setText(textViewDescription.getText().toString() + "Description: " + res.getString(2) + "\n");
textViewLocation.setText(textViewLocation.getText().toString() + "Location: " + res.getString(4) + "\n");
}
}
Или даже лучше, как
- Конкатенация строк в цикле неэффективна
- Это также добавляет символ новой строки только после первого.
: -
public void viewAll() {
Cursor res = myDb.getAllData();
if (res.getCount() == 0) {
// show error
System.out.println("No Data Found");
return;
}
StringBuilder idsb = new StringBuilder();
StringBuilder namesb = new StringBuilder();
StringBuilder descsb = new StringBuilder();
StringBuilder locsb = new StringBuilder();
String endofline = "";
TextView textViewID = (TextView) findViewById(R.id.textViewID);
TextView textViewName = (TextView) findViewById(R.id.textViewName);
TextView textViewDescription = (TextView) findViewById(R.id.textViewDescription);
TextView textViewLocation = (TextView) findViewById(R.id.textViewLocation);
while (res.moveToNext()) {
System.out.println("Id: " + res.getString(0) + "\n");
System.out.println("Title: " + res.getString(1) + "\n");
System.out.println("Description: " + res.getString(2) + "\n");
System.out.println("Location: " + res.getString(4) + "\n\n");
idsb.append("Id: ").append(res.getString(0)).append(endofline);
namesb.append("Name: ").append(res.getString(1)).append(endofline);
descsb.append("Description: ").append(res.getString(2)).append(endofline);
locsb.append("Location: ").append(res.getString(4)).append(endofline);
if (endofline.length() == 0) {
endofline = "\n";
}
}
textViewId.setText(idsb.toString());
textViewName.setText(namesb.toString());
textViewDescription.setText(descsb.toString());
textViewLocation.setText(locsb.toString());
}
Однако вы, вероятно, хотите использовать ListView или RecyclerView.
Дополнительно - использовать ListView
Важное примечание
В этом примере используется CursorAdapter, который упрощает жизнь, НО им требуется наличие столбца с именем _id (идентификатор не будет). Возможно, вам придется изменить таблицу так, чтобы столбец имел имя _id (вы можете использовать константу BaseColumns._ID, как это используется в DBHelper ниже). Существуют и другие способы, такие как создание столбца _id в SELECT (запрос), например, SELECT rowid AS _id,* FROM the_table
.
1 В макете упражнения добавьте (замените textviews для id / name / description / location) ListView, убедившись, что вы даете ему идентификатор, например, : -
<ListView
android:id="@+id/my_listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
2 Создайте новый макет mylistview_item.xml , это будет иметь 4 просмотра текста, например.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textview_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textview_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textview_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textview_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
- Это будет макет, используемый для каждой строки (элемента) в списке
3 Добавьте следующие переменные класса: -
SimpleCursorAdapter mSCA; //Adapts/Handles the data for the listview
ListView mList;
Cursor mCsr;
4 Добавьте следующий массив int в качестве переменной класса: -
int[] item_layout_ids_for_list = new int[]{
R.id.textview_id,
R.id.textview_name,
R.id.textview_description,
R.id.textview_location
};
- обратите внимание, что это идентификаторы TextView в макете mylistview_item.xml и будут использоваться адаптером для сопоставления данных из столбцов с TextViews.
5 Аналогичным образом добавьте массив String для имен столбцов, из которых должны быть получены данные; НО ПОМНИТЕ, что вам / возможно придется изменить имена столбцов (в следующих случаях используются КОНСТАНТЫ, определенные в Помощнике по базам данных (рекомендуется определять такие константы и всегда использовать их, а не жестко кодировать имена)), например : -
String[] columns_to_list = new String[]{
DBHelper.COL_MYTABLE_ID,
DBHelper.COl_MYTABLE_NAME,
DBHelper.COL_MYTABLE_DESCRIPTION,
DBHelper.COl_MYTABLE_LOCATION
};
6 Добавьте следующий метод в упражнение: -
private void manageListView() {
mCsr = myDb.getAllData();
if (mSCA == null) {
// Builds the Adapter for the List
mSCA = new SimpleCursorAdapter(
this,
R.layout.mylistview_item, mCsr,
columns_to_list,
item_layout_ids_for_list,
0
);
mList.setAdapter(mSCA); // Ties the Adapter to the ListView
} else {
mSCA.swapCursor(mCsr); // Refresh the List
}
}
- Это, как говорит метод, управляет ListView. Он получает данные из базы данных в Cursor, создает (создает) SimpleCursorAdapter, если он не был создан, а затем связывает адаптер с ListView. Если был создан экземпляр адаптера, он сообщает адаптеру, что появился новый (измененный) курсор (поэтому список обновляется).
7
Добавьте следующие строки в метод onCreate действия: -
mList = this.findViewById(R.id.my_listview);
myDb = new DBHelper(this); //<<<<<<<<<< SHOULD ALREADY HAVE SOMETHING LIKE THIS LEAVE AS IT IS
manageListView();
8 Переопределите методы onResume и onDestroy своей активности, используя: -
@Override
protected void onDestroy() {
super.onDestroy();
mCsr.close();
}
@Override
protected void onResume() {
super.onResume();
manageListView();
}
- Это пока не существенно, но хорошая практика.
onDestroy
закрывает, когда действие уничтожено. Курсор (Курсоры должны быть закрыты после завершения)
- менее важно для основной деятельности
onResume
разрешено вызывать метод manageListView()
(еще не добавлен), и в результате в представлении списка отображаются самые последние данные по возвращении из другого действия.
Активность, которую я использовал для проверки: -
public class MainActivity extends AppCompatActivity {
DBHelper myDb;
SimpleCursorAdapter mSCA; //Adapts/Handles the data for the listview
ListView mList;
Cursor mCsr;
String[] columns_to_list = new String[]{
DBHelper.COL_MYTABLE_ID,
DBHelper.COl_MYTABLE_NAME,
DBHelper.COL_MYTABLE_DESCRIPTION,
DBHelper.COl_MYTABLE_LOCATION
};
int[] item_layout_ids_for_list = new int[]{
R.id.textview_id,
R.id.textview_name,
R.id.textview_description,
R.id.textview_location
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mList = this.findViewById(R.id.my_listview);
myDb = new DBHelper(this);
forTestingAddSomeData();
manageListView();
}
private void manageListView() {
mCsr = myDb.getAllData();
if (mSCA == null) {
// Builds the Adapter for the List
mSCA = new SimpleCursorAdapter(
this,
R.layout.mylistview_item, mCsr,
columns_to_list,
item_layout_ids_for_list,
0
);
mList.setAdapter(mSCA); // Ties the Adapter to the ListView
} else {
mSCA.swapCursor(mCsr); // Refresh the List
}
}
private void forTestingAddSomeData() {
if(DatabaseUtils.queryNumEntries(myDb.getWritableDatabase(),DBHelper.TABLE_MYTABLE) < 1) {
myDb.add("Test001","This is a test","Home");
myDb.add("Test002","For Testing","Garage");
myDb.add("Test003","Test using this","Loft");
myDb.add("Test004","Yet again for testing","Cupboard");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mCsr.close();
}
@Override
protected void onResume() {
super.onResume();
manageListView();
}
}
- Примечание forTestingAddSomeData и вызов метода просто для добавления некоторых данных тестирования. Добавление и использование этого метода (чтобы я мог отобразить некоторые данные) было опущено в пошаговом руководстве.
Если у вас есть проблемы или вы хотите использовать полный код, тогда класс DBHelper: -
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String TABLE_MYTABLE = "mytable";
public static final String COL_MYTABLE_ID = BaseColumns._ID;
public static final String COl_MYTABLE_NAME = "name";
public static final String COL_MYTABLE_DESCRIPTION = "description";
public static final String COl_MYTABLE_LOCATION = "location";
SQLiteDatabase mDB;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_MYTABLE +
"(" +
COL_MYTABLE_ID + " INTEGER PRIMARY KEY," +
COl_MYTABLE_NAME + " TEXT, " +
COL_MYTABLE_DESCRIPTION + " TEXT, " +
COl_MYTABLE_LOCATION + " TEXT" +
")"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long add(String name, String description, String location) {
ContentValues cv = new ContentValues();
cv.put(COl_MYTABLE_NAME,name);
cv.put(COL_MYTABLE_DESCRIPTION,description);
cv.put(COl_MYTABLE_LOCATION,location);
return mDB.insert(TABLE_MYTABLE,null,cv);
}
public Cursor getAllData() {
return mDB.query(TABLE_MYTABLE,null,null,null,null,null,null);
}
}
Результат
Результат выполнения выше: -