百度地圖的使用-定位—逆地理編碼(即座標轉地址)

先上效果:

  1. 定位+拖動定位
  2. 定位動畫
  3. 動畫結束顯示地址

效果

實現思路

  1. 中心點不變,在百度地圖圖層上覆蓋自定義的定位佈局
    (TextView+ImageView+ImageView)
  2. 拖動地圖時,隱藏地址顯示,定位標示落下來後顯示地址
  3. 拿到百度地圖的拖動監聽 setOnMapStatusChangeListener
  4. 拿到中心點經緯度,逆地理編碼(即座標轉地址)mapStatus.target

clipboard.png

具體實現:

佈局:

在主界面佈局上覆蓋本身定位用的佈局location_markerandroid

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context=".MainActivity">

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />
    <include layout="@layout/location_marker"/>

</android.support.constraint.ConstraintLayout>
location_marker佈局:三個控件
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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">

    <ImageView
        android:id="@+id/iv_shadow"
        android:layout_width="22dp"
        android:layout_height="4dp"
        android:layout_centerHorizontal="true"
        android:src="@drawable/location_shadow"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <ImageView
        android:id="@+id/iv_location"
        android:layout_width="36dp"
        android:layout_height="36dp"
        android:src="@drawable/location_ic_select"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@id/iv_shadow"/>

    <TextView
        android:padding="2dp"
        android:background="@drawable/shape_buttn_text"
        android:id="@+id/tv_describe"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        android:text="TextView"
        app:layout_constraintBottom_toTopOf="@+id/iv_location"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />


</android.support.constraint.ConstraintLayout>

拖動監聽

  1. 建立地理編碼檢索實例;
  2. 建立地理編碼檢索監聽者;
  3. 開始向上的動畫
  4. 中止拖動後,發起地理編碼檢索
mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
            @Override
            public void onMapStatusChangeStart(MapStatus mapStatus) {
                mSearch = GeoCoder.newInstance();
                mSearch.setOnGetGeoCodeResultListener(listener);
                startUpAnimation(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                        //動畫開始時,隱藏地址顯示
                        tv_describe.setVisibility(View.INVISIBLE);
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {

                    }
                });

            }

            @Override
            public void onMapStatusChangeStart(MapStatus mapStatus, int i) {

            }

            @Override
            public void onMapStatusChange(MapStatus mapStatus) {

            }

            @Override
            public void onMapStatusChangeFinish(MapStatus mapStatus) {

                mSearch.reverseGeoCode(new ReverseGeoCodeOption()
                        .location(mapStatus.target));



            }
        });

地理位置編碼檢索監聽實現:git

OnGetGeoCoderResultListener listener = new OnGetGeoCoderResultListener() {

        public void onGetGeoCodeResult(GeoCodeResult result) {

            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                //沒有檢索到結果
            }

            //獲取地理編碼結果
        }

        @Override

        public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {

            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                //沒有找到檢索結果
                Toast.makeText(MainActivity.this,"沒有找到檢索結果",Toast.LENGTH_SHORT).show();
            }

            //獲取反向地理編碼結果
            String address = result.getAddress();
            System.out.println(address+"---------");
            tv_describe.setText(address);
            startDownAnimation(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    tv_describe.setVisibility(View.VISIBLE);
                    bounce();
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });

        }
    };

三種動畫的具體實現:

須要一個變量紀錄是否向上
private boolean isUp = false;

    /**
     * 向上移動動畫
     */
    public void startUpAnimation(Animation.AnimationListener listener){
        if (isUp){
            return;
        }
        Animation animation = new TranslateAnimation(
                0,
                0,
                0  ,
                - 80);
        animation.setDuration(500);
        animation.setFillAfter(true);//設置爲true,動畫轉化結束後被應用
        animation.setInterpolator(new AccelerateDecelerateInterpolator());
        iv_location.startAnimation(animation);//開始動畫
        if(listener != null){
            animation.setAnimationListener(listener);
        }

        isUp = true;
    }

    /**
     * 向下移動動畫
     */
    public void startDownAnimation(Animation.AnimationListener listener){
        if(isUp){
            Animation animation = new TranslateAnimation(
                    0,
                    0,
                    -80,
                    0);
            animation.setDuration(500);
            animation.setFillAfter(true);//設置爲true,動畫轉化結束後被應用
            animation.setInterpolator(new AccelerateInterpolator(15));
            if(listener != null){
                animation.setAnimationListener(listener);
            }
            iv_location.startAnimation(animation);//開始動畫
            isUp = false;
        }
    }

    /**
     * 彈跳動畫
     */
    public  void bounce() {
        if (iv_location.getVisibility() == View.VISIBLE) {
            ObjectAnimator animator = ObjectAnimator.ofFloat(iv_location, "translationY", 0, -30, 0);
            animator.setInterpolator(new EasingInterpolator(EasingInterpolator.Ease.ELASTIC_IN_OUT));

            animator.setDuration(1000);
            animator.setRepeatMode(ValueAnimator.REVERSE);
            animator.start();
        }
    }

定位方面參考以前文章,更新一下以前寫的MyLocationListener

新添加一個變量紀錄是否第一次定位
private boolean isFirst = true;
    class MyLocationListener extends BDAbstractLocationListener {


        @Override
        public void onReceiveLocation(BDLocation bdLocation) {

            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(bdLocation.getRadius())
                    // 此處設置開發者獲取到的方向信息,順時針0-360
                    .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
            mBaiduMap.setMyLocationData(locData);

            String addr = bdLocation.getAddrStr();    //獲取詳細地址信息
            String country = bdLocation.getCountry();    //獲取國家
            String province = bdLocation.getProvince();    //獲取省份
            String city = bdLocation.getCity();    //獲取城市
            String district = bdLocation.getDistrict();    //獲取區縣
            String street = bdLocation.getStreet();    //獲取街道信息
//            showMyLocate(locData);

            if(isFirst){
                // 開始移動百度地圖的定位地點到中心位置
                LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
                MapStatusUpdate u = MapStatusUpdateFactory.newLatLngZoom(ll,16);
                mBaiduMap.animateMapStatus(u);
                isFirst = false;
            }

        }
    }
}
相關文章
相關標籤/搜索