1

我正在创建谷歌地图当前位置气球覆盖。

我使用android-mapviewballoons这段代码来显示气球。

此处当前位置显示正在工作。当我点击标记时,会出现错误(BalloonOverlayView 49,37 行和 BalloonItemizedOverlay 86,179,76 行)。

我知道错误在哪里,但我不明白那部分,请帮助我

这是 LogCat 错误

 01-31 09:27:46.278: E/AndroidRuntime(4704): FATAL EXCEPTION: main
 01-31 09:27:46.278: E/AndroidRuntime(4704): android.view.InflateException: Binary XML file line #28: Error inflating class <unknown>
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.LayoutInflater.createView(LayoutInflater.java:613)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:660)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at   android.view.LayoutInflater.inflate(LayoutInflater.java:489)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.sygnet.locationingooglemap.BalloonOverlayView.setupView(BalloonOverlayView.java:49)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.sygnet.locationingooglemap.BalloonOverlayView.<init>(BalloonOverlayView.java:37)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.sygnet.locationingooglemap.BalloonItemizedOverlay.createBalloonOverlayView(BalloonItemizedOverlay.java:86)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.sygnet.locationingooglemap.BalloonItemizedOverlay.createAndDisplayBalloonOverlay(BalloonItemizedOverlay.java:179)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.sygnet.locationingooglemap.BalloonItemizedOverlay.onTap(BalloonItemizedOverlay.java:76)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.google.android.maps.ItemizedOverlay.onTap(ItemizedOverlay.java:453)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.google.android.maps.OverlayBundle.onTap(OverlayBundle.java:83)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.google.android.maps.MapView$1.onSingleTapUp(MapView.java:358)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.google.android.maps.GestureDetector.onTouchEvent(GestureDetector.java:562)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.google.android.maps.MapView.onTouchEvent(MapView.java:685)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.View.dispatchTouchEvent(View.java:7239)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405)
01-31 09:27:46.278: E/AndroidRuntime(4704):     at android.app.Activity.dispatchTouchEvent(Activity.java:2410)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901)
  01-31 09:27:46.278: E/AndroidRuntime(4704):   at android.view.View.dispatchPointerEvent(View.java:7419)
  01-31 09:27:46.278: E/AndroidRuntime(4704):   at an droid.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
  01-31 09:27:46.278: E/AndroidRuntime(4704):   at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.os.MessageQueue.nativePollOnce(Native Method)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.os.MessageQueue.next(MessageQueue.java:125)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at     android.os.Looper.loop(Looper.java:124)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at android.app.ActivityThread.main(ActivityThread.java:5039)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at java.lang.reflect.Method.invokeNative(Native Method)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at java.lang.reflect.Method.invoke(Method.java:511)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at dalvik.system.NativeStart.main(Native Method)
 01-31 09:27:46.278: E/AndroidRuntime(4704): Caused by: java.lang.reflect.InvocationTargetException
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at java.lang.reflect.Constructor.constructNative(Native Method)
 01-31 09:27:46.278: E/AndroidRuntime(4704):    at java.lang.reflect.Constructor.ne

这是 BalloonItemizedOverlay.java

public abstract class BalloonItemizedOverlay<Item extends OverlayItem> extends ItemizedOverlay<Item> {

private static final long BALLOON_INFLATION_TIME = 300;
private static Handler handler = new Handler();

private MapView mapView;
private BalloonOverlayView<Item> balloonView;
private View clickRegion;
private View closeRegion;
private int viewOffset;
final MapController mc;
private Item currentFocusedItem;
private int currentFocusedIndex;

private boolean showClose = true;
private boolean showDisclosure = false;
private boolean snapToCenter = true;
private static boolean isInflating = false;

public BalloonItemizedOverlay(Drawable defaultMarker, MapView mapView) {
    super(defaultMarker);
    this.mapView = mapView;
    viewOffset = 0;
    mc = mapView.getController();
}

public void setBalloonBottomOffset(int pixels) {
    viewOffset = pixels;
}
public int getBalloonBottomOffset() {
    return viewOffset;
}

protected boolean onBalloonTap(int index, Item item) {
    return false;
}

protected void onBalloonOpen(int index) {}

@Override
public final boolean onTap(int index) {

    handler.removeCallbacks(finishBalloonInflation);
    isInflating = true;
    handler.postDelayed(finishBalloonInflation, BALLOON_INFLATION_TIME);

    currentFocusedIndex = index;
    currentFocusedItem = createItem(index);
    setLastFocusedIndex(index);

    onBalloonOpen(index);
    createAndDisplayBalloonOverlay();

    if (snapToCenter) {
        mc.animateTo(currentFocusedItem.getPoint());
    }

    return true;
}

protected BalloonOverlayView<Item> createBalloonOverlayView() {
    return new BalloonOverlayView<Item>(getMapView().getContext(), getBalloonBottomOffset());
}

protected MapView getMapView() {
    return mapView;
}

public void hideBalloon() {
    if (balloonView != null) {
        balloonView.setVisibility(View.GONE);
    }
    currentFocusedItem = null;
}

private void hideOtherBalloons(List<Overlay> overlays) {

    for (Overlay overlay : overlays) {
        if (overlay instanceof BalloonItemizedOverlay<?> && overlay != this) {
            ((BalloonItemizedOverlay<?>) overlay).hideBalloon();
        }
    }       
}

public void hideAllBalloons() {
    if (!isInflating) {
        List<Overlay> mapOverlays = mapView.getOverlays();
        if (mapOverlays.size() > 1) {
            hideOtherBalloons(mapOverlays);
        }
        hideBalloon();
    }
}

private OnTouchListener createBalloonTouchListener() {
    return new OnTouchListener() {

        float startX;
        float startY;

        public boolean onTouch(View v, MotionEvent event) {

            View l =  ((View) v.getParent()).findViewById(R.id.balloon_main_layout);
            Drawable d = l.getBackground();

            //Event Action Down
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                int[] states = {android.R.attr.state_pressed};
                if (d.setState(states)) {
                    d.invalidateSelf();
                }
                startX = event.getX();
                startY = event.getY();
                return true;
            } 

            //Event Action Up
            else if (event.getAction() == MotionEvent.ACTION_UP) {
                int newStates[] = {};
                if (d.setState(newStates)) {
                    d.invalidateSelf();
                }
                if (Math.abs(startX - event.getX()) < 40 && Math.abs(startY - event.getY()) < 40 ) {
                    // call overridden method
                    onBalloonTap(currentFocusedIndex, currentFocusedItem);
                }
                return true;
            } else {
                return false;
            }               
        }
    };
}

