Как поместить данные счетчика в sqlite с помощью нажатия кнопки? - PullRequest
0 голосов
/ 10 мая 2019

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

// Get sample data from the database and display them in the spinner
    spinner1=(Spinner)findViewById(R.id.spinner);
    ArrayList <String> list=datahelper.getAllProvinces();
    ArrayAdapter <String> adapter=new ArrayAdapter<String>(this, R.layout.spinner_layout, R.id.text, list);
    spinner1.setAdapter(adapter);
    ok_button=findViewById ( R.id.ok_button );
    ok_button.setOnClickListener ( new View.OnClickListener () {
        @Override
        public void onClick(View v) {
            Ok_button_onClick ( v );

        }
    } );


}

private void Ok_button_onClick(View v) {
    spinner db = new spinner ( getApplicationContext () );
    String firstspin= (String) spinner1.getItemAtPosition ( spinner1.getSelectedItemPosition () );
    db.insertLabel ( firstspin );
    Toast.makeText ( Main2Activity.this,"Selected Item" + firstspin, Toast.LENGTH_SHORT).show ();

ошибка, что я получаю ..

D / AndroidRuntime: завершение работы VM E / AndroidRuntime: FATAL EXCEPTION: main Process:com.example.newlogin, PID: 14079 java.lang.NullPointerException: попытка вызвать виртуальный метод 'int android.widget.Spinner.getSelectedItemPosition ()' для ссылки на пустой объект в com.example.newlogin.loginSQLite.Main2Activity.Ok_buton_Main2Activity.java:64) на com.example.newlogin.loginSQLite.Main2Activity.access $ 000 (Main2Activity.java:24) на com.example.newlogin.loginSQLite.Main2Activity $ 1.onClick (Main2Activity.java:49) на android.view.View.performClick (View.java:5610) на android.view.View $ PerformClick.run (View.java:22265) на android.os.Handler.handleCallback (Handler.java:751) на android.os.Handler.dispatchMessage (Handler.java:95) на android.os.Looper.loop (Looper.java:154) на android.app.ActivityThread.main (ActivityThread.java:6077) на java.lang.reflect.Method.invoke (роднойМетод) в com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:866) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:756)

Ответы [ 2 ]

0 голосов
/ 15 мая 2019

Дополнительно

Следование ответу с использованием ArrayList на самом деле не лучший подход.

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

В SQLite, за исключением специальных таблиц, определенных с использованием WITHOUT ROWID, все таблицы имеют специальный, обычно скрытый столбец, называемый ROWID .Содержит целое число (до 64 разрядов со знаком, так что потенциально 9223372036854775807 строк (в два раза больше, если вы используете отрицательные значения)).

Столбец rowid (обычно с псевдонимом (см. Далее)) имеет некоторые преимущества.Его можно рассматривать как индекс MASTER (лучше, чем индекс PRIMARY).Поиск rowid или его псевдонима выполняется быстрее.

Данные для таблиц rowid хранятся в виде структуры B-Tree, содержащей одну запись для каждой строки таблицы, с использованием значения rowidкак ключ.Это означает, что получение или сортировка записей по rowid выполняется быстро.Поиск записи с определенным идентификатором строки или всех записей с идентификаторами строк в указанном диапазоне выполняется примерно вдвое быстрее, чем аналогичный поиск, выполняемый путем указания любого другого PRIMARY KEY или индексированного значения.

Хранилищедля хранения rowid будет меньше, чем a для строки, поэтому при извлечении данных может быть буферизовано больше строк.

Обычно таблица будет иметь псевдоним rowid специально с использованием INTEGER PRIMARY KEY (например, INT PRIMARY KEY не создает псевдоним rowid ).Если вы проверите ответ, то увидите, что в столбце _id (то есть BaseColumns._ID) используется INTEGER PRIMARY KEY.

Таким образом, использование ArrayList может быть неэффективным в качестве единственного способа последующего доступа к данным.из базы данных требует менее эффективного, чем оптимальный, поиск этой строки.

