android:如何使用谷歌地图V2在自定义infoWindow上设置点击监听器上的按钮

时间:2016-03-18 09:26:50

标签: android google-maps

我想使用button V2在自定义onClick上设置infoWindow Google Map,以下是我的完整代码,但无法正常使用。

这是我的MainActivity。

public class MainActivity extends Activity {
private ViewGroup infoWindow;
private TextView infoTitle;
private TextView infoSnippet;
private Button infoButton;
private OnInfoWindowElemTouchListener infoButtonListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    final MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
    final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout)findViewById(R.id.map_relative_layout);
    final GoogleMap map = mapFragment.getMap();

    mapWrapperLayout.init(map, getPixelsFromDp(this, 39 + 20));

    this.infoWindow = (ViewGroup)getLayoutInflater().inflate(R.layout.info_window, null);
    this.infoTitle = (TextView)infoWindow.findViewById(R.id.title);
    this.infoSnippet = (TextView)infoWindow.findViewById(R.id.snippet);
    this.infoButton = (Button)infoWindow.findViewById(R.id.button);

    this.infoButtonListener = new OnInfoWindowElemTouchListener(infoButton,
            getResources().getDrawable(R.drawable.ic_launcher),
            getResources().getDrawable(R.drawable.ic_launcher))
    {
        @Override
        protected void onClickConfirmed(View v, Marker marker) {
            // Here we can perform some action triggered after clicking the button
            Toast.makeText(MainActivity.this, marker.getTitle() + "'s button clicked!", Toast.LENGTH_SHORT).show();
        }
    };
    this.infoButton.setOnTouchListener(infoButtonListener);

    map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
        @Override
        public View getInfoWindow(Marker marker) {
            return null;
        }

        @Override
        public View getInfoContents(Marker marker) {
            // Setting up the infoWindow with current's marker info
            infoTitle.setText(marker.getTitle());
            infoSnippet.setText(marker.getSnippet());
            infoButtonListener.setMarker(marker);
            mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
            return infoWindow;
        }
    });

    // Let's add a couple of markers
    map.addMarker(new MarkerOptions()
            .title("Prague")
            .snippet("Czech Republic")
            .position(new LatLng(50.08, 14.43)));

    map.addMarker(new MarkerOptions()
            .title("Paris")
            .snippet("France")
            .position(new LatLng(48.86,2.33)));

    map.addMarker(new MarkerOptions()
            .title("London")
            .snippet("United Kingdom")
            .position(new LatLng(51.51,-0.1)));
}

public static int getPixelsFromDp(Context context, float dp) {
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int)(dp * scale + 0.5f);

}

以下是我的activity_main

<com.circlegate.tt.cg.an.lib.map.MapWrapperLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map_relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.google.android.gms.maps.MapFragment" />

//这里是MapWrapperLayout。

public class MapWrapperLayout extends RelativeLayout {
private GoogleMap map;
private int bottomOffsetPixels;
private Marker marker;
private View infoWindow;

public MapWrapperLayout(Context context) {
    super(context);
}
public MapWrapperLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}
public MapWrapperLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}
public void init(GoogleMap map, int bottomOffsetPixels) {
    this.map = map;
    this.bottomOffsetPixels = bottomOffsetPixels;
}
public void setMarkerWithInfoWindow(Marker marker, View infoWindow) {
    this.marker = marker;
    this.infoWindow = infoWindow;
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    boolean ret = false;
    // Make sure that the infoWindow is shown and we have all the needed references
    if (marker != null && marker.isInfoWindowShown() && map != null && infoWindow != null) {

        Point point = map.getProjection().toScreenLocation(marker.getPosition());
        MotionEvent copyEv = MotionEvent.obtain(ev);
        copyEv.offsetLocation(
                -point.x + (infoWindow.getWidth() / 2),
                -point.y + infoWindow.getHeight() + bottomOffsetPixels);

        ret = infoWindow.dispatchTouchEvent(copyEv);
    }
    return ret || super.dispatchTouchEvent(ev);
}

//这里是OnInfoWindowElemTouchListener

        public abstract class OnInfoWindowElemTouchListener implements View.OnTouchListener 
    {
        private final View view;
        private final Drawable bgDrawableNormal;
        private final Drawable bgDrawablePressed;
        private final Handler handler = new Handler();
        private Marker marker;
        private boolean pressed = false;

        public OnInfoWindowElemTouchListener(View view, Drawable bgDrawableNormal, Drawable bgDrawablePressed) {
            this.view = view;
            this.bgDrawableNormal = bgDrawableNormal;
            this.bgDrawablePressed = bgDrawablePressed;
        }
        public void setMarker(Marker marker) {
            this.marker = marker;
        }
        @Override
        public boolean onTouch(View vv, MotionEvent event) {
            if (0 <= event.getX() && event.getX() <= view.getWidth() &&
                    0 <= event.getY() && event.getY() <= view.getHeight())
            {
                switch (event.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN: startPress(); break;
                    case MotionEvent.ACTION_UP: handler.postDelayed(confirmClickRunnable, 150); break;
                    case MotionEvent.ACTION_CANCEL: endPress(); break;
                    default: break;
                }
            }
            else {
                endPress();
            }
            return false;
        }
        private void startPress() {
            if (!pressed) {
                pressed = true;
                handler.removeCallbacks(confirmClickRunnable);
                view.setBackground(bgDrawablePressed);
                if (marker != null)
                    marker.showInfoWindow();
            }
        }
        private boolean endPress() {
            if (pressed) {
                this.pressed = false;
                handler.removeCallbacks(confirmClickRunnable);
                view.setBackground(bgDrawableNormal);
                if (marker != null)
                    marker.showInfoWindow();
                return true;
            }
            else
                return false;
        }
        private final Runnable confirmClickRunnable = new Runnable() {
            public void run() {
                if (endPress()) {
                    onClickConfirmed(view, marker);
                }
            }
        };
        protected abstract void onClickConfirmed(View v, Marker marker);
    }

2 个答案:

答案 0 :(得分:1)

我认为这是不可能的,因为地图上的视图可以作为图像使用,因此可以完全点击自定义窗口,但是按照Google文档无法按下每个按钮。

答案 1 :(得分:0)

直接我们无法做到这一点,尝试使用此库 enter link description here