Search code examples
androidlistviewandroid-spinnercustom-adapter

Getting currently selected listview item spinner on button click


I am creating an app that contains a functionality that includes a list of questions with multiple answer options for each. To do this I am using a listview that with each item contains a TextView for displaying the question with a spinner that holds the list of answers. I am attempting to retrieve the currently selected value of a spinner within each listview item. This is typically easy except for the fact that I have a spinner for each listview item and the number of spinners I need is "unknown" until the number of questions is loaded.

My issue is how to get the value of each currently selected spinner item. Currently I am only able to get the value of the first spinner item. Below is my code for the class that uses my custom adapter:

questionsList = new ArrayList<>();
    masterAnswersList = new ArrayList<>();
    //For all questions with the tech answer's group id, get questions
    for(int k = 0; k < allQuestions.size(); k++) {
        final int z = k;
        //Each question for the tech
        System.out.println("Question " + z + " " + allQuestions.get(z).getQuestionTitle());
        questionsList.add(new CompleteQuestions.ListViewItem() {{
            QUESTION = allQuestions.get(z).getQuestionTitle();
        }});

        int questionId = allQuestions.get(z).getQuestionId();
        //Get all possible answers for this question based on the question and the group id
        allAnswers = db.getAllGroupAnswers(questionId, groupID, database);
        answersList = new ArrayList<>();
        //For all answers for this question, add to arraylist
        for(int j = 0; j < allAnswers.size(); j++) {
            final int p = j;
            answersList.add(new CompleteQuestions.ListViewItem() {{
                ANSWER = allAnswers.get(p).getAnswerTitle().trim();
            }});
        }
        masterAnswersList.add(answersList);
    }
    adapter = new CompQuestionsAdapter(this, questionsList, masterAnswersList);
    completeQuestionsListView.setAdapter(adapter);


//For the number of items in the listview
                for (int i = 0; i < completeQuestionsListView.getCount(); i++) {
                    //Update ticket questions table
                    String techChoice = CompQuestionsAdapter.spinner.getSelectedItem().toString();
                    System.out.println("techChoice: " + techChoice);
                    //Get id of answer tech chose
                    int techAnswerId = db.getAnswerId(techChoice, database);
                    int questionId = allQuestions.get(i).getQuestionId();
                    int groupId = db.getGroupId(techChoice, questionId, database);
                    System.out.println("Group id: " + groupId);
                    Ticket questionTicket = new Ticket(questionId, techAnswerId, ticketId, companyId, groupId, true);
                    db.addTicketQuestionResponse(questionTicket, context, database);
                }

And part of the custom adapter itself:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    /**
     * The database used to pull all ticket information
     */
    final DatabaseHandler db = new DatabaseHandler(context);
    final SQLiteDatabase database = db.getReadableDatabase();

    ListViewItem item = questions.get(position);
    //ListViewItem item2 = answers.get(position).get(position);
    View vi=convertView;

    if(convertView==null)
        vi = inflater.inflate(R.layout.comp_questions_view, null);

    TextView question = (TextView)vi.findViewById(R.id.QUESTION);
    question.setText("" + item.QUESTION);

    spinner = (Spinner)vi.findViewById(R.id.ANSWERS);
    List<String> strAnswers = new ArrayList<>();
    List<CompleteQuestions.ListViewItem> currentAnswers = answers.get(position);
    for (int i = 0; i < currentAnswers.size(); i++) {
        strAnswers.add(currentAnswers.get(i).ANSWER);
    }
    //Place all the cleared by codes in a string array used to populate the spinner
    String[] strArrayAnswers = new String[strAnswers.size()];
    for(int i = 0; i < strAnswers.size(); i++) {
        if(strAnswers.get(i) != null) {
            strArrayAnswers[i] = strAnswers.get(i);
        }
    }
    adapter = new ArrayAdapter<>(context,
            android.R.layout.simple_spinner_item, strArrayAnswers);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

    List<String> selections = new ArrayList<>();
    selections.add(spinner.getSelectedItem().toString());
    System.out.println("Currently selected item: " + spinner.getSelectedItem());

    return vi;
}

Any help on this would be greatly appreciated.


Solution

  • First of all you need to define an interface so your adapter class can use to tell the parent class which item has been chosen from the spinner in position and what is the selectedItem

    The OnSpinnerItemSelected Interface

    public interface OnSpinnerItemSelected {
        void onItemSelected(int position, String selectedItem);
    }
    

    Then you need to pass one OnSpinnerItemSelected Object in your adapter constructor.

    private OnSpinnerItemSelected onSpinnerItemSelected;
    
    public CompQuestionsAdapter(......, OnSpinnerItemSelected onSpinnerItemSelected) {
        this.onSpinnerItemSelected = onSpinnerItemSelected;
    }
    

    In your class that uses custem adapter add this:

        adapter = new CompQuestionsAdapter(this, questionsList, masterAnswersList, new OnSpinnerItemSelected() {
            @Override
            public void onItemSelected(int position, String selectedItem) {
    
            }
        });
    

    In your adapter call onItemSelected method (in getView method)

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
    
                onSpinnerItemSelected.onItemSelected(position, adapterView.getAdapter().getItem(i));
    
            }
    
            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {
    
            }
        });
    

    Just let me know if it's not clear.