Создание setError () для Spinner

Как вы создаетеsetError() (аналогичноTextView/EditText) функция дляSpinner? Следующее не работает:

Я попытался расширить класс Spinner и в конструкторе:

ArrayAdapter<String> aa = new ArrayAdapter<String>(getContext(),
                    android.R.layout.simple_spinner_item, android.R.id.text1,
                    items);
            aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            setAdapter(aa);
             tv = (TextView) findViewById(android.R.id.text1);
            // types_layout_list_tv

            ctv = (CheckedTextView) aa.getDropDownView(1, null, null);
            tv2 = (TextView) aa.getView(1, null, null);

setError метод:

    public void setError(String str) {
        if (tv != null)
            tv.setError(str);
        if(tv2!=null)
            tv2.setError(str);
        if (ctv != null)
            ctv.setError(str);
    }
 Code_Life06 февр. 2012 г., 14:04
У тебя есть решение для этого? \ Похоже на решение @ Gábor, но мне не нужно было создавать собственный адаптер. Я просто вызываю следующий код в моей функции проверки (т.е. при нажатии кнопки отправки)
 Ready4Android18 сент. 2011 г., 11:16
Что меня озадачивает в вашем примере: откуда взялись телевизоры TextView, ctv и tv2 и что они должны делать с вертушкой? Привет, Ready4Android

Ответы на вопрос(9)

Это решение включает в себя добавление дополнительного скрытого текстового поля чуть ниже вращающегося элемента в правильном положении, чтобы позволить отображать диалоговое окно с ошибкой TextView, а также использование TextView, установленного в XML-макете счетчика, для отображения красного (!) Значка. Таким образом, в действительности используются два текстовых представления - одно для значка, а другое (скрытое) для разрешения диалога об ошибке.

):SetError(null)Вот как это выглядит, когда есть ошибка (используйте

):SetError("my error text, ideally from a resource!")Вот выдержка из макета блесны XML. Существует RelativeLayout, который используется для того, чтобы TextView был как можно ближе к счетчику, и имеет достаточно paddingRight, чтобы стрелка в диалоговом окне сообщения была выровнена под красным значком ошибки (!). Скрытый (поддельный) TextView позиционируется относительно Spinner.

Замечания:

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="top|left"
        >

        <Spinner
            android:id="@+id/spnMySpinner"
            android:layout_width="400dp"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:dropDownSelector="@drawable/selector_listview"
            android:background="@android:drawable/btn_dropdown"
            android:paddingBottom="0dp"
            android:layout_marginBottom="0dp"
            />

        <!-- Fake TextView to use to set in an error state to allow an error to be shown for the TextView -->
        <android.widget.TextView
            android:id="@+id/tvInvisibleError"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_alignRight="@+id/spnMySpinner"
            android:layout_alignBottom="@+id/spnMySpinner"
            android:layout_marginTop="0dp"
            android:paddingTop="0dp"
            android:paddingRight="50dp"
            android:focusable="true"
            android:focusableInTouchMode="true"
            />

    </RelativeLayout>

 определены за пределами этого решения.@drawable/selector_listviewСмотрите пример здесь о том, как заставить это работать, так как это не по теме для этого ответа.Вот код, чтобы заставить его работать. Просто позвони

 либо сSetError(errMsg) чтобы удалить ошибку, или с текстом, чтобы установить его в состояние ошибки.nullв

/**
 * When a <code>errorMessage</code> is specified, pops up an error window with the message
 * text, and creates an error icon in the secondary unit spinner. Error cleared through passing
 * in a null string.
 * @param errorMessage Error message to display, or null to clear.
 */
public void SetError(String errorMessage)
{
    View view = spnMySpinner.getSelectedView();

    // Set TextView in Secondary Unit spinner to be in error so that red (!) icon
    // appears, and then shake control if in error
    TextView tvListItem = (TextView)view;

    // Set fake TextView to be in error so that the error message appears
    TextView tvInvisibleError = (TextView)findViewById(R.id.tvInvisibleError);

    // Shake and set error if in error state, otherwise clear error
    if(errorMessage != null)
    {
        tvListItem.setError(errorMessage);
        tvListItem.requestFocus();

        // Shake the spinner to highlight that current selection 
        // is invalid -- SEE COMMENT BELOW
        Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
        spnMySpinner.startAnimation(shake);

        tvInvisibleError.requestFocus();
        tvInvisibleError.setError(errorMessage);
    }
    else
    {
        tvListItem.setError(null);
        tvInvisibleError.setError(null);
    }
}

 Функция выше, например, есть некоторый дополнительный код, который заставляет текст в Spinner дрожать, когда установлена ​​ошибка. Это не обязательно, чтобы решение работало, но это хорошее дополнение.SetErrorПосмотреть здесь для вдохновения для этого подхода.Слава @ Габору для

