akvo / akvo-flow-mobile

Akvo Flow app
GNU General Public License v3.0
18 stars 16 forks source link

Error view crash #285

Closed ichinaski closed 9 years ago

ichinaski commented 9 years ago

Upon error view display (i.e. mandatory response skipped), a very subtle focusability error can happen. Since the QuestionGroupTab requests the focus each time the scroll state has changed, this can potentially cause an IllegalStateException in the error popup, if this view has just been instantiated and hasn't been attached to the window manager yet.

There are two things to consider here: 1) The QuestionGroupTab should not claim the focus on each scroll interaction, and 2) the keyboard input mode, currently set to adjustPan, should be changed to adjustResize, which handles the space better, leaving all UI elements accessible.

The main UX change this fix will involve is the removal of implicit focus changes, which has proven to be something rather complicated to manage automatically (and probably not necessary).

Relevant stack trace:

java.lang.IllegalArgumentException: View not attached to window manager at
android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:655) at
android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:364) at
android.view.WindowManagerImpl$CompatModeWrapper.removeViewImmediate(WindowManagerImpl.java:172) at
android.widget.PopupWindow.dismiss(PopupWindow.java:1256) at
android.widget.Editor.hideError(Editor.java:330) at
android.widget.Editor.onFocusChanged(Editor.java:892) at
android.widget.TextView.onFocusChanged(TextView.java:7316) at
android.view.View.unFocus(View.java:4380) at
android.view.ViewGroup.unFocus(ViewGroup.java:791) at
android.view.ViewGroup.unFocus(ViewGroup.java:791) at
android.view.ViewGroup.handleFocusGainInternal(ViewGroup.java:561) at
android.view.View.requestFocusNoSearch(View.java:6490) at
android.view.View.requestFocus(View.java:6469) at
android.view.ViewGroup.requestFocus(ViewGroup.java:2409) at
android.view.View.requestFocus(View.java:6436) at
android.view.View.requestFocus(View.java:6415) at
org.akvo.flow.ui.view.QuestionGroupTab.onScrollChanged(QuestionGroupTab.java:117) at
android.view.View.scrollTo(View.java:9967) at
android.widget.ScrollView.scrollTo(ScrollView.java:1533) at
android.view.View.scrollBy(View.java:9982) at
android.widget.ScrollView.scrollToChildRect(ScrollView.java:1285) at
android.widget.ScrollView.requestChildRectangleOnScreen(ScrollView.java:1413) at
android.view.View.requestRectangleOnScreen(View.java:4308) at
android.widget.PopupWindow.findDropDownPosition(PopupWindow.java:1122) at
android.widget.PopupWindow.showAsDropDown(PopupWindow.java:890) at
android.widget.Editor.showError(Editor.java:288) at
android.widget.Editor.setError(Editor.java:322) at
android.widget.TextView.setError(TextView.java:4156) at
android.widget.TextView.setError(TextView.java:4141) at
org.akvo.flow.ui.view.FreetextQuestionView.displayError(FreetextQuestionView.java:200) at
org.akvo.flow.ui.view.QuestionView.setError(QuestionView.java:546) at
org.akvo.flow.ui.view.QuestionView.checkMandatory(QuestionView.java:564) at
org.akvo.flow.ui.view.FreetextQuestionView.captureResponse(FreetextQuestionView.java:161) at
org.akvo.flow.ui.view.QuestionView.captureResponse(QuestionView.java:449) at
org.akvo.flow.ui.view.FreetextQuestionView$ResponseListener.afterTextChanged(FreetextQuestionView.java:265) at
android.widget.TextView.sendAfterTextChanged(TextView.java:7115) at
android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:8780) at
android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:970) at
android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:497) at
android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:212) at
android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:30) at
android.view.inputmethod.BaseInputConnection.deleteSurroundingText(BaseInputConnection.java:242) at
com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:382) at
com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77) at
android.os.Handler.dispatchMessage(Handler.java:99) at
android.os.Looper.loop(Looper.java:153) at
android.app.ActivityThread.main(ActivityThread.java:4987) at
java.lang.reflect.Method.invokeNative(Native Method) at
java.lang.reflect.Method.invoke(Method.java:511) at
m.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821) at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584) at
dalvik.system.NativeStart.main(Native Method) View not attached to window manager
ichinaski commented 9 years ago

Test plan: This is admittedly a rather difficult-to-test issue, since it simply involves a configuration change.

rumca commented 9 years ago

The above test plan passes fine - I also used 2.1.5 for the dashboard regression testing round this week and noticed nothing untoward :+1: