You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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时加载内容。

示例代码修改

  1. 修改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;
    }
});
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:45:37