ArrayList

Если бы вы создавали объект Province, который включает переменную-член (поле) для rowid (как правило, его псевдоним) и использование ArrayList в качестве источника для счетчика, тогда использование этого значения может иметь преимущества в плане эффективности (меньше данных для хранения, более быстрый доступ к данным, больше буферизованных данных).

Если это значение хранится в соответствующей таблице, то изменение значения «Провинция Х» на «Провинция» в таблице «Провинция» приведет к изменению этого значения во всем.Так что только 1 обновление.

Таким образом, рабочий пример ниже включает в себя Spinner и Button, которые используют ArrayList (также включен класс Province).

CursorAdapater (SimpleCursorAdapter)

Как вы уже поняли, с помощью Android SQLite SDK / API вы получаете данные в Cursor, и, как подсказывает заголовок этого раздела, есть адаптеры для Cursors для ListViews и Spinners.Использовать их, на мой взгляд, еще проще, и у них есть несколько преимуществ.У них есть методы, которые возвращают _id (должен быть псевдонимом столбца rowid ). ЕСЛИ ЭТО ВАЖНО ДЛЯ АДАПТЕРОВ КУРСОРА, столбец определенно называется _id (следовательно, константа BaseColumns._ID).Адаптер курсора вылетит, если такой колонки нет.Результаты непредсказуемы, если столбцы не являются псевдонимами столбца rowid .

  • Infact ArrayAdapters также имеют обработку идентификаторов, например, существует getSelectedItemId () .Тем не менее, это вернет позицию не как целое число, а как долго, onItemClickListeners также будет включать значение в качестве 4-го параметра (опять же, поскольку курсор отсутствует, значение - это позиция выбранного элемента).

В качестве такового вы можете рассмотреть следующий пример / демонстрацию, в которой есть 3 счетчика и кнопки (оригинальный адаптер ArrayList, Aapter ArrayList и CursorAdapter).

Все три результата выводятся в журнал.

Пример демонстрационного кода

Класс Провинции. Province.java

public class Province {

    private long provinceId;
    private String provinceName;

    public Province(long id, String name) {
        this.provinceId = id;
        this.provinceName = name;
    }

    public Province(String name) {
        this(-1,name);
    }

    public Province() {
    }

    public long getProvinceId() {
        return provinceId;
    }

    public void setProvinceId(long provinceId) {
        this.provinceId = provinceId;
    }

    public String getProvinceName() {
        return provinceName;
    }

    public void setProvinceName(String provinceName) {
        this.provinceName = provinceName;
    }

    @Override
    public String toString() {
        return this.provinceName; // NOTE overridden to avoid using Custom adapter
    }
}
  • ничего сверх базового Java в вышеприведенном

макет действия activity_main.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=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
    <Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </Spinner>
    <Button
        android:id="@+id/ok_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OK">
    </Button>


    <Spinner
        android:id="@+id/spinner2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </Spinner>
    <Button
        android:id="@+id/ok2_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OK2 (Province ArrayList)">
    </Button>


    <Spinner
        android:id="@+id/spinner3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </Spinner>
    <Button
        android:id="@+id/ok3_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OK3 (Cursor)">
    </Button>
</LinearLayout>
  • Два дополнительных счетчика и кнопки

Расположение Spinner (без изменений, поэтому не отображается)

Помощник по базам данных

Помощник базы данных из исходного ответа имеет два дополнительных метода согласно

//<<<<<<<<<< ADDITIONAL FOR  ArrayList<Province> adapter
public ArrayList<Province> getAllProvicesAsProvinceObjects() {
    ArrayList<Province> rv = new ArrayList<>();
    Cursor csr = mDB.query(TABLENAME_PROVINCE,null,null,null,null,null,COL_PROVINCE_NAME);
    while (csr.moveToNext()) {
        rv.add(
                new Province(
                        csr.getLong(csr.getColumnIndex(COL_PROVINCE_ID)),
                        csr.getString(csr.getColumnIndex(COL_PROVINCE_NAME))
                )
        );
    }
    csr.close(); //<<<<<<<<<< should always close cursors when done with them
    return rv;
}

