Spinner не переносит текст-это ошибка Android?
если текст a Spinner
элемент слишком длинный, чтобы поместиться в одну строку, текст не завернут, но отрезан. Это только в случае уровень API >= 11. Вот скриншоты Android 4.2.2 (слева), который показывает неправильное поведение и Android 2.3.3 (справа), где это выглядит так, как ожидалось.
android:singleLine="false"
просто игнорируется здесь. Так как все остальные пробует вроде android:lines
,android:minLines
и т. д. Этот TextView
как-то кажется, гораздо шире, чем ширина окна.
я видел других людей, имеющих ту же проблему, но никто не мог найти решение. Итак, это системная ошибка? Я не думаю, что это несоответствие между версиями ОС может быть предназначено.
обратите внимание:
были некоторые ответы, предлагающие относительно простые решения.
написание на заказ
Adapter
и переопределитьgetView()
а такжеgetDropDownView()
. Это не решение здесь, потому что на данный момент все еще существует исходная проблема: как макет должен выглядеть, чтобы обрабатывать правильную обертку линии?упаковка
TextView
из выпадающего представления в родительViewGroup
. Не работает сandroid:layout_width="match_parent"
потому что ширина родителя странно кажется неограниченной.придание выпадающему виду фиксированной ширины. Это не подходит с различной шириной
Spinner
можете иметь.и, конечно же, нет решения вручную вставить
n
s в любом месте текста.
воспроизвести с помощью следующего кода:
обновление: я также загрузил это в качестве примера проекта на GitHub:скачать
/res/значения / массивы.XML-код:
<string-array name="items">
<item>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.</item>
<item>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est.</item>
</string-array>
/res / layout / spinner_item.XML-код:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="none"
android:minHeight="?android:attr/listPreferredItemHeight"
android:singleLine="false" />
Set Adapter
:
spinner.setAdapter(ArrayAdapter.createFromResource(this,
R.array.items,
R.layout.spinner_item));
14 ответов:
в holo theme spinner по умолчанию используется выпадающий режим. И все движения с переопределением стилей по умолчанию просто переходят в режим переключения spinner в диалоговый режим, который успешно обертывает многострочный текст, как в api 11. Вместо этого вы можете создать счетчик с
new Spinner(context, Spinner.MODE_DIALOG)
или в xml:android:spinnerMode="dialog"
. Но это не решить проблему, потому что это диалог, а не выпадающий список.Я нашел другое решение этой проблемы: переопределить
getDropDownView
методArrayAdapter
и поставитьsetSingleLine(false)
в методе представления 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 на кнопку и спрятать его на listitem элемент щелчком мыши.
простая реализация, чтобы показать идею:
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<String> list = new ArrayList<String>(); 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<String>(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); } }); } }
Я решил эту проблему, переключившись на диалоговый стиль spinner:
<Spinner ... android:spinnerMode="dialog" />
только комбинация решений здесь работала для меня (проверено на Android 5.1 тоже):
spinner_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@android:id/text1" style="?android:attr/spinnerItemStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="false" android:textAlignment="inherit"/> </LinearLayout>
код
final ArrayAdapter<String> spinnerArrayAdapter=new ArrayAdapter<String>(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
. Это позволит использовать многострочные выпадающие элементы.- стиль спиннер "вручную", так что это выглядит как
Holo
-тематические.это производит (показ закрыто и открыто государства):
детали реализации:
нет никакого способа наследовать от
Holo
наSpinner
и показать несколько строкSpinner
выпадающий элемент, насколько я могу судить, даже если мы установим выпадающий элементTextView
доfalse
и поставьте изготовленный на заказ план. Я также попытался сохранитьHolo
стиль, но измененияandroid:spinnerStyle android:spinnerItemStyle android:spinnerDropDownItemStyle
атрибуты стилей (пример использования этих атрибутов здесь) но я не мог заставить его произвести многострочный результат.
однако, если мы переопределим стиль для
Spinner
и не наследуютspinnerStyle
СHolo
:<style name="AppTheme" parent="android:Theme.Holo.Light"> <item name="android:spinnerStyle">@style/spinnerStyle</item> </style> <--no parent attribute--> <style name="spinnerStyle"> <item name="android:clickable">true</item> </style>
тогда выпадающий элемент будет поддерживать отображение нескольких строк. Но теперь мы потеряли
Holo
наSpinner
и закрытое состояние выглядит какTextView
не aSpinner
без стрелки или визуальной подсказки этоSpinner
. Если мы вместо этого установимspinnerStyle
родитель:parent="android:style/Widget.Spinner
:<style name="spinnerStyle" parent="android:style/Widget.Spinner"> <item name="android:clickable">true</item> </style>
the
Spinner
закрытое состояние покажет стрелку, но будет стилизован как серый pre-HoloSpinner
который выглядит неуместно вHolo
приложение.Итак, возможное решение тут:
- переопределить тему для
spinnerStyle
и не использоватьHolo
для родителей. это позволит многострочный текст в выпадающих пунктов.- изменить
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)); }
активность планировка:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="50dip" tools:context=".MainActivity" > <Spinner android:id="@+id/styled_spinner" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
стили:
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <style name="AppTheme" parent="android:Theme.Holo.Light"> <item name="android:spinnerStyle">@style/spinnerStyle</item> </style> <style name="spinnerStyle"> <item name="android:clickable">true</item> <item name="android:background">@drawable/spinner_background_holo_light</item> </style> </resources>
в папке drawable поместите spinner_background_holo_light:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:drawable="@drawable/spinner_disabled_holo_light" /> <item android:state_pressed="true" android:drawable="@drawable/spinner_pressed_holo_light" /> <item android:state_pressed="false" android:state_focused="true" android:drawable="@drawable/spinner_focused_holo_light" /> <item android:drawable="@drawable/spinner_default_holo_light" /> </selector>
и включите эти чертежи в свой :
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
тематические закрытом состоянии и многострочные элементы, как показано на скриншотах выше.выпадающие элементы в этом примере не
Holo
-тематический, но, возможно, это приемлемый компромисс, если многострочное отображение выпадающих элементов действительно важный.в этом примере
android:minSdkVersion
был установлен до14
иandroid:targetSdkVersion
до17
в Манифесте.
Holo
графика иspinner_background_holo_light.xml
код пришел из HoloEverywhere Copyright (c) 2012 Christophe Versieux, Сергей Шатунов. См. раздел Связанные с проектом github сведения о лицензии.
добавление LinearLayout вокруг TextView позволяет тексту правильно обернуть.
макет (common_domainreferencemodel_spinner_item.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:layout_width="match_parent" android:padding="4dp"> <TextView android:id="@+id/nameTextView" android:singleLine="false" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
адаптер:
public class DomainReferenceModelAdapter extends ArrayAdapter<DomainReferenceModel> { private List<DomainReferenceModel> objects; private LayoutInflater inflater; private int oddRowColor = Color.parseColor("#E7E3D1"); private int evenRowColor = Color.parseColor("#F8F6E9"); public DomainReferenceModelAdapter(Context context, int resource, List<DomainReferenceModel> 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"
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/multiline_spinner_text_view" android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" 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.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" > <CheckedTextView android:id="@+id/multiline_spinner_text_view" android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:singleLine="false" /> </LinearLayout>
и
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.multiline_spinner_dropdown_item,R.id.multiline_spinner_text_view, awasomeListValues);
это решение работает в обоих режимах spinner: MODE_DROPDOWN и MODE_DROPDOWN.Надеюсь, это поможет вам!
Я думаю, что есть ошибка на Android. Ты можешь попробовать это. Удалите пробелы из текста, а затем отобразить его будет работать нормально. Если длина textview
добавьте файл в папку res/layout с именем multiline_spinner_dropdown_item.xml с примером кода:
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android" style="?android:attr/spinnerDropDownItemStyle" android:singleLine="false" android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:ellipsize="marquee" />
и когда вы создаете спиннер, создайте его из этого макет.
что-то типа :
ArrayAdapter.createFromResource(this, items, R.layout.multiline_spinner_dropdown_item);
в основном, скопируйте android.R. макет.simple_spinner_dropdown_item макет в проект и изменить макет, установив атрибут singleLine значение false в CheckedTextView.
читать этот ответ: ошибка приведения textview: - android.штучка.LinearLayout не может быть приведен к android.штучка.TextView и в этой теме я мог бы решить эту проблему: нам нужен LinearLayout, обертывающий TextView (текст spinner), чтобы избежать выхода текста с экрана, но у нас будут некоторые проблемы для решения. Для начала создайте макет (я назвал его spinner_dd_item.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/simple_spinner_dropdown" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="5dp" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="5dp" android:textColor="@color/colorAccent" tools:text="Hello" /> </LinearLayout>
следующим шагом является создание экземпляра ArrayAdapter для установите его на счетчик:
ArrayAdapter<CharSequence> arrayAdapter = new ArrayAdapter<CharSequence>(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
Я только что обнаружил, что android имеет существующий стиль для этого случая
final Spinner pelanggaran = (Spinner) findViewById(R.id.pelanggaran); ArrayAdapter<CharSequence> 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);
надеюсь, что это решило вашу проблему.
у меня была такая же проблема, и я нашел решение.
Я хотел, чтобы текст был обернут в начальный дисплей и в раскрывающемся списке.
текст был обернут в начальный дисплей, и для выпадающего списка я нашел другое решение, рекомендующее использовать пользовательский вид линейного макета с фиксированной шириной, охватывающей textview. Это сделало выпадающий список блесны выглядеть правильно, а также что из первоначального выбора. Однако это вызвало серьезную проблему на старое устройство.
начальный дисплей не будет обновляться, и текст будет выглядеть сложенным, если я попытаюсь выбрать что-то еще. и поскольку он укладывался вниз, добавление фона не помогло.
как оказалось, адаптеры имеют метод setDropDownViewResource (), который позволяет установить другое представление для выпадающего списка, чем то, что отображается в первоначальном выборе spinner.
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-это
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="300dp" android:layout_height="wrap_content" > <TextView android:id="@+id/android:text1" android:layout_width="wrap_content" android:layout_height="50dp" android:ellipsize="marquee" android:layout_gravity="center_vertical" android:singleLine="false"/> </LinearLayout>
теперь текст обертывается внутри раскрывающегося списка блесны и в отображаемом выборе блесны.
просто обернуть
TextView
СLinearLayout
:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
ArrayAdapter<?> specAdapter = ArrayAdapter.createFromResource( getActivity().getBaseContext(), aa[position], android.R.layout.select_dialog_item); specAdapter.setDropDownViewResource(android.R.layout.select_dialog_item);
вот что я сделал, чтобы заставить его работать:
ArrayAdapter<KeyValue> adapter = new ArrayAdapter<>(getContext(), R.layout.simple_dropdown_item_multiline, R.id.nameTextView, choices);
и это содержание "simple_dropdown_item_multiline":
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/nameTextView" style="?android:attr/dropDownItemStyle" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="marquee" android:paddingBottom="@dimen/large" android:paddingTop="@dimen/large" android:singleLine="false" android:textAppearance="?android:attr/textAppearanceLargePopupMenu"/>
Я решил эту проблему, добавив \n (новая строка) в текст (так просто).
<string name="bmr1">sedentary (little or no exercise)</string> <string name="bmr2">lightly active (light exercise/\nsports 1-3 days/week)</string> <string name="bmr3">moderately active (moderate exercise/\nsports 3-5 days/week)</string> <string name="bmr4">very active (hard exercise/\nsports 6-7 days a week)</string> <string name="bmr5">extra active (very hard exercise/sports &\nphysical job or 2x training)</string>
выглядит так:
и это макет, который счетчик использует в качестве строки:
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/default_listview_row" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="false" android:gravity="center_vertical" android:textColor="@android:color/white" android:background="@android:color/transparent" android:padding="5dp" />