Spinner не обертывает текст – это ошибка Android?

Если текст элемента Spinner слишком длинный, чтобы вписаться в одну строку, текст не обернут, а обрезается. Это относится только к уровню API> = 11 . Вот скриншоты Android 4.2.2 (слева), которые показывают неправильное поведение и Android 2.3.3 (справа), где это выглядит так, как ожидалось.

android:singleLine="false" просто игнорируется здесь. Итак, как и все другие, такие как android:lines , android:minLines и т. Д. TextView каким-то образом кажется намного шире ширины windows.

Я видел других людей, имеющих ту же проблему, но никто не мог найти решение. Итак, это системная ошибка? Я не думаю, что это несоответствие между версиями ОС может быть предназначено.


Пожалуйста, обратите внимание:

Были некоторые ответы, предлагающие относительно простые решения.

  • Написание пользовательского Adapter и переопределение getView() а также getDropDownView() . Это не решение здесь, потому что на данный момент все еще существует оригинальная проблема: как макет должен выглядеть так, чтобы обрабатывать правильную упаковку строк?

  • Обтекание TextView из раскрывающегося ViewGroup в родительскую ViewGroup . Не работает с android:layout_width="match_parent" потому что ширина родителя странно кажется неограниченной.

  • Предоставление раскрывающегося списка фиксированной ширины. Это не подходит для различной ширины, которую может использовать Spinner .

  • И, конечно же, никакое решение не должно вручную вставлять \n любом месте в текст.


Воспроизведите следующий код:

UPDATE: Я также добавил это как пример проекта на GitHub : Скачать

/res/values/arrays.xml:

  Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est.  

/res/layout/spinner_item.xml:

  

Установить Adapter :

 spinner.setAdapter(ArrayAdapter.createFromResource(this, R.array.items, R.layout.spinner_item)); 

В голой теме spinner по умолчанию использует выпадающий режим. И все движения с переопределяющими стилями по умолчанию просто переходят к переключению режима spinner в режим диалога, который успешно обертывает многострочный текст, как в api 11. Вместо этого вы можете создать spinner с new Spinner(context, Spinner.MODE_DIALOG) или в xml: android:spinnerMode="dialog" . Но проблема не решена, потому что это диалог, а не раскрывающийся список.

Я нашел другое решение для этой проблемы: переопределите метод getDropDownView в ArrayAdapter и поместите setSingleLine(false) в метод post post. Поэтому, когда просмотр полностью создан, он привязывает текст к соответствующим строкам.

 @Override public View getDropDownView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = new TextView(_context); } TextView item = (TextView) convertView; item.setText("asddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"); final TextView finalItem = item; item.post(new Runnable() { @Override public void run() { finalItem.setSingleLine(false); } }); return item; } 

ОБНОВИТЬ:

И вот еще один ответ.

Вручную сверните listview в PopupWindow и покажите его в TextView при щелчке и спрячьте его в щелчке по списку.

