Редактировать данные SQLite при нажатии textview - PullRequest
2 голосов
/ 31 марта 2019

Я хочу обновить данные из базы данных SQLite, нажав на динамически созданное текстовое представление. Моя база данных показывает название, дату начала и дату окончания школьного семестра. Каждое текстовое представление показывает данные одного школьного семестра. Когда я нажимаю ID Textview, я хочу перейти на другой экран, где пользователь может редактировать данные этого конкретного термина. Проблема в том, что я не знаю, как подключить текстовое представление к идентификатору термина. Текстовые представления создаются динамически. При нажатии на текстовое представление идентификатора термина пользователь переходит на новый экран, где он может редактировать существующие данные. Однако значения EditText показывают только последний термин, потому что SetText перезаписывает условия ранее. Если я использую append, оба идентификатора заполняются в EditText. Я хочу, чтобы данные только одного термина отображались на экране редактирования, и мне нужно, чтобы термин соответствовал идентификатору Textview, по которому пользователь щелкает. Это код, где пользователь нажимает на термин, который он хочет изменить. У ID Textview есть onclickListeners, которые переносят пользователя на следующий экран, где EditText заполнен выбранными данными 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());
    }

Если я использую setText, отображаются только данные последнего термина Если я использую append, отображаются данные всех терминов.

1 Ответ

1 голос
/ 01 апреля 2019

Я считаю, что это делает то, что вы хотите (вместо того, чтобы обновлять строку, это столбец идентификатора Toast, который затем может быть передан через намерение и извлеченные данные).

Он использует тег каждого 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) {

    }
}

Активность: -

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");
        }
    }
}
  • Обратите внимание, что если вы добавляете / удаляете / редактируете строки в иерархически более низкой активности, вам необходимо перестроить представления.

  • LinearLayout с горизонтальной ориентацией был добавлен для каждой строки. Основной Linearlayout установлен в вертикальной ориентации.

Альтернатива (типовое решение)

Однако более простым в управлении (особенно в отношении обновленных данных) является ListView. Возможно, рассмотрите следующее как альтернативу.

В макете действия (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 TextViews (идентификатор не очень удобен для пользователя, так как он ничего не значит и может даже сбить с толку) на отображаемую строку, то другой макет для каждой строки списка, например, 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, чтобы можно было проверить оба действия): -

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();
    }
}

Результаты

Fisrt (динамические TextViews): -

enter image description here

Альтернатива приводит к: -

enter image description here

В обоих случаях нажатие на строку приводит к поджариванию идентификатора (не пытаясь поймать тост).

  • Оба были также проверены на Android 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...