DialogFragment调用startActivityForResult选联系人需多次点击问题求助
DialogFragment中调用联系人选择器需多次点击才能关闭的问题解决
我之前也碰到过类似的坑,你的问题根源其实出在触摸事件的处理逻辑上,咱们来一步步拆解:
问题原因
你用OnTouchListener触发联系人选择器,但触摸事件是一个完整的序列——当你点击View时,系统会依次发送ACTION_DOWN、ACTION_MOVE(如果有滑动)、ACTION_UP等事件。而你的代码里每次收到任何触摸事件都会调用一次startActivityForResult,这就导致一次点击操作会连续打开多个联系人选择器窗口。当你点击联系人时,只是关闭了最上层的那个窗口,下面还有之前打开的,所以需要多次点击才能全部关闭。
你的问题代码
触发选择器的触摸事件代码:
contact.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { startActivityForResult(new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI), REQUEST_CODE_PICK_CONTACTS); return true; } });
对应的onActivityResult处理:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_PICK_CONTACTS && resultCode == getActivity().RESULT_OK) { uriContact = data.getData(); contact.setText(name); } }
解决方案
有两种简单的修复方式,更推荐第二种:
方案1:限制仅在ACTION_UP事件触发选择器
修改触摸事件逻辑,只在用户完成点击动作(手指抬起)时启动选择器:
contact.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // 仅在手指抬起时触发选择器 if (event.getAction() == MotionEvent.ACTION_UP) { startActivityForResult(new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI), REQUEST_CODE_PICK_CONTACTS); } return true; } });
方案2:改用OnClickListener替代OnTouchListener
OnClickListener是专门为点击动作设计的,它只会在完整的点击流程(按下+抬起)完成后触发一次,从根源上避免重复启动的问题:
contact.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivityForResult(new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI), REQUEST_CODE_PICK_CONTACTS); } });
额外注意
你的onActivityResult代码已经正确调用了super.onActivityResult,这部分是没问题的,不用修改。核心问题解决后,点击联系人就能一次关闭选择器并返回结果了。
内容的提问来源于stack exchange,提问作者Mohamed Mellal
相关产品推荐
相关产品推荐

