Использование скрытого TextView для отображения всплывающего сообщения
Это решение включает в себя добавление дополнительного скрытого текстового поля чуть ниже счетчика в нужном месте, чтобы разрешить отображение диалогового окна ошибки 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);
}
}
В приведенной выше функции SetError
есть дополнительный код, который вызывает дрожание текста в Spinner при установке ошибки. Это не обязательно, чтобы решение работало, но является хорошим дополнением. Посмотрите здесь, чтобы узнать об этом подходе.
Престижность @Gábor за его решение, которое использует TextView в макете элемента Spinner XML. Код View view = spnMySpinner.getSelectedView();
(на основе решения @Gábor) необходим, потому что он получает отображаемый в данный момент TextView, а не использует findViewById
, который просто получит первый TextView в списке (на основе предоставленного идентификатора ресурса) и, следовательно, не будет работать (отображать красную (!) иконку, если не выбран самый первый элемент в списке.
person
CJBS
schedule
29.04.2015