工作中遇到一个问题
android4.4原生Dialer
1、打开拨号盘(无常用联系人前提情况下)
2、点击拨号盘菜单,弹出拨号盘
3、随便输入数字搜索
4、返回键返回到起始界面
5、(多次)点击“所有联系人”无效
6、再点任意键(Button、menu、back、home。。。),之前点击“所有联系人”的按键事件都响应了,即弹出多次所有联系人界面。
分析
步骤5时,就没有执行注册的onClick函数,而是步骤6后执行了N次(对应步骤5的点击次数)。
View.java 中会调用post(mPerformClick)
mPerformClick 会调用到 mOnClickListener.onClick(this) 从而调用用户注册的listener处理按键。
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
return true;
}
正常情况下,mAttachInfo不为空,走上面的return,会直接处理消息。
加log发现,上述步骤5时,走的是下面的return,即mAttachInfo为空,将消息添加到一个队列里,后面触发后依次执行(即上述步骤6)。
mAttachInfo的值是在下面两个函数中设置的。
dispatchAttachedToWindow()
mAttachInfo = info;
dispatchDetachedFromWindow()
mAttachInfo = null;
回到拨号盘界面
PhoneFavoriteFragment onResume()后会重新加载数据,加载完后调用setEmptyViewVisibility()来设置R.id.phone_no_favorites_view是否可见以及调整R.id.contact_tile_frame的高度。
/* package */ void setEmptyViewVisibility(final boolean visible) {
final int previousVisibility = mEmptyView.getVisibility();
final int newVisibility = visible ? View.VISIBLE : View.GONE;
if (previousVisibility != newVisibility) {
final RelativeLayout.LayoutParams params = (LayoutParams) mContactTileFrame.getLayoutParams();
params.height = visible ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT;
mContactTileFrame.setLayoutParams(params);
mEmptyView.setVisibility(newVisibility);
}
}
布局文件R.layout.phone_favorites_fragment
<?xml version="1.0" encoding="utf-8"?>
<!-- Use LinearLayout + FrameLayout, just to rely on android:divider and android:showDividers -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="?android:attr/dividerHorizontal"
android:showDividers="end"
android:clipChildren="false"
android:background="@color/background_dialer_list_items">
<FrameLayout
android:id="@+id/contact_tile_frame"
android:layout_width="match_parent"
android:layout_height="<span style="color:#ff0000;">match_parent</span>"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
>
<com.android.dialer.list.PhoneFavoriteListView
android:id="@+id/contact_tile_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="@dimen/contact_tile_list_padding_top"
android:clipToPadding="false"
android:fadingEdge="none"
android:divider="@null" />
<ImageView
android:id="@+id/contact_tile_drag_shadow_overlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
</FrameLayout>
<include
android:id="@+id/phone_no_favorites_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/contact_tile_frame"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
layout="@layout/phone_no_favorites"
android:visibility="gone"/>
</RelativeLayout>
R.id.contact_tile_frame的属性设置为
android:layout_height="wrap_content"
或在代码里设置
params.height = LayoutParams.WRAP_CONTENT
就会调用几次dispatchAttachedToWindow和dispatchDetachedFromWindow,最终mAttachInfo = null;从而出现上述问题。
但是不知道为什么??
固定值或MATCH_PARENT就没问题。。。
解决办法
不设置WRAP_CONTENT,设置一个固定的值
问题虽然临时解决,但是不知道why。。。