java - 单击textview时编辑SQLite数据

标签 java android sqlite

我想通过单击动态创建的 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):-

enter image description here

替代结果:-

enter image description here

在这两种情况下,单击一行都会导致 id 被 toasted(无需 try catch Toast)。

  • 两者都已在 Android 10 上进行了测试

关于java - 单击textview时编辑SQLite数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55439022/

相关文章:

java - 如何在eclipse中的文本区域显示滚动条

android - 服务完成后停止服务

python - 如何从 Django 模型更改 sqlite 表列值类型?

c++ - sqllite3_bin_text 的正确用法

c# - 将现有的 MySql 数据库记录传输到 SqLite

java - 如何使用(导入)com.aldebaran.qi.helper.proxies.*;在 android studio 上,以便它可以在我的手机上运行?

java - 非常简单的Java帐户管理

java - 如何在 json 中仅显示 oneToMany 中实体的一个属性?

android - 应用内结算错误 : Item already owned (BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED)

android - Dagger - 嵌套注入(inject),有必要调用inject()吗?