为Spinner创建setError()

Sam*_*gal 46 android spinner

你如何创建setError()(类似于a 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);
Run Code Online (Sandbox Code Playgroud)

setError 方法:

    public void setError(String str) {
        if (tv != null)
            tv.setError(str);
        if(tv2!=null)
            tv2.setError(str);
        if (ctv != null)
            ctv.setError(str);
    }
Run Code Online (Sandbox Code Playgroud)

Edm*_*g99 41

与@Gábor的解决方案类似,但我不需要创建自己的适配器.我只是在我的验证函数中调用以下代码(即单击提交按钮)

        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
Run Code Online (Sandbox Code Playgroud)

  • @John我将android.widget.Spinner保存为onCreateView方法中的实例变量,然后通过另一个方法(在我的情况下为onDoneAction方法)再次访问它。确保在实际选择微调器中的某个项目后调用getSelectedView,即getSelectedItem()也返回非null (2认同)

Gáb*_*bor 20

我有一个解决方案,不涉及创建额外的编辑字段,但你需要自己SpinnerAdapter,像往常一样.

确保您TextView在适配器中使用的布局中至少有一个getView()(无论如何通常都有).

将以下函数添加到适配器(更改name为您的ID TextView):

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

以setError()这种方式从您的代码中调用:

YourAdapter adapter = (YourAdapter)spinner.getAdapter();
View view = spinner.getSelectedView();
adapter.setError(view, getActivity().getString(R.string.error_message));
Run Code Online (Sandbox Code Playgroud)

基本上,与任何其他控件一样,只有您在适配器上调用它,并且您还必须提供视图.

这将在微调器上显示错误图标,就像其他控件一样.


CJB*_*JBS 11

使用隐藏的TextView来显示弹出消息

此解决方案涉及在微调器正下方添加一个额外的隐藏文本框,以允许显示TextView的错误对话框,同时还使用微调器布局XML上的TextView设置允许显示红色(!)图标.因此实际上,使用了两个文本视图 - 一个用于图标,另一个用于隐藏一个文本视图以允许错误对话框.

这是不处于错误状态(使用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>
Run Code Online (Sandbox Code Playgroud)

注意:@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在SetError上面的函数中,示例中有一些额外的代码会导致Spinner中的文本在设置错误时抖动.这不是使解决方案工作所必需的,但是是一个很好的补充.请参阅此处获取此方法的灵感.

感谢@Gábor提供的解决方案,该解决方案利用了Spinner项目布局XML上的TextView.代码View view = spnMySpinner.getSelectedView();(基于@Gábor的解决方案)是必要的,因为它获取当前显示的TextView,而不是使用a findViewById,它只会获得列表中的第一个TextView(基于提供的资源ID),因此不起作用(如果未选择列表中的第一个项目,则显示红色(!)图标.


Jar*_*ard 7

这可以在不使用自定义布局或适配器的情况下完成.

((TextView)spinner.getChildAt(0)).setError("Message");
Run Code Online (Sandbox Code Playgroud)

这种方法的唯一缺点是,当点击图标时,带有错误文本的小弹出窗口将不会显示.


小智 5

我建议你EditText在你的微调器后面放一个空的.

在xml上设置 EditText

android:enabled="false"
    android:inputType="none"
Run Code Online (Sandbox Code Playgroud)

现在,当您想要为您的微调器设置错误时,只需将该错误设置为EditText.

切记不要将其设置EditText为invisibille/ gone.它不会那样工作.

另请注意,通过此方法,您可以准确确定要显示错误的位置.

  • 将EditText放在Spinner后面的一个限制是错误检查行为的某些部分被破坏了.虽然显示错误的红色感叹号显示,但单击感叹号将不会显示带有错误消息的弹出窗口,就像通常那样. (3认同)

Yur*_*ury 0

我猜想 Spinner 不是放置此方法的正确位置。如果使用微调器,您应该选择一个值,并且微调器中的值应根据适配器的级别进行过滤。因此,用户只能选择微调器中的那些值。

  • 我同意,但在 0 个项目是“选择..”的情况下,如果用户选择保留在索引 0 上,则可能需要 setError (3认同)