//<<<<<<<<<< ADDITIONAL FOR  Cursor adapter
public Cursor getAllProvincesAsCursor() {
    return mDB.query(TABLENAME_PROVINCE,null,null,null,null,null,null);
}
  • Первый getAllProvicesAsProvinceObjects () возвращает ArrayList
  • Второй возвращает Cursor (поэтому нет необходимости создавать промежуточный ArrayList) +1 для Cursor Adapter, который легче кодировать.

Активность MainActivity.java

У этого есть три из большинства частей кода.

Обратите внимание на управление ?????? методы, извлекать последние данные, создавать Spinner (один раз) и управлять (вызываясь согласно методу onResume в конце) обновлением списка (сообщить адаптеру, что данные изменились).

public class MainActivity extends AppCompatActivity {

    DatabaseHelper datahelper;
    Spinner spinner1,
            spinner2, //<<<<<<<<<<ADDITONAL For ArrayList<Province> adapter
            spinner3  //<<<<<<<<<<ADDITIONAL for Cursor adapter
                    ;
    Button ok_button,
            ok2_button, //<<<<<<<<<<ADDITIONAL For ArrayList<Province> adapter
            ok3_button  //<<<<<<<<<<ADDITIONAL for Cursor adapter
                    ;
    ArrayAdapter<String> adapter; //<<<<<<<<<< declares the adapter at class level
    ArrayList<String> list; //<<<<<<<<<< declares at the class level

    ArrayAdapter<Province> adapter2; //<<<<<<<<<<ADDITIONAL For ArrayList<Province> adapter
    ArrayList<Province> list2; //<<<<<<<<<< ADDITIONAL For ArrayList<Province> adapter

    SimpleCursorAdapter adapter3; //<<<<<<<<<<ADDITIONAL for Cursor adapter
    Cursor mCsr; //<<<<<<<<<<ADDITIONAL for Cursor adapter


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        datahelper = new DatabaseHelper(this);
        loadDataForDemo(); //<<<<<<<<<< load some data for the demo

        spinner1=(Spinner)findViewById(R.id.spinner);
        spinner2 =(Spinner) findViewById(R.id.spinner2); //<<<<<<<<<< For ArrayList<Province> adapter
        spinner3 = (Spinner) findViewById(R.id.spinner3); //<<<<<<<<<<ADDITIONAL for Cursor adapter

        list=datahelper.getAllProvinces(); //<<<<<<<<<< CHANGED to use already decalred
        adapter=new ArrayAdapter<String>(this, R.layout.spinner_layout, R.id.text, list); // <<<<<<<<< CHANGED to use already decalred
        spinner1.setAdapter(adapter);
        ok_button=findViewById ( R.id.ok_button );
        ok_button.setOnClickListener ( new View.OnClickListener () {
            @Override
            public void onClick(View v) {
                Ok_button_onClick (v);
            }
        } );

        manageSpinner2(); //<<<<<<<<<< For ArrayList<Province> adapter

