Как скрыть один элемент в Android Spinner

Я ищу способ скрыть один элемент в виджере Android spinner. Это позволит вам моделировать счетчик без выбранных элементов и гарантирует, что обратный вызов onItemSelected () всегда вызывается для каждого выбранного элемента (если скрытый элемент является «текущим»). Обычно в счетчике всегда есть один элемент, который не генерирует обратный вызов, а именно текущий.

Существует некоторый код в stackoverflow для того, как отключить (серого) элементы, но не как скрыть объекты полностью, как если бы они не существовали.

После долгих экспериментов я придумал несколько хакерских решений, которые работают на разных старых и новых платформах Android. У этого есть некоторые незначительные косметические недостатки, которые трудно заметить. Я все равно хотел бы услышать о более официальном решении, кроме «не делай этого с помощью счетчика».

Это всегда скрывает первый элемент в счетчике, но его можно легко расширить, чтобы скрыть произвольный элемент или более одного элемента. Добавьте фиктивный элемент, содержащий пустую строку в начале списка элементов-счетчиков. Вы можете установить текущий выбор счетчика на элемент 0 до того, как откроется диалоговое окно счетчика, это будет имитировать невыбранный счетчик.

Пример установки Spinner с переопределением метода ArrayAdapter:

List list = new ArrayList(); list.add(""); // Initial dummy entry list.add("string1"); list.add("string2"); list.add("string3"); // Populate the spinner using a customized ArrayAdapter that hides the first (dummy) entry ArrayAdapter dataAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, list) { @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { View v = null; // If this is the initial dummy entry, make it hidden if (position == 0) { TextView tv = new TextView(getContext()); tv.setHeight(0); tv.setVisibility(View.GONE); v = tv; } else { // Pass convertView as null to prevent reuse of special case views v = super.getDropDownView(position, null, parent); } // Hide scroll bar because it appears sometimes unnecessarily, this does not prevent scrolling parent.setVerticalScrollBarEnabled(false); return v; } }; dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mySpinner.setAdapter(dataAdapter); 

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

 public class CustomAdapter extends ArrayAdapter { private int hidingItemIndex; public CustomAdapter(Context context, int textViewResourceId, String[] objects, int hidingItemIndex) { super(context, textViewResourceId, objects); this.hidingItemIndex = hidingItemIndex; } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { View v = null; if (position == hidingItemIndex) { TextView tv = new TextView(getContext()); tv.setVisibility(View.GONE); v = tv; } else { v = super.getDropDownView(position, null, parent); } return v; } } 

И используйте свой пользовательский адаптер при создании списка элементов.

 List list = new ArrayList(); list.add(""); // Initial dummy entry list.add("string1"); list.add("string2"); list.add("string3"); int hidingItemIndex = 0; CustomAdapter dataAdapter = new CustomAdapter(this, android.R.layout.simple_spinner_item, list, hidingItemIndex); dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mySpinner.setAdapter(dataAdapter); 

(Я не тестировал код) надеюсь, что это поможет.

Легче скрыть элемент в конце списка, обрезая список.

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

 List list = new ArrayList(); list.add("string1"); list.add("string2"); list.add("string3"); list.add("[Select one]"); final int listsize = list.size() - 1; ArrayAdapter dataAdapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item, list) { @Override public int getCount() { return(listsize); // Truncate the list } }; dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mySpinner.setAdapter(dataAdapter); mySpinner.setSelection(listsize); // Hidden item to appear in the spinner 

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

 public class CustomAdapter extends ArrayAdapter { private List dates; private int hideItemPostion; public CustomAdapter (Context context, int resource, List dates) { super(context, resource,dates); this.dates=dates; } public void setItemToHide(int itemToHide) { this.hideItemPostion =itemToHide; } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { View v = null; if (position == hideItemPostion) { TextView tv = new TextView(getContext()); tv.setVisibility(View.GONE); tv.setHeight(0); v = tv; v.setVisibility(View.GONE); } else v = super.getDropDownView(position, null, parent); return v; }} 

И настройка адаптера – это что-то вроде этого

 final CustomAdapter dataAdapter = new CustomAdapter(this,R.layout.spinner_item,dates); dataAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item); spinner.setAdapter(dataAdapter); dataAdapter.setItemToHide(0); 

При выборе некоторых элементов в раскрывающемся меню необходимо изменить положение

  spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView adapterView, View view, final int i, long l) { dataAdapter.notifyDataSetChanged(); mEPGDateSelector.setSelection(i); dataAdapter.setItemToHide(i);} @Override public void onNothingSelected(AdapterView adapterView) { } }); 