Простая реализация, чтобы показать идею:

 public class MySpinner extends TextView { private PopupWindow _p; private ListView _lv; public MySpinner(Context context) { super(context); init(); } public MySpinner(Context context, AttributeSet attributeSet){ super(context, attributeSet); init(); } private void init(){ setBackgroundResource(R.drawable.spinner_background); final List list = new ArrayList(); list.add("Very long text AAAAAAAAAAAAAAAA"); list.add("1 Very long text AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); list.add("2 Very long text A"); list.add("3 Very long text AAAAAAAAA"); setMinimumWidth(100); setMaxWidth(200); _lv = new ListView(getContext()); _lv.setAdapter(new ArrayAdapter(getContext(), R.layout.simple_list_item_1, list)); _lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { _p.dismiss(); setText(list.get(i)); } }); setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { _p = new PopupWindow(getContext()); _p.setContentView(_lv); _p.setWidth(getWidth()); _p.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); _p.setTouchable(true); _p.setFocusable(true); _p.setOutsideTouchable(true); _p.showAsDropDown(view); } }); } } 

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

  

Для меня работала только комбинация решений (тестировалась также на Android 5.1):

spinner_item.xml

    

код

  final ArrayAdapter spinnerArrayAdapter=new ArrayAdapter(activity,R.layout.spinner_item,android.R.id.text1,spinnerItemsList) { @Override public View getDropDownView(final int position,final View convertView,final ViewGroup parent) { final View v=super.getDropDownView(position,convertView,parent); v.post(new Runnable() { @Override public void run() { ((TextView)v.findViewById(android.R.id.text1)).setSingleLine(false); } }); return v; } }; spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 

Достижение многострочных выпадающих элементов на Spinner при использовании темы Holo невозможно, из того, что я пробовал.

Обходным решением является:

  • создайте стиль для Spinner , который не наследуется от Holo . Это позволит многострочные выпадающие элементы.
  • Нарисуйте Spinner ‘вручную’, так что похоже, что это Holo themed.

Это создает (показывает закрытые и открытые состояния):

введите описание изображения здесь

Подробная информация о реализации:

Насколько я могу сказать, нет способа наследовать тему Holo на Spinner и показывать несколько строк в раскрывающемся элементе Spinner , даже если мы устанавливаем атрибут singleLine TextView singleLine в false и поставляем собственный макет , Я также старался придерживаться стиля Holo но изменяя

 android:spinnerStyle android:spinnerItemStyle android:spinnerDropDownItemStyle 

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

Однако, если мы переопределим стиль для Spinner и не наследуем spinnerStyle от Holo :

   <--no parent attribute-->  

то раскрывающийся элемент будет поддерживать показ нескольких строк. Но теперь мы потеряли тему Holo на Spinner и закрытое состояние выглядит как TextView не Spinner без стрелки или визуальной подсказки, это Spinner . Если вместо этого установить родительский spinnerStyle : parent="android:style/Widget.Spinner :

  

закрытое состояние Spinner покажет стрелку, но будет выглядеть как серый pre-Holo Spinner который выглядит неуместным в приложении Holo .

Итак, возможно решение:

  • Переопределите тему для spinnerStyle и не используйте Holo для родителя. Это позволит многострочный текст в элементах DropDown.
  • Измените фон Spinner чтобы он выглядел так, как будто он наследует тему Holo .

Вот пример:

Создать основную деятельность:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Spinner spinner = (Spinner)findViewById(R.id.styled_spinner); spinner.setAdapter(ArrayAdapter.createFromResource(this, R.array.items, R.layout.spinner_item)); } 

Схема действий:

    

стили:

     

в выпадающей папке, место spinner_background_holo_light:

       

и drawables-hdpi эти drawables-hdpi папку drawables-hdpi :

введите описание изображения здесь spinner_default_holo_light.9.png

введите описание изображения здесь spinner_disabled_holo_light.9.png

введите описание изображения здесь spinner_focused_holo_light.9.png

введите описание изображения здесь spinner_pressed_holo_light.9.png

Это создает счетчик с закрытым состоянием Holo themed и многострочными элементами, как показано на скриншотах выше.

Выпадающие элементы в этом примере не являются Holo themed, но, возможно, это приемлемый компромисс, если многолинейное отображение выпадающих элементов действительно важно.

В этом примере для android:minSdkVersion установлено значение 14 и android:targetSdkVersion17 в манифесте.

Графика Holo и код spinner_background_holo_light.xml принадлежат HoloEverywhere Copyright (c) 2012 Кристоф Верси, Сергей Шатунов. См. Связанный проект github для получения сведений о лицензии.

Добавление LinearLayout вокруг TextView позволяет корректно обертывать текст.

Макет (common_domainreferencemodel_spinner_item.xml):

    

адаптер:

 public class DomainReferenceModelAdapter extends ArrayAdapter { private List objects; private LayoutInflater inflater; private int oddRowColor = Color.parseColor("#E7E3D1"); private int evenRowColor = Color.parseColor("#F8F6E9"); public DomainReferenceModelAdapter(Context context, int resource, List objects) { super(context, resource, objects); this.objects = objects; this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } static class ViewHolder { public TextView nameTextView; } @Override public View getView(int position, View convertView, ViewGroup parent) { return getViewInternal(position, convertView, parent, false); } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { return getViewInternal(position, convertView, parent, true); } private View getViewInternal(int position, View convertView, ViewGroup parent, boolean isDropdownView) { View view = convertView; if (view == null) { view = inflater.inflate(R.layout.common_domainreferencemodel_spinner_item, null); ViewHolder viewHolder = new ViewHolder(); viewHolder.nameTextView = (TextView) view.findViewById(R.id.nameTextView); view.setTag(viewHolder); } if (isDropdownView) { view.setBackgroundColor(position % 2 == 0 ? evenRowColor : oddRowColor); } ViewHolder holder = (ViewHolder) view.getTag(); DomainReferenceModel model = objects.get(position); holder.nameTextView.setText(model.getName()); return view; } } 

Я столкнулся с той же проблемой. Я хочу видеть 2 строки в выпадающем списке spinner, но все найденные мной решения кажутся мне необоснованными для решения такой простой проблемы. Я исследую исходный код Spinner, и я нашел, если мы используем пользовательский .xml с атрибутом android: singleLine = “false”

  

и по умолчанию ArrayAdapter, следующий код, выполняемый в ListPopupWindow каждый раз

  @Override View More obtainView(int position, boolean[] isScrap) { View view = super.obtainView(position, isScrap); if (view instanceof TextView) { ((TextView) view).setHorizontallyScrolling(true); } return view; } 

и поэтому мы видим только одну строку строки в строке списка, она фактически прокручивается.

Чтобы решить эту проблему, наше представление должно быть не экземпляром TextView, просто поместите свой TextView в FrameLayout или LinearLayout.

     

а также

 ArrayAdapter adapter = new ArrayAdapter(this, R.layout.multiline_spinner_dropdown_item,R.id.multiline_spinner_text_view, awasomeListValues); 

Это решение работает в обоих режимах spinner: MODE_DROPDOWN и MODE_DROPDOWN. Надеюсь, это поможет вам!

Я думаю, что есть ошибка на Android. Вы можете попробовать это. Удалите пробелы из текста, а затем отобразите, что он будет работать нормально. Если длина текстового представления <строка, она игнорирует все символы после пробела. Для работы вы можете попробовать следующее:

добавьте файл в папку res / layout с именем multiline_spinner_dropdown_item.xml с образцом кода:

  

и когда вы создаете spinner, создайте его из этого макета.

Что-то вроде :

 ArrayAdapter.createFromResource(this, items, R.layout.multiline_spinner_dropdown_item); 

В принципе, скопируйте макет android.R.layout.simple_spinner_dropdown_item в проект и измените макет, установив атрибут singleLine в false в CheckedTextView.

Чтение этого ответа: ошибка кадрирования textview: – android.widget.LinearLayout не может быть отброшен в android.widget.TextView и этот раздел, я мог бы решить эту проблему: нам нужно, чтобы LinearLayout обертывал TextView (текст Spinner), чтобы избежать получения текста с экрана, но у нас возникнут некоторые проблемы. Для начала создайте макет ( я назвал его spinner_dd_item.xml ):

     

Следующий шаг – создание экземпляра ArrayAdapter для установки его на счетчик:

  ArrayAdapter arrayAdapter = new ArrayAdapter(getActivity(), R.layout.spinner_dd_item, R.id.simple_spinner_dropdown, hashmapToString(hashMap, keys)) { @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { return getView(position, convertView, parent); } }; spinner.setAdapter(arrayAdapter); 

Не забудьте добавить имя макета и идентификатор TextView в ArrayAdapter, потому что мы добавили LinearLayout, и нам нужно указать TextView и переопределить getDropDownView, чтобы получить представление, которое отображает данные в указанной позиции в наборе данных. Теперь мы видим, как spinner работает хорошо на более старых и старых версиях Android

У меня была такая же проблема и я нашел решение.

Я хотел, чтобы текст был завершен на начальном экране и в раскрывающемся списке.

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

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

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

  import org.holoeverywhere.widget.Spinner; ArrayAdapter adapter1 = ArrayAdapter.createFromResource(this,R.array.array_of_strings,R.layout.simple_list_item_1); adapter1.setDropDownViewResource(R.layout.my_simple_list_item_1); spQ1.setAdapter(adapter1); 

в этом примере simple_list_item является представлением по умолчанию, предоставленным android, а my_simple_list_item –

    

Теперь текст обертывается внутри раскрывающегося списка прядильщика И в выбранном списке прядильщиков.

Просто заверните TextView с LinearLayout :

    
 ArrayAdapter specAdapter = ArrayAdapter.createFromResource( getActivity().getBaseContext(), aa[position], android.R.layout.select_dialog_item); specAdapter.setDropDownViewResource(android.R.layout.select_dialog_item); 

Вот что я сделал, чтобы заставить его работать:

 ArrayAdapter adapter = new ArrayAdapter<>(getContext(), R.layout.simple_dropdown_item_multiline, R.id.nameTextView, choices); 

И это содержание «simple_dropdown_item_multiline»:

    

я только что нашел, что у андроида есть существующий стиль для этого случая

 final Spinner pelanggaran = (Spinner) findViewById(R.id.pelanggaran); ArrayAdapter pelanggaran_adapter = ArrayAdapter.createFromResource(this,R.array.pelanggaran_array, android.R.layout.simple_expandable_list_item_1); pelanggaran_adapter.setDropDownViewResource(android.R.layout.simple_expandable_list_item_1); pelanggaran.setAdapter(pelanggaran_adapter); 

надеюсь, что он решил вашу проблему.

Я разрешил эту проблему, добавив в текст \ n (новая строка) (как это просто).

 sedentary (little or no exercise) lightly active (light exercise/\nsports 1-3 days/week) moderately active (moderate exercise/\nsports 3-5 days/week) very active (hard exercise/\nsports 6-7 days a week) extra active (very hard exercise/sports &\nphysical job or 2x training) 

Выглядит так:

введите описание изображения здесь

И это макет, который spinner использует как строку:

   
  • Как получить значение Spinner?
  • Изменение цвета текста выбранного элемента в прядильщике
  • Как создать прядильщик Android без треугольника в правой части виджета
  • Как программно настроить шрифт для шрифтов Spinner?
  • Нежелательные вызовы onItemSelected
  • Как установить стрелку вниз в spinner?
  • Как изменить дизайн фона плеера и цвет для андроида?
  • Хороший эквивалент NumericUpDown в WPF?
  • Как получить значение выделенного элемента Spinner для строки?
  • Android Spinner с несколькими вариантами выбора
  • Multi-spinner в android без AlertDialog
  • Давайте будем гением компьютера.