        ok2_button = findViewById(R.id.ok2_button);
        ok2_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Ok_button2_onClick(v);
            }
        });

        manageSpinner3(); //<<<<<<<<<<ADDITIONAL for Cursor adapter

        ok3_button = findViewById(R.id.ok3_button);
        ok3_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Ok_button3_onClick(v);
            }
        });

    }

    //<<<<<<<<<< For ArrayList<Province> adapter >>>>>>>>>>
    private void manageSpinner2() {
        list2 = datahelper.getAllProvicesAsProvinceObjects();
        if (adapter2 == null) {
            adapter2 = new ArrayAdapter<>(this,R.layout.spinner_layout,R.id.text,list2);
            spinner2.setAdapter(adapter2);
        } else {
            // Note this applies any changed data (updates, insert, deletes)
            adapter2.clear();
            adapter2.addAll(list2);
            adapter2.notifyDataSetChanged();
        }
    }

    //<<<<<<<<<<ADDITIONAL for Cursor adapter >>>>>>>>>>
    private void manageSpinner3() {
        mCsr = datahelper.getAllProvincesAsCursor();
        if (adapter3 == null) {
            adapter3 = new SimpleCursorAdapter(
                    this,
                    R.layout.spinner_layout,mCsr,
                    // Note following arrays should have matching number of elements
                    new String[]{DatabaseHelper.COL_PROVINCE_NAME}, // columns to get data from
                    new int[]{R.id.text}, // view id's (TextViews) into which data goes
                    // Note SimpleCursorAdapter quite flexible as layout can have multiple column/view matchings
                    0
            );
            spinner3.setAdapter(adapter3);
        } else {
            adapter3.swapCursor(mCsr);
        }
    }

    private void Ok_button_onClick(View v) {
         String value_via_position =  list.get(spinner1.getSelectedItemPosition());
         String value_from_selected_item = (String) spinner1.getSelectedItem();
         Log.d("SELECTED","Selected item is " + value_via_position + " according to position.");
         Log.d("SELECTED","Selected item is " + value_from_selected_item + " as per the selected item method");
         long id_of_province1 = datahelper.getProvinceIdFromName(value_via_position);
         long id_of_province2 = datahelper.getProvinceIdFromName(value_from_selected_item);
         Log.d ("SELECTED","ID (via position) is " + String.valueOf(id_of_province1) + " ID (via selected item) is " + String.valueOf(id_of_province2));
    }

    private void loadDataForDemo() {
        // Only load provinces if none exist
        if (DatabaseUtils.queryNumEntries(datahelper.getWritableDatabase(),DatabaseHelper.TABLENAME_PROVINCE) > 0) return;
        String[] provinces_to_load = new String[]{
                "Hereington",
                "Nothereington",
                "Nowherington",
                "Somewhereington",
                "Overthereington",
                "Inthehaystackington",
                "Noweheretobefoundington",
                "Atsomeplaceington",
                "Zeroington",
                "Beforetheotherplacington"
        };
        for (String province: provinces_to_load) {
            datahelper.addProvince(province);
        }
    }

    //<<<<<<<<<< For OK2 button
    private void Ok_button2_onClick(View v) {
        Province thisProvince = (Province) spinner2.getSelectedItem();
        long id = ((Province) spinner2.getSelectedItem()).getProvinceId();
        //spinner2.getSelectedItemId()
        String name = ((Province) spinner2.getSelectedItem()).getProvinceName();
        Log.d("SELECTED2",
                "You selected Province:-" +
                        " ID=" + String.valueOf(thisProvince.getProvinceId()) +
                        " Name=" + thisProvince.getProvinceName());
    }

    private void Ok_button3_onClick(View v) {
        long id = spinner3.getSelectedItemId(); // Cursor Adapter knows the id
        String name = mCsr.getString(mCsr.getColumnIndex(DatabaseHelper.COL_PROVINCE_NAME));
        Log.d("SELECTED3","You clicked ID=" + String.valueOf(id) + " Name="+name);
    }


    @Override
    protected void onResume() {
        super.onResume();
        manageSpinner2(); //<<<<<<<<<< will apply changed data when returning to the activity
        manageSpinner3(); //<<<<<<<<<<< likewise for Cursor adapter
    }
}
0 голосов
/ 15 мая 2019

Ваша проблема связана с областью применения списка и spinner1 переменных.То есть область действия не позволяет им быть достигнутыми, и, таким образом, они являются нулевыми.

Обе переменные объявлены и созданы в методе onCreate действия и, таким образом, доступны только с этим действием,

Несмотря на то, что вы установили onClickListener кнопки в методе onCreate , при нажатии кнопки метод onCreate завершится до того, как выполучите шанс нажать кнопку, и тогда переменные будут недоступны.

Что вам нужно сделать, это объявить переменные, к которым вам нужен доступ, на более высоком уровне (на уровне класса).Вы можете получить к ним доступ внутри класса.

