我一直在我的Android应用程序中的特定点获得标题中提到的异常。
有一个ListView
包含多个输入控件。我知道这样做可能并不理想,但我无法看到另一种解决方案,因为这样一个非常灵活的部分。一般来说,它的工作效果不错。
第二个列表视图出现错误,一旦点击一个按钮,就会执行验证。验证消息通过其适配器传递给另一个ListView
。然后崩溃发生了。只有在按下按钮的同时显示键盘时才会发生这种情况,尽管我在Button-Press上隐藏了键盘。这似乎工作正常,因为当我在验证期间有一个断点时,不再有键盘可见。
所以可能存在其他种类的竞争条件,导致这种行为。
我了解Preventing/catching "IllegalArgumentException: parameter must be a descendant of this view" error或java.lang.IllegalArgumentException: parameter must be a descendant of this view Error中提及的ScrollListener
和FOCUS_BLOCK_DESCENDANTS
的类似问题和解决方案。但它们似乎并不适用于我的情况。
我还尝试使用简单的TextView
代替ListView
来显示验证消息,但却导致了相同的异常。
我希望有人能解决这个问题的原因。正如在scrollToRectOrFocus
期间发生的那样,如何确定导致问题的ListView?
编辑:请求的代码(虽然我猜不是特别的)
布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/application_background">
<TextView
android:id="@+id/form_title"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:text="Form Title"
android:gravity="center_vertical"
style="@style/TxtLead"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/admin_form_cancel"
android:id="@+id/cancel_button" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/admin_form_save"
android:id="@+id/save_button"
style="@style/BtnPrimary"/>
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/error_list_view"
android:descendantFocusability="blocksDescendants">
</ListView>
</RelativeLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/form_list_view"
style="@style/formListView"
android:descendantFocusability="blocksDescendants" />
<EditText
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/proxy_focus_catcher"
android:inputType="none"/>
</LinearLayout>
片段的一部分
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.form_container, container, false);
formListView = (ListView)view.findViewById(R.id.form_list_view);
formListView.setOnScrollListener(new MyScrollListener());
errorAdapter = new ObjectAdapter<>(getActivity(), R.layout.item_form_error, errors, R.id.error_text);
// Action listeners
(view.findViewById(R.id.save_button)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { save(); }
});
(view.findViewById(R.id.cancel_button)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { cancel(); }
});
((ListView)view.findViewById(R.id.error_list_view)).setAdapter(errorAdapter);
((ListView)view.findViewById(R.id.error_list_view)).setOnScrollListener(new MyScrollListener());
// Proxy input fetcher clears the keyboard at the end
((EditText)view.findViewById(R.id.proxy_focus_catcher)).setInputType(InputType.TYPE_NULL);
view.findViewById(R.id.proxy_focus_catcher).setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
});
return view;
}
/**
* Form saving
*/
private void save() {
clearFocus();
if(!form.isValid(getActivity())) {
FormValidation errors = form.getFormValidation(getActivity());
errorAdapter.setItems(errors.getRowValidationErrorsAsStrings());
return;
}
if(null != listener) {
listener.onFormSave(changesMap);
}
}