How can i update a field of my spinner with user input in EditText

二次信任 提交于 2019-12-13 00:22:57

问题


I have a SQLite Database with is populating my Spinner. The "add" functionality it's working good! What I wanna do is when user clicks in on spinner item he can change the following field and update in the Database

My Spinner database

public class SpinnerDatabase extends SQLiteOpenHelper{
    private SQLiteDatabase db;

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "spinnerDB";
    private static final String TABLE_LABELS = "labels";
    private static final String KEY_ID = "id";
    private static final String KEY_NAME = "name";

    public SpinnerDatabase(Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_CATEGORIES_TABLES = "CREATE TABLE " +
                TABLE_LABELS + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"+
                KEY_NAME + " TEXT)";
        db.execSQL(CREATE_CATEGORIES_TABLES);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_LABELS);
        onCreate(db);
    }

    public void insertLabel(String label){
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_NAME,label);

        db.insert(TABLE_LABELS,null,values);
        db.close();
    }   
    public List<String> getAllLabels(){
        List<String> labels = new ArrayList<String>();
        String selectQuery = "SELECT * FROM "+ TABLE_LABELS;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery,null);
        if (cursor.moveToFirst()){
            do{
                labels.add(cursor.getString(1));
            }while (cursor.moveToNext());
        }

        cursor.close();
        db.close();
        return labels;
    }


    public void updateSpinner (int id, String label){
        ContentValues values;
        String where;

        db = this.getWritableDatabase();

        where = KEY_ID + " = " +id;

        values = new ContentValues();
        values.put(KEY_NAME,label);

        db.update(TABLE_LABELS,values,where,null);
        db.close();
    }
}

The problem is when I click the button to update, it doesn't do anything! And just update the other item (if I have more the one). This is my method in my fragment that list all the entries:

 private void loadSpinnerData (){
        SpinnerDatabase db = new SpinnerDatabase(getActivity().getApplicationContext());

        List<String> labels = db.getAllLabels();

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
                android.R.layout.simple_spinner_item,labels);

        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
    }

And here the button save that i'm trying to do the update:

btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = editText.getText().toString();

                if(name.length()>0 && name != null){
                    int spinnerValue = spinner.getSelectedItemPosition();
                    SpinnerDatabase db = new SpinnerDatabase(getActivity().getApplicationContext());
                    db.updateSpinner(spinnerValue,name);
            }
        });

回答1:


Your issue, is that you are using the Spinner's selected position (0,1,2 etc) as the row's id. The first row id will be 1, then 2, etc (probably but NOT CERTAINLY i.e. delete a row for some reason and you have a gap in the sequence).

As such what you are currently experiencing is a difference of 1 between row id and spinner position, so either nothing or another row is being updated.

You either need to employ some method of working out the row id to spinner position (e.g a second array that has the respective id for the same index of the first array), or to, what I'd do is, take advantage of the flexibility of a CursorAdpater, such as SimpleCursorAdapter and then use spinner.getSelectedItemId() instead of spinner.getSelectedItemPosition().


To use A CursorAdapter, you will need a row called _id (e.g. change private static final String KEY_ID = "id"; to public static final String KEY_ID = "_id";)

Note! I'd also suggest changing, as I have above, your private statics to public statics).

Also to use a CursorAdapter, you will need a Cursor. The following method in SpinnerDatabase.java would suffice.

public Cursor getAll() {
    db = this.getWritableDatabase();
    return db.query(TABLE_LABELS,null,null,null,null,null,null);
}

The following could be used to setup the adpater:-

    csr = dbhlpr.getAll();

    sca = new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_1,
            csr,
            new String[]{SpinnerDatabase.KEY_NAME},
            new int[]{android.R.id.text1},0);

    spinner.setAdapter(sca);

Note! the use of SpinnerDatabase.KEY_NAME, this is an example of why I suggest 'public static' as opposed to private static.