его решение который использует TextView в XML макета элемента Spinner. Код (на основе решения @ Gábor) необходимо, поскольку он получает отображаемый в данный момент TextView, а не используетView view = spnMySpinner.getSelectedView();, который просто получит первый TextView в списке (на основе предоставленного идентификатора ресурса) и, следовательно, не будет работать (отображать красный (!) значок), если не выбран самый первый элемент в списке.findViewByIdВ этой части у меня есть линейное расположение, какие-нибудь подсказки? TextView tvListItem = (TextView) представление;

 vinicius gati01 июн. 2018 г., 21:17
Это можно сделать без использования пользовательского макета или адаптера.

что небольшое всплывающее окно с текстом ошибки не будет отображаться при нажатии на значок.

((TextView)spinner.getChildAt(0)).setError("Message");

Не работал для меня. Единственный способ это пользовательский адаптер

 Sasha19 мар. 2015 г., 12:47
Вероятно, работает только на непустых спиннеров
 mathias.horn15 сент. 2017 г., 21:18
Я бы предложил вам поставить пустой

Используйте адаптер для Spinner

    public class RequiredSpinnerAdapter<T> extends ArrayAdapter<T> {
        public RequiredSpinnerAdapter(Context context, int textViewResourceId,
                                      java.util.List<T> objects) {
            super(context, textViewResourceId, objects);
        }

        int textViewId = 0;

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = super.getView(position, convertView, parent);
            if (view instanceof TextView) {
                textViewId = view.getId();
            }
            return view;
        }

        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            View row = super.getView(position, convertView, parent);
            return (row);
        }

        public void setError(View v, CharSequence s) {
            if(textViewId != 0){
                TextView name = (TextView) v.findViewById(textViewId);
                name.setError(s);
            }
        }
    }

Проверить на валидацию

ArrayAdapter<String> arrayAdapter = new RequiredSpinnerAdapter<String>(PropertyAdd.this, R.layout.checked, status_arr);
    marketstatus_spinner.setAdapter(arrayAdapter);
    marketstatus_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1,
                                   int arg2, long arg3) {

            // Put code here
        }

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

Добавьте один для высказывания "В дальнейшем"! :-)

private boolean checkValidation() {
    if(marketstatus_spinner.getSelectedItem().toString().equals("")){
        RequiredSpinnerAdapter adapter = (RequiredSpinnerAdapter)marketstatus_spinner.getAdapter();
        View view = marketstatus_spinner.getSelectedView();
        adapter.setError(view, "Please select a value");

        return false;
    }
}
 ban-geoengineering08 июл. 2015 г., 12:50
Я думаю, что Спиннер не то место, где можно поставить этот метод. В случае Spinner вы должны выбрать одно значение и чтобы значения в Spinner были отфильтрованы на уровне вашего адаптера. Таким образом, пользователь может выбирать только те значения, которые есть в Spinner.

  а затем получить выбранный вид с вашего счетчика, используяTextView если основной вид в выбранном вами виде являетсяgetSelectedView() затем прямо бросьте свой взгляд наTextView а такжеTextView как это :setErrorИначе, если Textview не является непосредственно MAIN View, вам нужно найти его по идентификатору и снова разыграть и

((TextView) jobCategory.getSelectedView()).setError("Field Required");

 сюда :setErrorСоздание setError () для Spinner

 ((TextView) jobCategory.getSelectedView().findViewById(R.id.firstName)).setError("Field Required");

ArrayAdapter) Когда вы добавляете пустой элемент списка, чтобы позволить пользователю оставлять поле пустым до тех пор, пока оно не станет обязательным (первый элемент в счетчике), вы можете сохранить его TextView как закрытый элемент в адаптере. Затем, когда приходит время вызвать setError ("...") из Activity или Fragment, вы можете вызвать его на адаптере, который может передать его в пустой TextView.В аналогичном случае (как ваш пример) у меня только значок без текстовой ошибки

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return createViewFromResource(position, convertView, parent, mTextViewId);
}

