在android中自定义

在android中自定义

本文介绍了在android中自定义,禁用和空白地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只想在地图上显示标记的半径部分,地图的其余部分必须是空白的。
就像标记半径是5公里一样,我希望只有地图的半径部分必须对用户可见,而地图的其余部分必须是空白的。



我已经阅读了Google Map Overlays,并且还搜索了像MapBox和Skobbler等各种SDK,但它们都没有提供我想要的功能。



在图片中,您可以看到只有标记周围的某些部分可见并且休息是空白。我想在android地图中实现此功能。



如果有人有任何解决方案或想法,请告诉我。



谢谢。 隐藏它并在其上绘制一个圆圈以仅显示所需位置的地图。



我已根据我的答案



  • $ b

    限制:




    • 此解决方案仅更新 onCameraChange 上的 HideOverlayView ,因此当用户缩放或平铺地图,地图上的其他位置可以显示

    • 计算半径的计算不考虑地图的旋转和倾斜度。 $ b

    I want to display only the radius part of marker on map and rest of the map must be blank.Like if Marker radius is 5 KM and i want that only that radius part of the map must be visible to user and rest of the map must be blank.

    I have read about Google Map Overlays and also search about various SDK Like MapBox and Skobbler but none of them provide the functionality that i want.

    In the image you can see that only some part around the marker is visible and rest is blank. I want to achieve this functionality in android Maps.

    If anyone has any solution or idea, please let me know.

    Thanks.

    解决方案

    You can add a View over the map that hides it and draw a circle on it to show only the desired locations.

    I have based my answers on

    MapsActivity:

    public class MapsActivity extends FragmentActivity implements GoogleMap.OnCameraChangeListener {
        private GoogleMap mMap;
        private HideOverlayView hideView;
        private List<Marker> visibleMarkers = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_maps);
    
            hideView = (HideOverlayView) findViewById(R.id.hideview);
    
            setUpMapIfNeeded();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            setUpMapIfNeeded();
        }
    
        @SuppressLint("NewApi")
        private void setUpMapIfNeeded() {
            if (mMap == null) {
                final SupportMapFragment f = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
                mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                        .getMap();
                if (mMap != null) {
                    setUpMap();
                }
            }
        }
    
        private void setUpMap() {
            mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
            mMap.getUiSettings().setAllGesturesEnabled(true);
            mMap.getUiSettings().setZoomControlsEnabled(true);
            mMap.getUiSettings().setMyLocationButtonEnabled(true);
            mMap.setMyLocationEnabled(true);
            mMap.setOnCameraChangeListener(this);
    
            mMap.moveCamera(CameraUpdateFactory.newCameraPosition(
                    CameraPosition.fromLatLngZoom(new LatLng(40.22861, -3.95567), 15)));
    
            visibleMarkers.add(mMap.addMarker(new MarkerOptions().position(
                    new LatLng(40.22861, -3.95567))));
            visibleMarkers.add(mMap.addMarker(new MarkerOptions().position(
                    new LatLng(40.22977, -3.95338))));
        }
    
        @Override
        public void onCameraChange(final CameraPosition cameraPosition) {
            List<Point> visiblePoints = new ArrayList<>();
            Projection projection = mMap.getProjection();
    
            for (Marker visibleMarker : visibleMarkers) {
                visiblePoints.add(projection.toScreenLocation(visibleMarker.getPosition()));
            }
    
            float radius = 150f; // meters
            Point centerPoint = projection.toScreenLocation(cameraPosition.target);
            Point radiusPoint = projection.toScreenLocation(
                    SphericalUtil.computeOffset(cameraPosition.target, radius, 90));
    
            float radiusPx = (float) Math.sqrt(Math.pow(centerPoint.x - radiusPoint.x, 2));
    
            hideView.reDraw(visiblePoints, radiusPx);
        }
    }
    

    HideOverlayView:

    public class HideOverlayView extends LinearLayout {
        private Bitmap windowFrame;
        private float radius = 0f;
        private List<Point> points;
    
        public HideOverlayView(Context context) {
            super(context);
        }
    
        public HideOverlayView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        protected void dispatchDraw(Canvas canvas) {
            super.dispatchDraw(canvas);
    
            createWindowFrame();
            canvas.drawBitmap(windowFrame, 0, 0, null);
        }
    
        @Override
        public boolean isEnabled() {
            return false;
        }
    
        @Override
        public boolean isClickable() {
            return false;
        }
    
        public void reDraw(List<Point> points, float radius) {
            this.points = points;
            this.radius = radius;
    
            invalidate();
        }
    
        protected void createWindowFrame() {
            windowFrame = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            Canvas osCanvas = new Canvas(windowFrame);
    
            RectF outerRectangle = new RectF(0, 0, getWidth(), getHeight());
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setColor(Color.BLACK);
            osCanvas.drawRect(outerRectangle, paint);
    
            if (radius > 0 && points != null) {
                for (Point point : points) {
                    paint.setColor(Color.TRANSPARENT);
                    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
                    paint.setStyle(Paint.Style.FILL);
                    osCanvas.drawCircle(point.x, point.y, radius, paint);
                }
            }
        }
    
        @Override
        public boolean isInEditMode() {
            return true;
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            windowFrame = null;
        }
    }
    

    activity_maps.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    xmlns:app="http://schemas.android.com/apk/res-auto"
                    xmlns:tools="http://schemas.android.com/tools"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical">
        <fragment
            android:id="@+id/map"
            android:name="mypackage.MySupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MapsActivity"/>
        <mypackage.HideOverlayView
            android:id="@+id/hideview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            app:radius="150dp"/>
    </RelativeLayout>
    

    Result:

    Limitations:

    • This solution only updates the HideOverlayView on onCameraChange, so when the user zooms or pans the map, other locations on the map can be shown
    • The calculations made to compute the radius don't take into account rotations and tilts of the map

    这篇关于在android中自定义,禁用和空白地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 17:56