То есть вместо использования: -

protected void onCreate(Bundle savedInstanceState) {
    ..........
    spinner1=(Spinner)findViewById(R.id.spinner);
    ArrayList <String> list=datahelper.getAllProvinces();
    ArrayAdapter <String> adapter=new ArrayAdapter<String>(this, R.layout.spinner_layout, R.id.text, list); // included as you might well want to use this
    ..........
}
  • .......... используетсячтобы указать другие строки кода, не показанные для краткости.
  • Примечание см. комментарий к Адаптер Переменная.

Вы можетеиметь: -

public class Main2Activity extends AppCompatActivity {

    .......... // may be lines here

    Spinner spinner1;
    Button ok_button; //<<<<<<<< included as you may want to access this as well
    ArrayAdapter<String> adapter; //<<<<<<<<<< declares the adapter at class level
    ArrayList<String> list; //<<<<<<<<<< declares at the class level

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        ..........

        spinner1=(Spinner)findViewById(R.id.spinner);
        list=datahelper.getAllProvinces(); 
        adapter=new ArrayAdapter<String>(this, R.layout.spinner_layout, R.id.text, list);

        ..........
}

Теперь вы можете использовать: -

private void Ok_button_onClick(View v) {
    //spinner db = new spinner ( getApplicationContext () ); //<<<<<<<<<< A new spinner? Why? Probably not hence commented out, you you mean new Database Helper (see demo below)
    String firstspin= (String) spinner1.getItemAtPosition ( spinner1.getSelectedItemPosition () );
    //db.insertLabel ( firstspin ); //<<<<<<<<<<commented out re above
    Toast.makeText ( Main2Activity.this,"Selected Item" + firstspin, Toast.LENGTH_SHORT).show (); //could this on it's own (see demo)
  • Важно см. закомментированные строки.

Демонстрация / Рабочий пример

Ниже приведен рабочий пример, основанный на коде, представленном в вопросе.

Однако вместо вставки строки при нажатии (что согласно комментариямскорее всего потерпит неудачу), он получает rowid (число, уникальное для строки и, таким образом, средство id , обозначающее конкретную строку) в соответствии с выбранным именем,Обратите внимание, что в базовой таблице столбец определен с использованием UNIQUE, поэтому две провинции не могут быть одинаковыми.

  • Лучше не использовать ArrayList, а использовать ArrayList (или CursorAdapter, например SimpleCursorAdapter)это работает с курсором (вот почему в демонстрационной версии псевдоним rowid использует BaseColumns._ID )).
  • a_suitable_object может быть объектом Province (новый класс), которыйвключает провинцию и идентификатор в качестве переменных.

Активность ( MainActivity.java )

  • Примечание * loadDataForDemo, просто для загрузки некоторых данных для демонстрации.

: -

public class MainActivity extends AppCompatActivity {

    DatabaseHelper datahelper;
    Spinner spinner1;
    Button ok_button;
    ArrayAdapter<String> adapter; //<<<<<<<<<< declares the adapter at class level
    ArrayList<String> list; //<<<<<<<<<< declares at the class level

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        datahelper = new DatabaseHelper(this);
        loadDataForDemo(); //<<<<<<<<<< load some data for the demo

