Удаление последнего элемента из spinner удаляет весь список

#android #spinner

#Android #счетчик

Вопрос:

Я пытаюсь использовать элемент управления spinner, который позволит пользователю удалять любой элемент списка. У меня есть кнопка «Добавить» для добавления элементов в список и кнопка «Удалить», которая удаляет отображаемый в данный момент элемент из списка.

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

Мой код выглядит следующим образом:

     @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

    // grab our UI elements so we can manipulate them (for the Spinner)
    // or add listeners to them (in the case of the buttons)
    m_myDynamicSpinner = (Spinner)findViewById(R.id.dynamicSpinner);
    m_addItemText = (EditText)findViewById(R.id.newSpinnerItemText);
    Button addButton = (Button)findViewById(R.id.AddBtn);
    Button clearButton = (Button)findViewById(R.id.ClearBtn);

    // create an arrayAdapter an assign it to the spinner
    m_adapterForSpinner = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
        ((ArrayAdapter)m_adapterForSpinner).setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    m_myDynamicSpinner.setAdapter(m_adapterForSpinner);

    // add listener for addButton
    addButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            addNewSpinnerItem();
        }
    });

    clearButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            clearSpinnerItems();
        }
    });
}

// add listener for addButton
private void addNewSpinnerItem() {
    if (m_addItemText.getText().length() == 0) {
        Toast.makeText(getApplicationContext(), "The textView is empty", Toast.LENGTH_LONG).show();
    } else {
        CharSequence textHolder = ""   m_addItemText.getText();
        ((ArrayAdapter) m_adapterForSpinner).add(textHolder);
    }
    m_addItemText.setText("");
}

private void clearSpinnerItems() {
    m_myDynamicSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
            Object t = m_adapterForSpinner.getItem(pos);
            ((ArrayAdapter) m_adapterForSpinner).remove((CharSequence) t);
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
            // TODO
        }
    });
}
  

У кого-нибудь есть идеи или предложения о том, как заставить это работать?

Комментарии:

1. Есть ли у вас setSingleChoiceItems или setMultiChoiceItems в spinner? и, пожалуйста, не могли бы вы предоставить какой-нибудь код, чтобы мы могли лучше вам помочь

2. какой ответ вы получаете в Log.v («Элемент удален», t «»); ?

3. с помощью Log.v(«Элемент удален», t «»); я получаю выбранный элемент, но не могу удалить выбранный элемент.

Ответ №1:

Проблема с вашим кодом заключается в том, что удаление происходит внутри обратного вызова onItemSelected, который вызывается каждый раз, когда вы удаляете запись, таким образом удаляя рекурсивно до тех пор, пока у вас фактически не останется больше записей для выбора. Если вы добавите журнал внутри этого метода:

 Log.d("Spinner", "Count: "   m_adapterForSpinner.getCount());
  

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

 public class SpinnerTest extends Activity {
    Spinner m_myDynamicSpinner;
    EditText m_addItemText;
    ArrayAdapter m_adapterForSpinner;

    public static boolean cleared = false;  //   <--- set up a static boolean here

       @Override
        public void onCreate(Bundle savedInstanceState) {
// all your code unchanged

        clearButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {

                cleared=false;   //   <--- nope, we did not clear the value yet

                clearSpinnerItems();
            }
        });
    }

// code unchanged

    private void clearSpinnerItems() {
        m_myDynamicSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                Object t = m_adapterForSpinner.getItem(pos);
                Log.d("Spinner", "Count: "   m_adapterForSpinner.getCount());

                if (!cleared)  //   <--- did I do it already?

                    ((ArrayAdapter) m_adapterForSpinner).remove((CharSequence) t);

                Log.d("Spinner", "Count: "   m_adapterForSpinner.getCount());

                cleared=true;  // I did it!

            }

// code unchanged
  

Комментарии:

1. это верно, после удаления элемента счетчик выбирает новый и вызывается сам, пока не останется ни одного элемента. Вы не должны регистрировать прослушиватель onitemselect, но выберите элемент, который вы хотите удалить, и удалите его, нажав на кнопку

2. @2red13 да, это то, что я бы тоже сделал, но я предполагаю, что это тестовый пример для кода, который я не видел, поэтому я даю решение, которое меньше всего изменяет структуру. Фактически, у этого подхода есть вторая проблема: вы не можете удалить опцию, которая уже выбрана (поскольку она не запускается onItemSelected).

3. @Shrey Я рад, что у вас это сработало. Просто убедитесь, что уведомление также связано с проблемой, о которой я упоминал в своем комментарии к 2red13 выше.

4. @Aleadam: не может ли этот код работать в режиме просмотра списка для удаления элемента при нажатии кнопки удаления???

Ответ №2:

я не могу понять ваш вопрос.любым способом вы можете получить позицию выбранного элемента, используя метод getSelectedItemPosition().

Комментарии:

1. я использую android.R.layout.simple_spinner_dropdown_item

2. и android.R.layout.simple_spinner_item

3. @shruti … просто попробуйте следующий код в clearspinneritem m_myDynamicSpinner.removeViewAt( m_myDynamicSpinner.getSelectedItemPosition()); и удалите код прослушивателя из метода.