Просто для интереса я принял решение использовать подсказку «Подскажите». Этот код предназначен для Xamarin.Android , но он может быть отлично портирован на Java за 10 минут. Используйте его как простой ArrayAdapter не добавляя в исходный массив ArrayAdapter 0 или индексированные счетчиком. Он также устанавливает SpinnerGeolocation.SelectedItemId в -1, когда ничего не выбрано ( hint – текущий элемент).

 public class ArrayAdapterWithHint: ArrayAdapter { protected bool HintIsSet = false; protected int HintResource = 0; public ArrayAdapterWithHint(Context context, int textViewResourceId, T[] objects) : base(context, textViewResourceId, objects) { } public ArrayAdapterWithHint(Context context, int hintResource, int textViewResourceId, T[] objects) : base(context, textViewResourceId, objects) { HintResource = hintResource; } public ArrayAdapterWithHint(Context context, int textViewResourceId, IList objects) : base(context, textViewResourceId, objects) { } public ArrayAdapterWithHint(Context context, int hintResource, int textViewResourceId, IList objects) : base(context, textViewResourceId, objects) { HintResource = hintResource; } public override View GetDropDownView(int position, View convertView, ViewGroup parent) { if (HintIsSet) return base.GetDropDownView(position + 1, convertView, parent); return base.GetDropDownView(position, convertView, parent); } public override View GetView(int position, View convertView, ViewGroup parent) { if (!HintIsSet && parent is Spinner && !string.IsNullOrWhiteSpace((parent as Spinner).Prompt)) { Insert((parent as Spinner).Prompt, 0); HintIsSet = true; (parent as Spinner).SetSelection(base.Count - 1); } if (HintIsSet && position >= base.Count - 1) { View hintView = base.GetView(0, convertView, parent); if (hintView is TextView) (hintView as TextView).SetTextAppearance( Context, HintResource); return hintView; } if (HintIsSet && position < base.Count - 1) return base.GetView(position + 1, convertView, parent); return base.GetView(position, convertView, parent); } public override long GetItemId(int position) { if (HintIsSet) { if (position >= base.Count - 1) return -1; return position; } return base.GetItemId(position); } public override int Count { get { return base.Count > 0 && HintIsSet ? base.Count - 1 : base.Count; } } } 

Я думаю, будет лучше поставить проверку на список массивов, а не на Spinner, потому что, как только элемент будет отфильтрован, его можно будет добавить в Spinner

Я нашел это решение, которое решило мою проблему.

 final Spinner mySpinner = (Spinner)findViewById(R.id.spinner_triptype); final ArrayAdapter adapter = new ArrayAdapter(this,R.layout.spinner_item, R.id.weekofday, triptype_initial); final ArrayAdapter adapter_temp = new ArrayAdapter (this,R.layout.spinner_item, R.id.weekofday, triptype_array); mySpinner.setAdapter(adapter); mySpinner.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // display your error popup here if(flag_spinner_isFirst){ mySpinner.setAdapter(adapter_temp); flag_spinner_isFirst = false; } v.onTouchEvent(event); return true; } }); 

Другой подход, который лучше всего подходит для меня, – это вернуть новый пустой объект вида. Это значительно чистый подход, поскольку вы не играете с элементами массива.

Создайте свой class адаптера, расширяющий ArrayAdapter

внутри вашего метода

 public View getView(int position, View convertView, ViewGroup parent) { View row = getCustomView(); if(position==0) // put the desired check here. { row = new View(context); } } return row; } 
  • Spinner onItemSelected называется ошибочно (без действий пользователя)
  • Как изменить цвет шрифта Spinner?
  • Как установить стрелку вниз в spinner?
  • Multi-spinner в android без AlertDialog
  • Android: setSelection не влияет на Spinner
  • Как показать загрузчик в jQuery?
  • Spinner не обертывает текст - это ошибка Android?
  • Как создать список Spinner с помощью CustomAdapter в android
  • Как добавить элементы в spinner в Android?
  • Изменение цвета текста выбранного элемента в прядильщике
  • Как resize шрифта и цвет текста?
  • Давайте будем гением компьютера.