Это было бы правильно? Или есть способ для нажатия кнопки «добавить строку», чтобы динамически добавить два дополнительных столбца в базу данных для каждого ввода.
Возможно, вы захотите рассмотреть не попытку динамического управления списком, а использование ListView для отображения текущих данных вместе с одним набором EditTexts для ввода новых данных.
Или мне нужно два
различные базы данных, которые сохраняют каждый вход в каждую базу данных с
тот же идентификатор и получить значения через тот же идентификатор первичного ключа?
Между столбцами и базой данных есть таблицы. Таким образом, проблема заключается в добавлении переменного числа испытаний в эксперименты. Затем испытание проводится в эксперименте, так что вы, вероятно, имеете таблицу эксперимента и таблицу испытаний, причем последняя ссылается на эксперимент с одним родителем, к которому относится исследование.
Несколько баз данных. Скорее всего, вы не хотите осложнений, и в этом нет никакой необходимости.
Пример
Вот рабочий пример (хотя он очень простой, особенно в плане компоновки), в котором есть ряд экспериментов, к которым можно добавить испытания. Код добавляет 3 эксперимента для демонстрации, названных Эксперимент 1, Эксперимент 2 и Эксперимент 3.
При первом запуске не будет никаких испытаний ни для одного из экспериментов. Их можно добавить после ввода данных (2 Edit Texts) и нажатия кнопки ADD. Вверху отображается название эксперимента, и при нажатии кнопки СЛЕДУЮЩАЯ будет проходить цикл экспериментов и показываться испытания для эксперимента (если есть).
Количество испытаний на эксперимент не ограничено.
Код
Компоновка
Первый макет activity_main.xml , который имеет
- название (вездесущий Hello World)
- два EditTexts и кнопка для добавления новых данных.
- a ListView для перечисления данных в базе данных.
Код: -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
<LinearLayout
android:layout_marginTop="10dp"
android:id="@+id/experimentsection"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFAAAAFF">
<TextView
android:id="@+id/currentexperiment"
android:layout_width="0dp"
android:layout_weight="8"
android:layout_height="wrap_content"
android:text="No Experiment"/>
<Button
android:id="@+id/nextexperiment"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="NEXT"/>
</LinearLayout>
<LinearLayout
android:id="@+id/inputsection"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/input1"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/input2"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/add"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:text="ADD"/>
</LinearLayout>
<ListView
android:id="@+id/currentdata"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
База данных Помощник
Помощник по базам данных DBHelper.java , который определяет одну таблицу с 3 столбцами
- столбец идентификатора, который однозначно идентифицирует строку.
- (обратите внимание, что адаптер ListView требует, чтобы это было названо _id)
- столбцы data1 и data1 для 2 значений будут сохранены
Код: -
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String TBL_EXPERIMENT = "experiment";
public static final String COL_ID = BaseColumns._ID;
public static final String COL_EXPERIMENT_NAME = "experiment_name";
public static final String TBL_MYTABLE1 = "mytable1";
public static final String COL_EXPERIMENT_REF = "experiment_ref";
public static final String COl_DATA1 = "data1";
public static final String COL_DATA2 = "data2";
SQLiteDatabase mDB;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TBL_EXPERIMENT + "(" +
COL_ID + " INTEGER PRIMARY KEY," +
COL_EXPERIMENT_NAME + " TEXT UNIQUE" +
")"
);
db.execSQL("CREATE TABLE IF NOT EXISTS " + TBL_MYTABLE1 + "(" +
COL_ID + " INTEGER PRIMARY KEY," +
COL_EXPERIMENT_REF + " INTEGER " +
" REFERENCES " + TBL_EXPERIMENT + "(" +
COL_ID +
")," +
COl_DATA1 + " TEXT," +
COL_DATA2 + " TEXT" +
")"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long addExperiment(String name) {
ContentValues cv = new ContentValues();
cv.put(COL_EXPERIMENT_NAME,name);
return mDB.insert(TBL_EXPERIMENT,null,cv);
}
public long addTrial(long expermientId, String data1, String data2) {
ContentValues cv = new ContentValues();
cv.put(COL_EXPERIMENT_REF,expermientId);
cv.put(COl_DATA1,data1);
cv.put(COL_DATA2,data2);
return mDB.insert(TBL_MYTABLE1,null ,cv);
}
public Cursor getAllRowsForAnExperiment(long experimentId) {
String whereclause = COL_EXPERIMENT_REF + "=?";
String[] whereargs = new String[]{String.valueOf(experimentId)};
return mDB.query(TBL_MYTABLE1,null,whereclause,whereargs,null,null,null);
}
public Cursor getAllExperiments() {
return mDB.query(TBL_EXPERIMENT,null,null,null,null,null,null);
}
public int deleteTrial(long id) {
String whereclause = COL_ID + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
return mDB.delete(TBL_MYTABLE1,whereclause,whereargs);
}
}
- addRow - метод, используемый для добавления строки данных.
- getAllRows - метод, используемый для извлечения всех данных.
Активность
Наконец, собрать все вместе - MainActivity.java
public class MainActivity extends AppCompatActivity {
//Define Class variables
DBHelper mDBHlpr;
Cursor mCursor, mExperiments;
SimpleCursorAdapter mSCA;
EditText mInput1, mInput2;
TextView mExperimentName;
Button mAdd, mNextExperiment;
ListView mListView;
long mCurrentExperimentId = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // Set the layout to be displayed
//Instaniate the layout objects to be used
mExperimentName = this.findViewById(R.id.currentexperiment);
mNextExperiment = this.findViewById(R.id.nextexperiment);
mInput1 = this.findViewById(R.id.input1);
mInput2 = this.findViewById(R.id.input2);
mAdd = this.findViewById(R.id.add);
mListView = this.findViewById(R.id.currentdata);
//Instantiate the Database helper
mDBHlpr = new DBHelper(this);
addSomeExperiments();
mExperiments = mDBHlpr.getAllExperiments();
// Do the work
manageExperimentButton();
manageListView();
manageAddButton();
}
/**
* Manage the list view,
* call this anytime the list is to be created (only once)
* or the list is changed (e.g. after adding)
*/
private void manageListView() {
mCursor = mDBHlpr.getAllRowsForAnExperiment(mCurrentExperimentId); // Get the current data
// If the Adapter hasn't been instantiated do so
if (mSCA == null) {
mSCA = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2,
mCursor,
new String[]{DBHelper.COl_DATA1, DBHelper.COL_DATA2},
new int[]{android.R.id.text1, android.R.id.text2},
0
);
mListView.setAdapter(mSCA); // Tie the adpater to the listview
//<<<<<<<<< EXTRA DELETE A ROW WHEN LONG CLICKED >>>>>>>>>>
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
if(mDBHlpr.deleteTrial(id) > 0) {
Toast.makeText(view.getContext(),"Deleted",Toast.LENGTH_SHORT).show();
manageListView();
} else {
Toast.makeText(view.getContext(),"NOT deleted????",Toast.LENGTH_SHORT).show();
}
return true; // set this event as having been actioned
}
});
} else {
// If adapter has been instantiated tell it that the data has changed
mSCA.swapCursor(mCursor);
}
}
//Handle the Add button by adding an onClick listener
private void manageAddButton() {
mAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//First thing check if there is data to be added
if (mInput1.getText().toString().length() < 1) {
Toast.makeText(v.getContext(),"No data in Input1. Try again",Toast.LENGTH_SHORT).show();
mInput1.requestFocus();
return;
}
if (mInput2.getText().toString().length() < 1) {
Toast.makeText(v.getContext(),"No data in Input2. Try again",Toast.LENGTH_SHORT).show();
mInput2.requestFocus();
return;
}
// If there is data to be added, try adding it
// if the value returned from addRow is less than 1 or more then data was added
if (mDBHlpr.addTrial(mCurrentExperimentId, mInput1.getText().toString(),mInput2.getText().toString()) > 0) {
Toast.makeText(v.getContext(),"Added",Toast.LENGTH_SHORT).show();
// As data has been added refresh the ListView
manageListView();
// and clear the input fields
mInput1.setText("");
mInput2.setText("");
// and finally position the focus on the first input
mInput1.requestFocus();
} else {
// Ooops something went wrong (very unlikely with the current db schema)
Toast.makeText(v.getContext(),"Not Added????",Toast.LENGTH_SHORT).show();
}
}
});
}
private void manageExperimentButton() {
mExperiments = mDBHlpr.getAllExperiments();
mExperiments.moveToFirst();
handleCurrentExperiment();
mNextExperiment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!mExperiments.moveToNext()) {
mExperiments.moveToFirst();
}
handleCurrentExperiment();
}
});
}
private void handleCurrentExperiment() {
mCurrentExperimentId = mExperiments.getLong(mExperiments.getColumnIndex(DBHelper.COL_ID));
mExperimentName.setText(mExperiments.getString(mExperiments.getColumnIndex(DBHelper.COL_EXPERIMENT_NAME)));
manageListView();
}
//When the activity finishes close the cursor
@Override
protected void onDestroy() {
super.onDestroy();
mCursor.close();
}
//If returning to the activity refresh the ListView
@Override
protected void onResume() {
super.onResume();
manageListView();
}
private void addSomeExperiments() {
// Add some experiments if none exist
if(DatabaseUtils.queryNumEntries(mDBHlpr.getWritableDatabase(),DBHelper.TBL_EXPERIMENT) > 0 ) return;
mDBHlpr.addExperiment("Experiment 1");
mDBHlpr.addExperiment("Experiment 2");
mDBHlpr.addExperiment("Experiment 3");
}
}
Результат
Снимок экрана эксперимента с более чем 20 испытаниями (были добавлены A-Z) (хотя и бесполезная информация). Код также включает в себя удаление испытаний путем длительного нажатия на них в списке (как видно, некоторые из них были удалены, например, пробная версия E была удалена):
Нажав на СЛЕДУЮЩИЙ, вы попадете в Эксперимент 1, в котором меньше испытаний: -