Android Studio(Java):InfoWindow内嵌EditText无法编辑问题求助
问题:Google地图InfoWindow中嵌入EditText并唤起软键盘失败
最近尝试在Google地图的InfoWindow中嵌入EditText,希望用户点击InfoWindow后能在该字段输入注释。已知InfoWindow只是渲染的图片而非交互控件,因此尝试通过OnInfoWindowClickListener唤起软键盘直接编辑EditText,但未能成功。
相关代码(已移除冗余部分):
@Override public void onMapReady(@NonNull GoogleMap googleMap) { gMap = googleMap; gMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() { @Nullable @Override public View getInfoContents(@NonNull Marker marker) { View iwv = getLayoutInflater().inflate(R.layout.infowindow, null); return iwv; } @Nullable @Override public View getInfoWindow(@NonNull Marker marker) { return null; } }); gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { @Override public void onMapClick(@NonNull LatLng point) { if(flag) { //toggle the ability to turn markers on or off gMap.addMarker(new MarkerOptions() .position(point)).showInfoWindow(); } } }); gMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() { @Override public void onInfoWindowClick(@NonNull Marker marker) { View v = li.inflate(R.layout.infowindow, null); infoWindowText = v.findViewById(R.id.iw_et); handleKeyboard(infoWindowText); } }); } public void handleKeyboard(View view) { if (view.requestFocus()) { InputMethodManager imm = getSystemService(InputMethodManager.class); imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0); } }
已知imm.toggleSoftInput已被弃用,改用imm.showSoftInput也无法唤起软键盘,询问功能是否可行,或是点击监听器使用有误。
解决方案
核心问题分析
你当前代码的关键错误在于:在OnInfoWindowClickListener中新inflate的View没有添加到Activity的布局树中,这个View是游离状态,不属于当前窗口的一部分,所以requestFocus()和输入法唤起的操作都不会生效。另外,InfoWindow本身是静态渲染的图片,确实无法承载可交互控件,必须换一种实现思路。
可行实现方案
点击InfoWindow后,关闭当前InfoWindow,在屏幕上显示一个真正可交互的EditText(可以动态添加到布局,或用弹窗承载),编辑完成后将内容关联到Marker,再重新显示InfoWindow时加载内容。
示例代码修改
- 修改InfoWindowAdapter,支持加载已保存的注释
gMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() { @Nullable @Override public View getInfoContents(@NonNull Marker marker) { View iwv = getLayoutInflater().inflate(R.layout.infowindow, null); EditText et = iwv.findViewById(R.id.iw_et); // 从Marker的Tag中获取已保存的注释内容 String savedNote = (String) marker.getTag(); if (savedNote != null) { et.setText(savedNote); } return iwv; } @Nullable @Override public View getInfoWindow(@NonNull Marker marker) { return null; } });
- 修改OnInfoWindowClickListener,添加可交互EditText并唤起键盘
gMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() { @Override public void onInfoWindowClick(@NonNull Marker marker) { // 先关闭当前InfoWindow marker.hideInfoWindow(); // 获取Activity的根布局,用于添加EditText ViewGroup rootLayout = findViewById(android.R.id.content); // 创建可交互的EditText EditText editText = new EditText(MainActivity.this); editText.setHint("输入注释"); editText.setTextSize(16); editText.setPadding(20, 15, 20, 15); editText.setBackgroundColor(Color.WHITE); // 将EditText定位到Marker对应的屏幕位置附近 LatLng markerPos = marker.getPosition(); Point screenPoint = gMap.getProjection().toScreenLocation(markerPos); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT ); params.setMargins(0, screenPoint.y - 120, 0, 0); // 调整位置避免遮挡Marker editText.setLayoutParams(params); // 添加到根布局 rootLayout.addView(editText); // 唤起软键盘 editText.requestFocus(); InputMethodManager imm = getSystemService(InputMethodManager.class); imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); // 监听编辑完成(回车/完成按钮) editText.setOnEditorActionListener((v, actionId, event) -> { if (actionId == EditorInfo.IME_ACTION_DONE) { // 保存内容到Marker的Tag marker.setTag(editText.getText().toString()); // 移除EditText rootLayout.removeView(editText); // 重新显示InfoWindow marker.showInfoWindow(); return true; } return false; }); // 点击布局其他区域关闭编辑 View.OnClickListener dismissListener = v -> { if (rootLayout.indexOfChild(editText) != -1) { marker.setTag(editText.getText().toString()); rootLayout.removeView(editText); marker.showInfoWindow(); // 移除点击监听,避免影响后续操作 rootLayout.setOnClickListener(null); } }; rootLayout.setOnClickListener(dismissListener); } });
替代方案
如果觉得动态添加EditText的位置处理麻烦,也可以直接用AlertDialog或BottomSheetDialog来承载EditText,实现更简单,用户体验也更稳定。
内容的提问来源于stack exchange,提问作者Fishie
相关产品推荐
相关产品推荐