        spinner1=(Spinner)findViewById(R.id.spinner);
        list=datahelper.getAllProvinces(); //<<<<<<<<<< CHANGED to use already declared
        adapter=new ArrayAdapter<String>(this, R.layout.spinner_layout, R.id.text, list); // <<<<<<<<< CHANGED to use already declared
        spinner1.setAdapter(adapter);
        ok_button=findViewById ( R.id.ok_button );
        ok_button.setOnClickListener ( new View.OnClickListener () {
            @Override
            public void onClick(View v) {
                Ok_button_onClick (v);
            }
        } );
    }

    private void Ok_button_onClick(View v) {
         // <<<<<<<<< shows 2 ways of getting the value from the spinner >>>>>>>>>
         String value_via_position =  list.get(spinner1.getSelectedItemPosition());
         String value_from_selected_item = (String) spinner1.getSelectedItem();
         Log.d("SELECTED","Selected item is " + value_via_position + " according to position.");
         Log.d("SELECTED","Selected item is " + value_from_selected_item + " as per the selected item method");
         long id_of_province1 = datahelper.getProvinceIdFromName(value_via_position);
         long id_of_province2 = datahelper.getProvinceIdFromName(value_from_selected_item);
         Log.d ("SELECTED","ID (via position) is " + String.valueOf(id_of_province1) + " ID (via selected item) is " + String.valueOf(id_of_province2));
    }

    private void loadDataForDemo() {
        // Only load provinces if none exist
        if (DatabaseUtils.queryNumEntries(datahelper.getWritableDatabase(),DatabaseHelper.TABLENAME_PROVINCE) > 0) return;
        String[] provinces_to_load = new String[]{
                "Hereington",
                "Nothereington",
                "Nowherington",
                "Somewhereington",
                "Overthereington",
                "Inthehaystackington",
                "Noweheretobefoundington",
                "Atsomeplaceington",
                "Zeroington",
                "Beforetheotherplacington"
        };
        for (String province: provinces_to_load) {
            datahelper.addProvince(province);
        }
    }
}

Вспомогательный класс базы данных (DatabaseHelper.java)

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;

    public static final String TABLENAME_PROVINCE = "province";
    public static final String COL_PROVINCE_ID = BaseColumns._ID; // use stock id column name
    public static final String COL_PROVINCE_NAME = "province";

    SQLiteDatabase mDB;

    public DatabaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLENAME_PROVINCE + "(" +
                COL_PROVINCE_ID + " INTEGER PRIMARY KEY," +
                COL_PROVINCE_NAME + " TEXT UNIQUE" +
                ")"
        );
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long addProvince(String provinceName) {
        ContentValues cv = new ContentValues();
        cv.put(COL_PROVINCE_NAME,provinceName);
        return mDB.insert(TABLENAME_PROVINCE,null,cv);
    }

    public ArrayList<String> getAllProvinces() {
        ArrayList<String> rv = new ArrayList<>();
        Cursor csr = mDB.query(TABLENAME_PROVINCE,null,null,null,null,null,COL_PROVINCE_NAME);
        while (csr.moveToNext()) {
            rv.add(csr.getString(csr.getColumnIndex(COL_PROVINCE_NAME)));
        }
        csr.close(); //<<<<<<<<<< should always close cursors when done with them
        return rv;
    }

    public long getProvinceIdFromName(String name) {
        long rv = -1; //default value to indicate not found (just in case)
        String whereclause = COL_PROVINCE_NAME + "=?";
        String[] wherearguments = new String[]{name};
        Cursor csr = mDB.query(TABLENAME_PROVINCE,null,whereclause,wherearguments,null,null,null);
        if (csr.moveToFirst()) {
            rv = csr.getLong(csr.getColumnIndex(COL_PROVINCE_ID));
        }
        csr.close(); //<<<<<<<<<< should always close cursors when done with them
        return rv;
    }
}
  • Это может значительно отличаться от вашего

Схема Spinner (очень базовая)

: -

<?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="match_parent">
    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

Схема деятельности

<?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!" />
    <Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </Spinner>
    <Button
        android:id="@+id/ok_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OK">
    </Button>
</LinearLayout>

Результат

Приложение выглядит так: -

enter image description here

С выбранным Spinner (выделенный элемент является выбранным элементом): -

enter image description here

Результирующий вывод вжурнал тогда: -

2019-05-15 11:07:39.300 D/SELECTED: Selected item is Noweheretobefoundington according to position.
2019-05-15 11:07:39.300 D/SELECTED: Selected item is Noweheretobefoundington as per the selected item method
2019-05-15 11:07:39.302 D/SELECTED: ID (via position) is 7 ID (via selected item) is 7
...