private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {
    View view;
    TextView text;

    if (convertView == null) {
        view = inflater.inflate(resource, parent, false);
    } else {
        view = convertView;
    }

    try {
        text = (TextView) view;
    } catch (ClassCastException e) {
        Log.e(TAG, "You must supply a resource ID for a TextView", e);
        throw new IllegalStateException("MyAdapter requires the resource ID to be a TextView", e);
    }

    MyItem i = getItem(position);
    String s = (null != i) ? i.toString() : "";
    text.setText(s);

    if ("".equals(s) && null == mEmptyText) {
        this.mEmptyText = text;
    }

    return view;
}

public void setError(String errorMessage) {
    if (null != mEmptyText) {
        mEmptyText.setError(errorMessage);
    } else {
        Log.d(TAG, "mEmptyText is null");
    }
}
 Bojan16 окт. 2013 г., 12:45
На самом деле это очень, вам просто нужно иметь только один
 Helpa02 мая 2013 г., 17:30
тоже самое. Есть ли способ вывести текст с ошибкой?

SpinnerAdapterУбедитесь, что у вас есть хотя бы один

 в макете вы используете в своем адаптереTextView (у вас, как правило, это так или иначе).getView()Добавьте следующую функцию в ваш адаптер (изменить

 к идентификатору вашегоname):TextViewПозвоните

public void setError(View v, CharSequence s) {
  TextView name = (TextView) v.findViewById(R.id.name);
  name.setError(s);
}

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

YourAdapter adapter = (YourAdapter)spinner.getAdapter();
View view = spinner.getSelectedView();
adapter.setError(view, getActivity().getString(R.string.error_message));

Это отобразит значок ошибки на счетчике, как в случае с другими элементами управления.

Это отличное решение

 EladHackim27 дек. 2014 г., 15:30
Когда width = wrap_content, значок ошибки отображается неправильно - скрыт под значком счетчика
 Wooff27 июл. 2015 г., 10:28
Использование скрытого TextView для отображения всплывающего сообщения

 EditTextНа xml установить, что

Теперь, когда вы хотите установить ошибку для вашего счетчика, просто установите эту ошибку наEditText

android:enabled="false"
    android:inputType="none"

Помните, чтобы не устанавливать этоEditText.

 вEditText, Это не сработает.invisibille / goneТакже обратите внимание, что с помощью этого метода вы можете решить, где именно вы хотите, чтобы ваша ошибка появилась.

Одно ограничение с размещением EditText позади Spinner состоит в том, что части поведения проверки на ошибки нарушены. Хотя отображается красный восклицательный знак, указывающий на ошибку, при нажатии на восклицательный знак не будет отображаться всплывающее окно с сообщением об ошибке, как это обычно бывает.

 Theo23 июл. 2014 г., 18:25
Спасибо Габор за ваше фантастическое решение. В поддержку вашей точки зрения мое решение таково:

оба возвращают нуль в getSelectedView () за исключением того, что решение выглядело лучше

        TextView errorText = (TextView)mySpinner.getSelectedView();                  
        errorText.setError("anything here, just to add the icon");
        errorText.setTextColor(Color.RED);//just to highlight that this is an error
        errorText.setText("my actual error text");//changes the selected item text to this
 EdmundYeung9906 янв. 2015 г., 15:30
отличный ответ! выбранный вид это на самом деле TextView, так что это будет работать как ожидалось!
 Ryan Amaral24 июл. 2015 г., 17:29
У меня есть решение, которое не требует создания дополнительного поля для редактирования, но вам нужно ваше собственное
 John17 дек. 2014 г., 21:59
@John Я сохранил свой android.widget.Spinner как переменную экземпляра в методе onCreateView, а затем снова получил доступ к нему в другом методе, в моем случае - метод onDoneAction. Обязательно вызывайте getSelectedView после того, как элемент в счетчике фактически выбран, то есть getSelectedItem () также возвращает ненулевое значение

Select ..", который возможен там, setRrror был бы необходим, если выбор пользователя остается в индексе 0

 Bojan16 окт. 2013 г., 12:49
Вы можете создать свой собственный адаптер (расширяет BaseAdapter, реализует SpinnerAdapter). Таким образом, вы можете получить доступ к TextViews, которые отображаются в счетчике. (методы getView и createViewFromResource - пример:

Ваш ответ на вопрос