ScrollView嵌套ListView导致的错误: java.
2018-06-29 本文已影响9人
酒吞
# main(2)
java.lang.IllegalArgumentException
parameter must be a descendant of this view
1 android.view.ViewGroup.offsetRectBetweenParentAndChild(ViewGroup.java:6153)
2 android.view.ViewGroup.offsetDescendantRectToMyCoords(ViewGroup.java:6075)
3 android.widget.ScrollView.isWithinDeltaOfScreen(ScrollView.java:2043)
4 android.widget.ScrollView.onSizeChanged(ScrollView.java:2542)
5 android.view.View.sizeChange(View.java:20993)
6 android.view.View.setFrame(View.java:20935)
7 android.view.View.layout(View.java:20838)
8 android.view.ViewGroup.layout(ViewGroup.java:6401)
9 android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
10 android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
11 android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
12 android.view.View.layout(View.java:20841)
13 android.view.ViewGroup.layout(ViewGroup.java:6401)
14 android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
15 android.widget.FrameLayout.onLayout(FrameLayout.java:261)
16 android.view.View.layout(View.java:20841)
17 android.view.ViewGroup.layout(ViewGroup.java:6401)
18 android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
19 android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
20 android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
21 android.view.View.layout(View.java:20841)
22 android.view.ViewGroup.layout(ViewGroup.java:6401)
23 android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
24 android.widget.FrameLayout.onLayout(FrameLayout.java:261)
25 android.view.View.layout(View.java:20841)
26 android.view.ViewGroup.layout(ViewGroup.java:6401)
27 android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
28 android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
29 android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
30 android.view.View.layout(View.java:20841)
31 android.view.ViewGroup.layout(ViewGroup.java:6401)
32 android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
33 android.widget.FrameLayout.onLayout(FrameLayout.java:261)
34 com.android.internal.policy.DecorView.onLayout(DecorView.java:944)
35 android.view.View.layout(View.java:20841)
36 android.view.ViewGroup.layout(ViewGroup.java:6401)
37 android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2907)
38 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2594)
39 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1738)
40 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7745)
41 android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
42 android.view.Choreographer.doCallbacks(Choreographer.java:723)
43 android.view.Choreographer.doFrame(Choreographer.java:658)
44 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
45 android.os.Handler.handleCallback(Handler.java:789)
46 android.os.Handler.dispatchMessage(Handler.java:98)
47 android.os.Looper.loop(Looper.java:164)
48 android.app.ActivityThread.main(ActivityThread.java:6940)
49 java.lang.reflect.Method.invoke(Native Method)
50 com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
51 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
公司的表单界面中,是属于ScrollView嵌套ListView,ListView包含EditText的样式。最近突然在bugly中发现三星手机上出现了这个bug,而且只有三星手机才出现。主要操作是,在用startActivityForResult启动新页面后,新页面携带数据返回,finish掉新页面,就导致了崩溃。(后来发展到,跳转新界面后,一弹出输入法就崩溃,同样的exception)
查阅资料并跟踪源码后发现是焦点导致的bug,网上也有不少文章解决这个bug,我一一进行了尝试,效果都不理想。
第一个方法:
在adapter的getView中,清除当前焦点View的焦点
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//abandon current focus
View currentFocus = ((Activity)mContext).getCurrentFocus();
if (currentFocus != null) {
currentFocus.clearFocus();
}
// other code
}
这个方法其实一看就不适合我的表单界面,因为每次刷新会导致EditText失去焦点从而无法输入文字,并且事实也是如此,pass!
第二个方法:
对ListView的滚动事件进行监听,在ListView滚动的时候,清除焦点。
protected class MyScrollListener implements OnScrollListener {
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// do nothing
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (SCROLL_STATE_TOUCH_SCROLL == scrollState) {
View currentFocus = getCurrentFocus();
if (currentFocus != null) {
currentFocus.clearFocus();
}
}
}
}
经过尝试后,还是出现闪退的问题。pass!
第三种方法:
在Activity的Manifest中,添加属性
android:windowSoftInputMode="adjustPan"
使具有焦点的输入框保持在用户界面中。看上去有道理,但是用了之后也没有什么卵用。。然而本着没有什么影响的原则,并没有把这个属性从Manifest中移除。
最后,既然已经确定是焦点的问题,那么我就尝试在跳转新页面的点击事件中,加入清除焦点的代码,如下:
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View view = ((Activity)context).getCurrentFocus();
if (view != null) {
view.clearFocus();
}
Intent intent = new Intent(context, RemarkEditActivity.class);
intent.putExtra("pageTitle", model.getTitle());
intent.putExtra("groupPosition", position);
intent.putExtra("remarkText", props.get(model.getFieldid()) != null ? props.get(model.getFieldid()).toString() : "");
((CustomizeFormDetailActivity) context).startActivityForResult(intent, EDIT_MULTI_TEXT_REQUEST_CODE);
}
});
在进行页面跳转之前,将焦点清除。这样,这个bug就解决了!