There are sublte differences for the SimpleCursorAdpater;

  • 3rd paramter is the Cursor,
  • 4th is a String array of the column names in the cursor to be dis0played(should match 5th parameter),
  • 5th is the id's of the views into which the data is placed (for simple_list_item_1 use 1 column name along with android.R.id.text1 as above).

and when it comes to the update use spinner.getSelectedItemId() for the row id.


Working Example (assumes rows have data)

SpinnerDatabase.java

public class SpinnerDatabase extends SQLiteOpenHelper {
    private SQLiteDatabase db;

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "spinnerDB";
    private static final String TABLE_LABELS = "labels";
    private static final String KEY_ID = "_id";
    public static final String KEY_NAME = "name";

    public SpinnerDatabase(Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_CATEGORIES_TABLES = "CREATE TABLE " +
                TABLE_LABELS + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"+
                KEY_NAME + " TEXT)";
        db.execSQL(CREATE_CATEGORIES_TABLES);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_LABELS);
        onCreate(db);
    }

    public void insertLabel(String label){
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_NAME,label);

        db.insert(TABLE_LABELS,null,values);
    }


    //Defunct
    public List<String> getAllLabels(){
        List<String> labels = new ArrayList<String>();
        String selectQuery = "SELECT * FROM "+ TABLE_LABELS;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery,null);
        if (cursor.moveToFirst()){
            do{
                labels.add(cursor.getString(1));
            }while (cursor.moveToNext());
        }

        cursor.close();
        return labels;
    }


    public void updateSpinner (long id, String label){
        ContentValues values;
        String where;

        db = this.getWritableDatabase();

        where = KEY_ID + " = " +id;

        values = new ContentValues();
        values.put(KEY_NAME,label);

        db.update(TABLE_LABELS,values,where,null);
        db.close();
    }

    public Cursor getAll() {
        db = this.getWritableDatabase();
        return db.query(TABLE_LABELS,null,null,null,null,null,null);
    }
}

Activity SO46330096Activity.java

public class SO46330096Activity extends AppCompatActivity {

    SpinnerDatabase dbhlpr;
    Spinner spinner;
    Button editbutton;
    EditText spinneritem;
    SimpleCursorAdapter sca;
    Cursor csr;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_so46330096);
        spinner = (Spinner) findViewById(R.id.spinner);
        editbutton = (Button) findViewById(R.id.editbutton);
        spinneritem = (EditText) findViewById(R.id.spinnerinput);
        dbhlpr = new SpinnerDatabase(this);
        csr = dbhlpr.getAll();

        sca = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_1,
                csr,
                new String[]{SpinnerDatabase.KEY_NAME},
                new int[]{android.R.id.text1},0);
        spinner.setAdapter(sca);

        editbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (spinneritem.getText().toString().length() > 0) {
                    dbhlpr.updateSpinner(spinner.getSelectedItemId(),spinneritem.getText().toString());
                    sca.swapCursor(csr = dbhlpr.getAll());
                }
            }
        });

    }
}

The Layout activity_so46330096.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SO463300096 Activity"/>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:text="SPINNER ENTRY"
            />
        <EditText
            android:id="@+id/spinnerinput"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/editbutton"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:text="EDIT"/>
    </LinearLayout>
    <Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </Spinner>
</LinearLayout>

Example usage:-

Spinner selected (note update data has already been entered):-

Peanut Butter selected and Updated data entered :-

After Clicking Edit button :-


Setting the EditText to the currently selected Spinner Item

The following can be used to set the EditText to the value of the currently selected spinner item:-

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            spinneritem.setText(csr.getString(csr.getColumnIndex(SpinnerDatabase.KEY_NAME)));
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

The could be added after setting the Adapter in the Activity.

In the aboveSO46330096Activity.java it could follow the line :-

        spinner.setAdapter(sca);


来源:https://stackoverflow.com/questions/46330096/how-can-i-update-a-field-of-my-spinner-with-user-input-in-edittext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!