如何为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);
}
答案 0 :(得分:39)
与@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
答案 1 :(得分:20)
我有一个解决方案并不涉及创建额外的编辑字段,但您需要照常使用自己的SpinnerAdapter
。
确保您在适配器TextView
中使用的布局中至少有一个getView()
(无论如何,您通常都会这样做。)
将以下功能添加到您的适配器(将name
更改为TextView
的ID):
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));
基本上,与任何其他控件一样,只有您在适配器上调用它,并且您还必须提供视图。
这将在微调器上显示错误图标,就像其他控件一样。
答案 2 :(得分:6)
这可以在不使用自定义布局或适配器的情况下完成。
((TextView)spinner.getChildAt(0)).setError("Message");
此方法的唯一缺点是,当点击图标时,带有错误文本的小弹出窗口将不会显示。
答案 3 :(得分:5)
我建议你在你的微调器后面放一个空的EditText
。
在EditText
android:enabled="false"
android:inputType="none"
现在,当您想为您的微调器设置错误时,只需将该错误设置为EditText
。
切记不要将EditText
设置为invisibille
/ gone
。它不会那样工作。
另请注意,通过此方法,您可以准确确定错误的显示位置。
答案 4 :(得分:1)
感谢Gabor提供的出色解决方案。为了促进你的观点,我的解决方案是:
自定义适配器
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);
}
}
}
使用适配器进行Spinner
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;
}
}
答案 5 :(得分:0)
我猜Spinner不适合放这种方法。如果是Spinner,你应该选择一个值,并且应该在适配器的级别上过滤Spinner中的值。因此,用户只能选择Spinner中的那些值。
答案 6 :(得分:0)
您可以创建自己的适配器(扩展BaseAdapter实现SpinnerAdapter)。这样,您就可以访问微调器中显示的TextView。 (getView和createViewFromResource方法 - 示例:ArrayAdapter)当您添加一个空列表项以允许用户将该字段保持为空(直到它成为必需项)(微调器中的第一项)时,您可以将其TextView存储为私有适配器中的成员。然后,当需要从Activity或Fragment调用setError(“...”)时,可以在可以将其传递给空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");
}
}
答案 7 :(得分:0)
实际上就是这样,您只需要在视图中只有一个import collections, re
fields = {'productId':'Product ID', 'score':'Rating',
'helpfulness':'Number Voting', 'text':'Review'}
pattern = r'/([^:]*):\s?(.*)'
kv = re.compile(pattern)
data = collections.defaultdict(list)
with open('file.txt') as f:
reviews = f.read()
for match in kv.finditer(reviews):
key, value = match.groups()
if key in fields:
data[fields[key]].append(value)
df = pd.DataFrame.from_dict(data)
,然后如果所选视图中的主视图为{TextView
,则使用getSelectedView()
从您的微调器中获取所选视图{1}}然后将您的视图直接投放到TextView
和TextView
,如下所示:
setError
否则,如果Textview不是直接在主视图中,那么您需要通过ID找到它并再次投射它并((TextView) jobCategory.getSelectedView()).setError("Field Required");
这样:
setError