我想通过单击动态创建的 TextView 来更新 SQLite 数据库中的数据。我的数据库显示学校学期的名称、开始日期和结束日期。每个 TextView 显示一个学期的数据。当我单击 ID Textview 时,我想转到另一个屏幕,用户可以在其中编辑该特定术语的数据。问题是我不知道如何将 TextView 连接到术语 ID。 TextView 是动态创建的。当单击术语的 ID TextView 时,用户将转到一个新屏幕,她可以在其中编辑现有数据。但是,EditText 值仅显示最后一个术语,因为 SetText 会覆盖之前的术语。如果我使用附加,则两个 ID 都会填写在 EditText 中。我只想在编辑屏幕上显示一个术语的数据,并且我想要与用户单击的 Textview ID 相对应的术语。这是用户单击他们想要编辑的术语的代码。 ID Textview 具有 onclickListeners,它将用户带到下一个屏幕,其中 EditText 填充了选定的术语数据(这就是它的工作方式) First block of code shows the first screen where the user clicks on the textvew that shows the id of each term
public void ViewAll() {
Cursor res = myDb.getAllData();
if(res.getCount() == 0) {
showMessage("Error", "Nothing Found");
return;
}
StringBuffer buffer = new StringBuffer();
while(res.moveToNext()) {
final LinearLayout layout = (LinearLayout ) findViewById(R.id.LinearLayOut);
final TextView textView1 = new TextView(this);
final TextView textView2 = new TextView(this);
final TextView textView3 = new TextView(this);
final TextView textView4 = new TextView(this);
textView1.append(res.getInt(0)+"\n");
textView2.append("Term Title : "+ res.getString(1)+"\n");
textView3.append("Start Date : "+ res.getString(2)+"\n");
textView4.append("End Date : "+ res.getString(3)+"\n");
textView1.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent myIntent = new Intent(ListTerms.this, EditTerms.class);
startActivity(myIntent);
}
}
);
layout.addView(textView1);
layout.addView(textView2);
layout.addView(textView3);
layout.addView(textView4);
}
} public void onClick(View v) {
Intent myIntent = new Intent(ListTerms.this, EditTerms.class);
startActivity(myIntent);
}
}
);
layout.addView(textView1);
layout.addView(textView2);
layout.addView(textView3);
layout.addView(textView4);
}
public void UpdateData() {
saveTermInfoBtn.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean isUpdate = myDb.updateTerm(termId.getText().toString(), inputTerm.getText().toString(), inputStart.getText().toString(), inputEnd.getText().toString());
if (isUpdate == true) {
Toast.makeText(EditTerms.this, "Data Update", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(EditTerms.this, "Data Not Updated", Toast.LENGTH_LONG).show();
}
}
}
);
}
public void ViewAll() {
Cursor res = myDb.getAllData();
if(res.getCount() == 0) {
// show message
showMessage("Error","Nothing found");
return;
}
StringBuffer buffer = new StringBuffer();
while (res.moveToNext()) {
termId.setText(res.getString(0) + "\n");
inputTerm.setText(res.getString(1) + "\n");
inputStart.setText(res.getString(2) + "\n");
inputEnd.setText(res.getString(3) + "\n\n");
}
// Show all data
showMessage("Data",buffer.toString());
}
If I use setText only the data of the last term gets displayed If I use append the data of all the terms gets displayed.
最佳答案
我相信这可以满足您的需求(而不是更新 Toast 的 id 列中的一行,然后可以通过 Intent 和提取的数据进行传递)。
它利用每个 TextView 的标签来存储各自的id
DatabaseHelper 使用DatabaseHelper.java :-
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "school.db";
public static final int DBVERSION = 1;
public static final String TBL_TERM = "term";
public static final String COL_TERM_ID = BaseColumns._ID;
public static final String COL_TERM_TITLE = "title";
public static final String COL_TERM_STARTDATE = "startdate";
public static final String COL_TERM_ENDDATE = "enddate";
SQLiteDatabase mDB;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, 1);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crt_term_sql = "CREATE TABLE IF NOT EXISTS " + TBL_TERM + "(" +
COL_TERM_ID + " INTEGER PRIMARY KEY, " +
COL_TERM_TITLE + " TEXT, " +
COL_TERM_STARTDATE + " TEXT," +
COL_TERM_ENDDATE + " TEXT" +
")";
db.execSQL(crt_term_sql);
}
public long addTerm(String title, String startdate, String enddate) {
ContentValues cv = new ContentValues();
cv.put(COL_TERM_TITLE,title);
cv.put(COL_TERM_STARTDATE,startdate);
cv.put(COL_TERM_ENDDATE,enddate);
return mDB.insert(TBL_TERM,null,cv);
}
public Cursor getAllData() {
return mDB.query(TBL_TERM,null,null,null,null,null,COL_TERM_STARTDATE + " ASC");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Activity :-
public class MainActivity extends AppCompatActivity {
LinearLayout layout;
DatabaseHelper myDB;
Cursor mCsr;
Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
layout = this.findViewById(R.id.LinearLayout);
mContext = this;
myDB = new DatabaseHelper(this);
addSomeData();
mCsr = myDB.getAllData();
while (mCsr.moveToNext()) {
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.HORIZONTAL);
long currentID = mCsr.getLong(mCsr.getColumnIndex(DatabaseHelper.COL_TERM_ID));
addtextView(ll,currentID,mCsr.getString(mCsr.getColumnIndex(DatabaseHelper.COL_TERM_ID)) + " ");
addtextView(ll,currentID,mCsr.getString(mCsr.getColumnIndex(DatabaseHelper.COL_TERM_TITLE))+ " ");
addtextView(ll,currentID,mCsr.getString(mCsr.getColumnIndex(DatabaseHelper.COL_TERM_STARTDATE))+ " ");
addtextView(ll, currentID,mCsr.getString(mCsr.getColumnIndex(DatabaseHelper.COL_TERM_ENDDATE))+ " ");
layout.addView(ll);
}
}
private void addtextView(LinearLayout ll, long tag, String data) {
TextView current_tv = new TextView(this);
current_tv.setTag(String.valueOf(tag)); //<<<<<<<<<< SETS THE TAG with current_id
current_tv.setText(data);
ll.addView(current_tv);
current_tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
long id = Long.valueOf((String)v.getTag()); //<<<<<<<<<< RETRIEVES THE id FROM THE TAG
Toast.makeText(mContext,"You clicked on ID " + String.valueOf(id),Toast.LENGTH_SHORT).show();
}
});
}
// JUST TO ADD SOME DATA FOR TESTING (if none exists)
private void addSomeData() {
if (DatabaseUtils.queryNumEntries(myDB.getWritableDatabase(),DatabaseHelper.TBL_TERM) < 1) {
myDB.addTerm("Term 1","2019-01-01","2019-03-31");
myDB.addTerm("Term 2","2019-04-01","2019-06-30");
myDB.addTerm("Term 3","2019-07-01","2019-08-31");
myDB.addTerm("Term 4","2019-09-01","2019-12-31");
}
}
}
请注意,如果您在层次结构较低的 Activity 中添加/删除/编辑行,则需要重建 View 。
已为每行添加了水平方向的 LinearLayout。主要 Linearlayout 设置为垂直方向。
替代方案(典型解决方案)
但是,ListView 更易于管理(尤其是更新数据)。也许可以考虑以下作为替代方案。
在 Activity 的(本例中为 Main2Activity)布局中添加一个 ListView,例如activity_main2.xml 是:-
<?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=".Main2Activity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Terms"
android:layout_marginBottom="20dp"/>
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
正如您希望每个显示行有 3 个 TextView(id 并不是真正的用户友好,因为它没有任何意义,甚至可能令人困惑),然后为列表的每一行使用另一个布局,例如termlist.xml:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_weight="6"
android:layout_height="match_parent" />
<TextView
android:id="@+id/startdate"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
<TextView
android:id="@+id/enddate"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
</LinearLayout>
DatabaseHelper DatabaseJelper.java 未更改。
MainActivity2.java(用作 MainActivity 的替代项,以便可以检查这两个 Activity ):-
public class Main2Activity extends AppCompatActivity {
DatabaseHelper myDB;
ListView mylistview;
SimpleCursorAdapter sca;
Cursor mCsr;
Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mContext = this;
mylistview = this.findViewById(R.id.listview);
myDB = new DatabaseHelper(this);
addSomeData();
manageListView();
}
private void manageListView() {
mCsr = myDB.getAllData();
if (sca == null) {
sca = new SimpleCursorAdapter(
this,
R.layout.termlist,mCsr,
new String[]{DatabaseHelper.COL_TERM_TITLE,DatabaseHelper.COL_TERM_STARTDATE,DatabaseHelper.COL_TERM_ENDDATE},
new int[]{R.id.title,R.id.startdate,R.id.enddate},
0
);
mylistview.setAdapter(sca);
mylistview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(mContext,"Your clicked on ID " + String.valueOf(id),Toast.LENGTH_SHORT).show();
}
});
} else {
sca.swapCursor(mCsr);
}
}
// JUST TO ADD SOME TEST DATA IF NOE EXISTS
private void addSomeData() {
if (DatabaseUtils.queryNumEntries(myDB.getWritableDatabase(),DatabaseHelper.TBL_TERM) < 1) {
myDB.addTerm("Term 1","2019-01-01","2019-03-31");
myDB.addTerm("Term 2","2019-04-01","2019-06-30");
myDB.addTerm("Term 3","2019-07-01","2019-08-31");
myDB.addTerm("Term 4","2019-09-01","2019-12-31");
}
}
//ADDED as simply calling manageListView will rebuild the list according to the data
// as such when the activity is returned to from another the List is rebuilt
// (basically the Cursor mCsr is overwritten and then as the SimpleCursorAdapter sca is instantiated
// the Cursor is swappped)
@Override
protected void onResume() {
super.onResume();
manageListView();
}
}
结果
第一个(动态 TextView):-
替代结果:-
在这两种情况下,单击一行都会导致 id 被 toasted(无需 try catch Toast)。
- 两者都已在 Android 10 上进行了测试
关于java - 单击textview时编辑SQLite数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55439022/