动态设置高德地图中心点(坐标点),始终位于屏幕中心

项目需求是做一个类似于滴滴的车辆救援,界面是地图上面再覆盖一部分表单。订单状态不同,表单里的信息不同,那么表单的高度就不同。因为界面都使用到了map,所以尽管订单有不同的状态,但是我都在一个界面做,通过状态变化来控制表单的显示状态。但是有一个问题是,不同的订单状态因为表单高度不同,导致地图的定位坐标点可能不在可视区域的中心。特别是我使用了bottomsheet来实现抽屉式表单,地图和表单肯定是有部分重叠的。那么如何才能让定位点位于可见地图区域的中心呢?

1、高德地图移动中心点的方法:

AMap.setPointToCenter(centerX, centerY)

2、寻找地图可见区域的中心点

主要是寻找地图中心点的Y坐标,思路是屏幕高度-title高度-表单高度,这样即使我的mapview设置的是match_parent,也可以让定位坐标点位于我计算的屏幕中心。

计算高度时遇到的问题是,什么时候计算高度。我们知道只有当view完成绘制的时候才能测量高度,所以在OnCreate里去获取控件高度肯定是不准的。网上的方法主要是以下四个:

(1)在onWindowFocuseChanged的时候去获取。这个方法虽然能获取到宽高,但是很被动。因为这个方法只有在activity获取焦点和失去焦点的时候才会被调用。而我希望是自己能够主动去获取宽高,设置中心点

(2)post runnable方法。没有用这个因为当时不懂原理,怕不稳妥,后来看了一下原理(https://blog.csdn.net/scnuxisan225/article/details/49815269)大概就是view.post(runnable)之后view会先取attachInfo,如果是空就会把这个runnable 添加到一个runnableQueue里,这个runnableQueue会在view.performTraversals里去遍历执行(performTraversals就是很重要的执行measure,layout.draw的地方)。最后这个list里的runnable会被handler post到主线程的消息队列中。而主线程正在执行view.performTraversals,那么post的runnable会等这个方法执行完再执行,就保证了post的runnable可以获取到宽高。(我知道onCreate的时候attchInfo是空的,那onResume的时候呢?onResume的时候会调用到view的attchToWindow的方法,如果post方法是在onResume里面,能否获取到宽高呢?不清楚)

(3)view.measure:不推荐会有错误

(4)ViewTreeObserver,它是一种观察者模式,可以通过给view添加布局监听,在布局完成之后进行中心点的设置。注意设置完之后要remove监听,不然每次布局变换都会被调用。

/**
     * 根据bottom view的高度设置地图中心点位置
     * @param view
     */
    private void setMapCenter(final View view) {
        LogUtils.i("setMapCenter:" + view);
        Display defaultDisplay = getWindowManager().getDefaultDisplay();
        Point point = new Point();
        defaultDisplay.getSize(point);
        final int screenWidth = point.x;
        final int screenHeight = point.y;
        final int centerX = screenWidth / 2;
        LogUtils.i("screenWidth:" + screenWidth + ",screenHeight:" + screenHeight);
        if (view.getVisibility() == View.VISIBLE) {
            view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    int bootomViewHeight = view.getHeight();
                    int centerY = (screenHeight - bootomViewHeight) / 2;
                    LogUtils.i("centerY:" + centerY);
                    if (mImLocation.getVisibility() == View.VISIBLE) {
                        centerY = (screenHeight - bootomViewHeight + mImLocation.getHeight()) / 2;
                        LogUtils.i("centerY:" + centerY);
                    }
                    //设置map中心点
                    mAmap.setPointToCenter(centerX, centerY);
                    LogUtils.i("onGlobalLayout,centerX:" + centerX + ",centerY:" + centerY);
                    view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }
            });
        }
    }

这样我在因为订单状态更新而更新界面的时候,可以通过这个方法将地图中心点(坐标marker)始终保持在地图中间

发布了14 篇原创文章 · 获赞 9 · 访问量 3万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览