@Override
public Item getFocus() {
    return currentFocusedItem;
}

@Override
public void setFocus(Item item) {
    super.setFocus(item);   
    currentFocusedIndex = getLastFocusedIndex();
    currentFocusedItem = item;
    if (currentFocusedItem == null) {
        hideBalloon();
    } else {
        createAndDisplayBalloonOverlay();
    }   
}

private boolean createAndDisplayBalloonOverlay(){
    boolean isRecycled;
    if (balloonView == null) {
        balloonView = createBalloonOverlayView();
        clickRegion = (View) balloonView.findViewById(R.id.balloon_inner_layout);

        clickRegion.setOnTouchListener(createBalloonTouchListener());
        closeRegion = (View) balloonView.findViewById(R.id.balloon_close);
        if (closeRegion != null) {
            if (!showClose) {
                closeRegion.setVisibility(View.GONE);
            } else {
                closeRegion.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        hideBalloon();  
                    }
                });
            }
        }

        if (showDisclosure && !showClose) {
            View v = balloonView.findViewById(R.id.balloon_disclosure);
            if (v != null) {
                v.setVisibility(View.VISIBLE);
            }
        }
        isRecycled = false;
    } 
    else {
        isRecycled = true;
    }

    balloonView.setVisibility(View.GONE);

    List<Overlay> mapOverlays = mapView.getOverlays();
    if (mapOverlays.size() > 1) {
        hideOtherBalloons(mapOverlays);
    }

    if (currentFocusedItem != null)
        balloonView.setData(currentFocusedItem);

    GeoPoint point = currentFocusedItem.getPoint();
    MapView.LayoutParams params = new MapView.LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, point,
            MapView.LayoutParams.BOTTOM_CENTER);
    params.mode = MapView.LayoutParams.MODE_MAP;

    balloonView.setVisibility(View.VISIBLE);

    if (isRecycled) {
        balloonView.setLayoutParams(params);
    } 
    else {
        mapView.addView(balloonView, params);
    }

    return isRecycled;
} 

public void setShowClose(boolean showClose) {
    this.showClose = showClose;
}

public void setShowDisclosure(boolean showDisclosure) {
    this.showDisclosure = showDisclosure;
}

public void setSnapToCenter(boolean snapToCenter) {
    this.snapToCenter = snapToCenter;
}

public static boolean isInflating() {
    return isInflating;
}

private static Runnable finishBalloonInflation = new Runnable() {
    public void run() {
        isInflating = false;
    }
};
}

这是 BalloonOverlayView.java

public class BalloonOverlayView<Item extends OverlayItem> extends FrameLayout  {

private LinearLayout layout;
private TextView title;
MainActivity main;
//  private CharSequence tvLocation;

public BalloonOverlayView(Context context, int balloonBottomOffset) {

    super(context);

    setPadding(10, 0, 10, balloonBottomOffset);

    layout = new LimitLinearLayout(context);
    layout.setVisibility(VISIBLE);

    setupView(context, layout);

    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    params.gravity = Gravity.NO_GRAVITY;

    addView(layout, params);
}

protected void setupView(Context context, ViewGroup parent) {

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = inflater.inflate(R.layout.balloon_overlay, parent);
    title = (TextView) v.findViewById(R.id.balloon_item_title);


//      title.setText(tvLocation);
}

public void setData(Item item) {
    layout.setVisibility(VISIBLE);
    setBalloonData(item, layout);
}

protected void setBalloonData(Item item, ViewGroup parent) {
    if (item.getTitle() != null) {
        title.setVisibility(VISIBLE);
        title.setText(item.getTitle());
    } else {
        title.setText("");
        title.setVisibility(GONE);
    }
}

private class LimitLinearLayout extends LinearLayout {

    private static final int MAX_WIDTH_DP = 280;

    final float SCALE = getContext().getResources().getDisplayMetrics().density;

    public LimitLinearLayout(Context context) {
        super(context);
    }

    public LimitLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        int adjustedMaxWidth = (int)(MAX_WIDTH_DP * SCALE + 0.5f);
        int adjustedWidth = Math.min(measuredWidth, adjustedMaxWidth);
        int adjustedWidthMeasureSpec = MeasureSpec.makeMeasureSpec(adjustedWidth, mode);
        super.onMeasure(adjustedWidthMeasureSpec, heightMeasureSpec);
    }
}
 }
4

0 回答 0