百度地图仿微信发送位置

先上图
地图

前提:有百度地图账号并配置了相关环境,可以参考百度地图开发者文档并下载so和jar
百度地图jar导入
代码有相对应的注释,关键的就是百度地图移动版开发密钥、正确填写SHA1 和 程序包名,这将影响百度地图的功能使用

主要功能(参照微信发送定位):
1.定位所在位置并且展示周边POI(建筑物等信息);
2.拖拽地图完成,返回中心覆盖物所处位置周边的POI信息;
3.支持关键词等搜索,每次搜索完成,中央覆盖物移动到第一条POI信息的相应位置;
4.点击定位的图标,中央覆盖物回到所定位的位置;
5.点击下边列表的某条数据,将中央覆盖物移至该条数据对应的位置;
6.发送定位时,有相应的地图位置截图和地址信息.
————————————————

核心代码

//点击地图的监听,并显示所点击位置周围的poi信息
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                mBaiduMap.clear();
                adapter.changeSelected(0);
                mJARecyclerView.smoothScrollToPosition(0);
                MapStatusUpdate u = MapStatusUpdateFactory
                        .newLatLng(latLng);
                mBaiduMap.animateMapStatus(u);
                isUseGeoCoder = true;
            }

            @Override
            public boolean onMapPoiClick(MapPoi mapPoi) {
                LatLng position = mapPoi.getPosition();
                mBaiduMap.clear();
                MapStatusUpdate u = MapStatusUpdateFactory
                        .newLatLng(position);
                mBaiduMap.animateMapStatus(u);
                isUseGeoCoder = true;
                return true;

            }
        });
//移动地图的监听,并显示所点击位置周围的poi信息
        mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener() {
            @Override
            public void onTouch(MotionEvent motionEvent) {
                if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                    isUseGeoCoder = true;
                    isNeedAnimation = true;
                }
            }
        });
//地图状态发生改变的监听,不管是点击还是移动地图,都会触发状态改变的监听,处理位置居中显示,开启动画,反地理编码(根据坐标获取位置名称、地址等信息)
        mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
            @Override
            public void onMapStatusChangeStart(MapStatus mapStatus) {
            }

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

            @Override
            public void onMapStatusChange(MapStatus mapStatus) {
            }

            @Override
            public void onMapStatusChangeFinish(MapStatus mapStatus) {
                mBaiduMap.clear();
                if (isNeedAnimation) {
                    centerImage.startAnimation(centerAnimation);
                }
                LatLng target = mapStatus.target;
                if (isUseGeoCoder) {
                    showLoading(true);
                    mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                            .location(target));
                    adapter.changeSelected(0);
                    mJARecyclerView.smoothScrollToPosition(0);
                }
            }
        });

完整代码:
SelectAddressActivity.class

package com.lyw.myproject.baidumap.cityselect;
import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextWatcher;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.offline.MKOLSearchRecord;
import com.baidu.mapapi.map.offline.MKOfflineMap;
import com.baidu.mapapi.map.offline.MKOfflineMapListener;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener;
import com.baidu.mapapi.search.sug.SuggestionResult;
import com.baidu.mapapi.search.sug.SuggestionSearch;
import com.baidu.mapapi.search.sug.SuggestionSearchOption;
import com.lyw.myproject.BaseActivity;
import com.lyw.myproject.BuildConfig;
import com.lyw.myproject.R;
import com.lyw.myproject.adapter.AddressSelectAdapter;
import com.lyw.myproject.utils.PermissionUtil;
import com.lyw.myproject.utils.StatusBarUtils;
import com.lyw.myproject.widget.DefaultItemDecoration;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
 * 功能描述:地址选择
 * Created on 2020/6/17.
 * @author  lyw
 */
public class SelectAddressActivity extends BaseActivity implements AddressSelectAdapter.OnAddressSelectItemClickListener{
    private RecyclerView mJARecyclerView;
    private TextView cancleTv,searchAddressTv,confirmTv,searchNoDataTv;
    private MapView mBmapView;
    private EditText mSearchAddressEt;
    private LinearLayout searchNoDataLayout,searchNonmalLayout,searchEditLayout;
    private ImageView centerImage,locationIv,clearInputIv,mCheckTipIv;

    private BaiduMap mBaiduMap;
    private LocationClient mLocationClient;
    //是否首次定位
    boolean isFirstLoc = true;
    private AddressSelectAdapter adapter;
    private List<PoiInfo> mFilterList = new ArrayList<>();
    //选择的位置信息
    private PoiInfo selPoiDetailInfo;
    // 当前经纬度
    double mLantitude;
    double mLongtitude;
    LatLng mLoactionLatLng;
    // MapView中央对于的屏幕坐标
    Point mCenterPoint = null;
    // 地理编码
    GeoCoder mGeoCoder = null;
    List<PoiInfo> mInfoList;
    PoiInfo mCurentInfo;
    MyBDLocationListner mListner = null;
    private Animation centerAnimation;
    //是否使用反地理编码
    private boolean isUseGeoCoder = true;
    //是否需要动画
    private boolean isNeedAnimation = true;
    private InputMethodManager inputMethodManager;
    private SuggestionSearch mSuggestionSearch;
    private String changeContent;
    private MKOfflineMap mOffline;
    //选中的CityCode
    private String selectCityCode;
    private ArrayList<MKOLSearchRecord> mkolSearchRecords;
    private RotateAnimation mAnimation;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity_address_select_layout);
        FullscreenInputWorkaroundUtil.assistActivity(this);
        //设置状态栏透明
        StatusBarUtils.makeStatusBarTransparent(SelectAddressActivity.this);
        //请求位置权限
        if (!PermissionUtil.isHasLocationPermission(this)) {
            PermissionUtil.requestLocationPermission(this);
        }
        initView();
        initEvent();
        inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        //得到城市code
        mOffline = new MKOfflineMap();
        mOffline.init(new MKOfflineMapListener() {
            @Override
            public void onGetOfflineMapState(int i, int i1) {

            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mBmapView != null) {
            mBmapView.onResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mBmapView != null) {
            mBmapView.onPause();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBmapView != null) {
            mBmapView.onDestroy();
        }
        mBaiduMap.setMyLocationEnabled(false);
        if (mLocationClient != null) {
            mLocationClient.stop();
        }
        if (mGeoCoder != null) {
            mGeoCoder.destroy();
        }
        if (mSuggestionSearch != null) {
            mSuggestionSearch.destroy();
        }
        if (mOffline != null) {
            mOffline.destroy();
        }
    }

    private void initView() {
        mJARecyclerView = (RecyclerView)findViewById(R.id.recyclerview);
        cancleTv = (TextView)findViewById(R.id.cancle_tv);
        searchAddressTv = (TextView)findViewById(R.id.search_address_tv);
        confirmTv = (TextView)findViewById(R.id.confirm_tv);
        mBmapView = (MapView)findViewById(R.id.bmapView);
        mSearchAddressEt = (EditText)findViewById(R.id.search_address_et);
        searchNoDataTv = (TextView)findViewById(R.id.search_no_data_tv);
        searchNoDataLayout = (LinearLayout)findViewById(R.id.search_no_data_layout);
        searchNonmalLayout = (LinearLayout)findViewById(R.id.search_nonmal_layout);
        searchEditLayout = (LinearLayout)findViewById(R.id.search_edit_layout);
        centerImage = (ImageView)findViewById(R.id.center_image);
        locationIv = (ImageView)findViewById(R.id.location_iv);
        clearInputIv = (ImageView)findViewById(R.id.clear_input_iv);
        mCheckTipIv = (ImageView)findViewById(R.id.check_tip_iv);
    }

    private void initEvent() {
        mBaiduMap = mBmapView.getMap();
        adapter = new AddressSelectAdapter(this);
        adapter.setOnAddressSelectItemClickListener(this);
        mJARecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mJARecyclerView.addItemDecoration(new DefaultItemDecoration(this, R.dimen.common_utils_divider_height, R.color.src_line_c9));
        mJARecyclerView.setAdapter(adapter);
        mSearchAddressEt.setHint("搜索地点");
        searchAddressTv.setText("搜索地点");
        mSearchAddressEt.addTextChangedListener(new SearchDevicesTextWatcher());
        cancleTv.setText("取消");
        confirmTv.setText("确定");


        //加载动画
        mAnimation = new RotateAnimation(0, 359, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        mAnimation.setDuration(1000);
        mAnimation.setRepeatCount(-1);
        mAnimation.setInterpolator(new LinearInterpolator());
        mCheckTipIv.setColorFilter(getResources().getColor(R.color.src_c1));
        mCheckTipIv.setImageResource(R.mipmap.icon_login_loading);
        centerAnimation = AnimationUtils.loadAnimation(this, R.anim.center_anim);

        initMyLocation();
        mBaiduMap.setCompassEnable(false);


        searchNonmalLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                searchNonmalLayout.setVisibility(View.GONE);
                searchEditLayout.setVisibility(View.VISIBLE);
                showInput(mSearchAddressEt);
            }
        });

        clearInputIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                searchNonmalLayout.setVisibility(View.VISIBLE);
                searchEditLayout.setVisibility(View.GONE);
                mSearchAddressEt.setText("");
                mSearchAddressEt.clearFocus();
                hideSoftInputWindow(v);
                mFilterList.clear();
                if (mLoactionLatLng != null) {
                    MapStatus.Builder builder = new MapStatus.Builder();
                    builder.target(mLoactionLatLng).zoom(17.0f);
                    mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus
                            (builder.build()));
                    isUseGeoCoder = true;
                    isNeedAnimation = false;
                } else {
                }
            }
        });

        locationIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mLoactionLatLng != null) {
                    MapStatus.Builder builder = new MapStatus.Builder();
                    builder.target(mLoactionLatLng).zoom(17.0f);
                    mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus
                            (builder.build()));
                    isUseGeoCoder = true;
                    isNeedAnimation = true;
                } else {
                }
            }
        });
    }

    /**
     * 隐藏键盘
     */
    private void hideSoftInputWindow(View view) {
        if (inputMethodManager.isActive()) {
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }

    /**
     * 显示键盘
     * @param et 输入焦点
     */
    public void showInput(final EditText et) {
        et.requestFocus();
        if (inputMethodManager.isActive()) {
            inputMethodManager.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
        }
    }

    /**
     * 获取我的定位
     */
    private void initMyLocation() {
        // 初始化地图
        mBmapView.showZoomControls(false);
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);
        mBaiduMap.setMapStatus(msu);
        mInfoList = new ArrayList<PoiInfo>();
        mCenterPoint = mBaiduMap.getMapStatus().targetScreen;
        mLoactionLatLng = mBaiduMap.getMapStatus().target;

        // 定位
        mBaiduMap.setMyLocationEnabled(true);
        mLocationClient = new LocationClient(this);
        mListner = new MyBDLocationListner();
        mLocationClient.registerLocationListener(mListner);
        LocationClientOption option = new LocationClientOption();
        option.setCoorType("bd09ll");
        mLocationClient.setLocOption(option);
        mLocationClient.start();

        // 地理编码
        mGeoCoder = GeoCoder.newInstance();
        mGeoCoder.setOnGetGeoCodeResultListener(mGeoListener);

        showLoading(true);

        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                mBaiduMap.clear();
                adapter.changeSelected(0);
                mJARecyclerView.smoothScrollToPosition(0);
                MapStatusUpdate u = MapStatusUpdateFactory
                        .newLatLng(latLng);
                mBaiduMap.animateMapStatus(u);
                isUseGeoCoder = true;
            }

            @Override
            public boolean onMapPoiClick(MapPoi mapPoi) {
                LatLng position = mapPoi.getPosition();
                mBaiduMap.clear();
                MapStatusUpdate u = MapStatusUpdateFactory
                        .newLatLng(position);
                mBaiduMap.animateMapStatus(u);
                isUseGeoCoder = true;
                return true;

            }
        });


        mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener() {
            @Override
            public void onTouch(MotionEvent motionEvent) {
                if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                    isUseGeoCoder = true;
                    isNeedAnimation = true;
                }
            }
        });

        mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
            @Override
            public void onMapStatusChangeStart(MapStatus mapStatus) {
            }

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

            @Override
            public void onMapStatusChange(MapStatus mapStatus) {
            }

            @Override
            public void onMapStatusChangeFinish(MapStatus mapStatus) {
                mBaiduMap.clear();
                if (isNeedAnimation) {
                    centerImage.startAnimation(centerAnimation);
                }
                LatLng target = mapStatus.target;
                if (isUseGeoCoder) {
                    showLoading(true);
                    mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                            .location(target));
                    adapter.changeSelected(0);
                    mJARecyclerView.smoothScrollToPosition(0);
                }
            }
        });
        mSuggestionSearch = SuggestionSearch.newInstance();
        mSuggestionSearch.setOnGetSuggestionResultListener(listener);
    }


    OnGetSuggestionResultListener listener = new OnGetSuggestionResultListener() {
        @Override
        public void onGetSuggestionResult(SuggestionResult suggestionResult) {
            //处理sug检索结果
            List<SuggestionResult.SuggestionInfo> allSuggestions = suggestionResult.getAllSuggestions();
            mInfoList.clear();
            if (allSuggestions == null) {

            }else {
                for (SuggestionResult.SuggestionInfo suggestionInfo : allSuggestions) {
                    if (suggestionInfo == null) {
                        continue;
                    }
                    PoiInfo info = new PoiInfo();
                    info.address = suggestionInfo.getKey();
                    LatLng pt = suggestionInfo.pt;
                    info.location = pt;
                    info.city = suggestionInfo.city;
                    info.name = suggestionInfo.getKey();
                    mInfoList.add(info);
                }
                selPoiDetailInfo = mInfoList.get(0);
                mkolSearchRecords = mOffline.searchCity(selPoiDetailInfo.getCity());
                selectCityCode = String.valueOf(mkolSearchRecords.get(0).cityID);
            }
            handleRelativeAddressResult(mInfoList, changeContent);
        }
    };

    @Override
    public void onAddressSelectItemClick(PoiInfo info, int position) {
        isUseGeoCoder = false;
        isNeedAnimation = true;
        mBaiduMap.clear();
        LatLng la = info.location;
        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(la);
        mBaiduMap.animateMapStatus(u);
        selPoiDetailInfo = info;
        adapter.changeSelected(position);
        if (position != 0) {
            mkolSearchRecords = mOffline.searchCity(selPoiDetailInfo.getCity());
            selectCityCode = String.valueOf(mkolSearchRecords.get(0).cityID);
        }
        if (BuildConfig.DEBUG) {
            Log.d("lyw", "onAddressSelectItemClick-cityCode->" + info.city+selectCityCode);
        }
    }


    // 定位监听器
    private class MyBDLocationListner implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null || mBmapView == null){
                return;
            }
            if (isFirstLoc) {
                MyLocationData data = new MyLocationData.Builder()
                        .accuracy(location.getRadius())
                        .latitude(location.getLatitude())
                        .longitude(location.getLongitude())
                        .build();
                mBaiduMap.setMyLocationData(data);
                MyLocationConfiguration config = new MyLocationConfiguration(
                        MyLocationConfiguration.LocationMode.NORMAL, false, null);
                mBaiduMap.setMyLocationConfigeration(config);
                mLantitude = location.getLatitude();
                mLongtitude = location.getLongitude();
                LatLng currentLatLng = new LatLng(mLantitude, mLongtitude);
                mLoactionLatLng = new LatLng(mLantitude, mLongtitude);
                isFirstLoc = false;
                MapStatusUpdate u = MapStatusUpdateFactory
                        .newLatLng(currentLatLng);
                mBaiduMap.animateMapStatus(u);
                mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                        .location(currentLatLng));
            }
        }
    }

    /**
     * 地理编码监听器
     */
    OnGetGeoCoderResultListener mGeoListener = new OnGetGeoCoderResultListener() {
        @Override
        public void onGetGeoCodeResult(GeoCodeResult result) {
        }

        @Override
        public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
            if (BuildConfig.DEBUG) {
                Log.d("lyw","result.error-->" + result.error);
            }
            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                if (result.error == SearchResult.ERRORNO.NETWORK_ERROR) {
                    showLoading(false);
                    Toast.makeText(SelectAddressActivity.this,"网络异常",Toast.LENGTH_SHORT).show();
                }
            } else {
                showLoading(false);
                mCurentInfo = new PoiInfo();
                mCurentInfo.address = result.getAddress();
                mCurentInfo.location = result.getLocation();
                mCurentInfo.name = result.getAddress();
                mCurentInfo.city = String.valueOf(result.getCityCode());
                selectCityCode = String.valueOf(result.getCityCode());
                mInfoList.clear();
                mInfoList.add(mCurentInfo);
                if (result.getPoiList() != null) {
                    mInfoList.addAll(result.getPoiList());
                }
                adapter.setPoiAddrList(mInfoList);
                adapter.notifyDataSetChanged();
                selPoiDetailInfo = mInfoList.get(0);
            }
        }
    };


    class SearchDevicesTextWatcher implements TextWatcher {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int start, int count, int before) {
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
            changeContent = charSequence.toString();
            if (changeContent != null && !changeContent.isEmpty() || !"".equals(changeContent)) {
                mSuggestionSearch.requestSuggestion(new SuggestionSearchOption().city("中国").keyword(changeContent));
            }else {
                if (mLoactionLatLng != null) {
                    MapStatus.Builder builder = new MapStatus.Builder();
                    builder.target(mLoactionLatLng).zoom(17.0f);
                    mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus
                            (builder.build()));
                    isUseGeoCoder = true;
                    isNeedAnimation = false;
                } else {
                }
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {
        }
    }

    /**
     * 处理搜索地点结果
     *
     * @param mInfoList
     */
    private void handleRelativeAddressResult(List<PoiInfo> mInfoList, String content) {
        mJARecyclerView.setAdapter(adapter);
        adapter.setPoiAddrList(mInfoList);
        if (mInfoList.size() == 0) {
            searchNoDataLayout.setVisibility(View.VISIBLE);
            String formatContent = String.format("没有找到“%1$s”相关内容", content);
            SpannableStringBuilder builder = new SpannableStringBuilder(formatContent);
            ForegroundColorSpan blueSpan = new ForegroundColorSpan(getResources().getColor(R.color.src_text_c16));
            int start = formatContent.indexOf(content);
            int end = start + content.length();
            builder.setSpan(blueSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            searchNoDataTv.setText(builder);
        } else {
            searchNoDataLayout.setVisibility(View.GONE);
        }
    }


    /**
     * Loading的显示
     * @param isShowLoading
     */
    private void showLoading(final boolean isShowLoading){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isShowLoading) {
                    mCheckTipIv.setVisibility(View.VISIBLE);
                    mCheckTipIv.setImageResource(R.mipmap.icon_login_loading);
                    mCheckTipIv.setAnimation(mAnimation);
                    mCheckTipIv.getAnimation().start();
                }else {
                    mCheckTipIv.clearAnimation();
                    mCheckTipIv.setVisibility(View.GONE);
                }
            }
        });
    }
}

main_activity_address_select_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    <ImageView
        android:layout_gravity="center"
        android:id="@+id/center_image"
        android:layout_width="40dp"
        android:layout_marginBottom="15dp"
        android:layout_height="40dp"
        android:src="@mipmap/icon_positioning" />


    <ImageView
        android:id="@+id/location_iv"
        android:layout_gravity="center|end"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginEnd="10dp"
        android:src="@mipmap/icon_map_locate" />


    <RelativeLayout
        android:background="@drawable/background_gradient"
        android:paddingTop="35dp"
        android:paddingBottom="40dp"
        android:paddingStart="10dp"
        android:paddingEnd="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/cancle_tv"
            android:textColor="@color/src_white"
            android:gravity="center"
            android:layout_width="60dp"
            android:layout_height="30dp"/>
        <TextView
            android:id="@+id/confirm_tv"
            android:layout_alignParentEnd="true"
            android:background="@color/src_c46"
            android:gravity="center"
            android:textColor="@color/src_white"
            android:layout_width="60dp"
            android:layout_height="30dp"/>
    </RelativeLayout>


    <LinearLayout
        android:orientation="vertical"
        android:background="@color/common_utils_white"
        android:layout_gravity="bottom"
        android:layout_width="match_parent"
        android:layout_height="250dp">

        <LinearLayout
            android:id="@+id/search_nonmal_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="15dp"
            android:layout_marginTop="15dp"
            android:layout_marginEnd="15dp"
            android:layout_marginBottom="6dp"
            android:orientation="horizontal">

            <LinearLayout
                android:gravity="center"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@drawable/common_utils_shape_address_input_white_bg"
                android:focusable="true"
                android:focusableInTouchMode="true"
                android:orientation="horizontal"
                android:paddingTop="7dp"
                android:paddingBottom="7dp">

                <ImageView
                    android:layout_width="18dp"
                    android:layout_height="18dp"
                    android:layout_gravity="center_vertical"
                    android:layout_marginStart="13dp"
                    android:src="@mipmap/icon_search_1"/>

                <TextView
                    android:layout_marginStart="10dp"
                    android:id="@+id/search_address_tv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">

                </TextView>
            </LinearLayout>

        </LinearLayout>

        <!-- 搜索 -->
        <LinearLayout
            android:visibility="gone"
            android:id="@+id/search_edit_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="15dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="15dp"
            android:layout_marginBottom="6dp"
            android:orientation="horizontal">

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@drawable/common_utils_shape_address_input_white_bg"
                android:focusable="true"
                android:focusableInTouchMode="true"
                android:orientation="horizontal"
                android:paddingTop="7dp"
                android:paddingBottom="7dp">

                <ImageView
                    android:layout_width="18dp"
                    android:layout_height="18dp"
                    android:layout_gravity="center_vertical"
                    android:layout_marginStart="13dp"
                    android:src="@mipmap/icon_search_1"/>

                <EditText
                    android:id="@+id/search_address_et"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:layout_marginStart="17dp"
                    android:layout_weight="1"
                    android:background="@null"
                    android:maxLength="32"
                    android:maxLines="1"
                    android:singleLine="true"
                    android:textColor="@color/src_text_c1"
                    android:textColorHint="@color/src_text_c2"
                    android:textSize="@dimen/common_utils_font_14"/>

                <ImageView
                    android:id="@+id/clear_input_iv"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:layout_gravity="end|center_vertical"
                    android:layout_marginEnd="13dp"
                    android:src="@mipmap/icon_clear_enter_1"/>
            </LinearLayout>

        </LinearLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:layout_below="@+id/search_devices_layout"
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp" />

   
        <LinearLayout
            android:layout_below="@+id/search_devices_layout"
            android:layout_gravity="center"
            android:gravity="center"
            android:id="@+id/search_no_data_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/common_utils_white"
            android:orientation="vertical"
            android:visibility="gone">
            <TextView
                android:id="@+id/search_no_data_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="20dp"
                android:textColor="@color/src_text_c2"
                android:textSize="14sp"/>
        </LinearLayout>
    </LinearLayout>

    <ImageView
        android:id="@+id/check_tip_iv"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginBottom="75dp"
        android:layout_gravity="center|bottom"
        android:src="@mipmap/icon_login_loading"
        />
</FrameLayout>

background_gradient.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <!--实现应用背景颜色渐变-->
    <gradient
        android:startColor="@color/src_nvr"
        android:endColor="@color/common_utils_transparent"
        android:angle="270"/>
</shape>

common_utils_shape_address_input_white_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid  android:color="@color/baidu_serach_address_bg" />
    <stroke
        android:width="0.5dp"
        android:color="@color/common_utils_black_30_transparent" />
    <corners android:radius="5dp" />
</shape>

AddressSelectAdapter.class

package com.lyw.myproject.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.baidu.mapapi.search.core.PoiInfo;
import com.lyw.myproject.R;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;


/**
 * 功能描述:位置选择Adapter
 * Created on 2020/4/27.
 * @author lyw
 */
public class AddressSelectAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public Context mContext;
    private List<PoiInfo> infoList;
    private OnAddressSelectItemClickListener mItemClickListener;
    private int selectedPosition = 0;// 选中的位置

    public AddressSelectAdapter(Context context) {
        mContext = context;
        infoList = new ArrayList<>();
    }

    public void changeSelected(int positon){
        if(positon != selectedPosition){
            selectedPosition = positon;
            notifyDataSetChanged();
        }
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.main_item_poi_address,viewGroup,false));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        MyViewHolder hodler = (MyViewHolder) viewHolder;
        PoiInfo info = infoList.get(i);
        hodler.nameTv.setText(info.getName());
        hodler.addressTv.setText(info.getAddress());

        if (selectedPosition == i) {
            hodler.checkImageIv.setImageResource(R.mipmap.icon_select_address);
        }else {
            hodler.checkImageIv.setImageResource(0);
        }
    }

    @Override
    public int getItemCount() {
        return infoList.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder{
        TextView nameTv;
        TextView addressTv;
        ImageView checkImageIv;
        LinearLayout addressSelectItemLl;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            nameTv = (TextView)itemView.findViewById(R.id.name_tv);
            addressTv = (TextView)itemView.findViewById(R.id.address_tv);
            checkImageIv = (ImageView)itemView.findViewById(R.id.check_image_iv);
            addressSelectItemLl = (LinearLayout)itemView.findViewById(R.id.address_select_item_ll);
            addressSelectItemLl.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mItemClickListener != null) {
                        int posotion = getAdapterPosition();
                        mItemClickListener.onAddressSelectItemClick(infoList.get(posotion), posotion);
                    }
                }
            });
        }
    }

    public  void setPoiAddrList(List<PoiInfo> infos){
        infoList = infos;
    }

    public  void clearPoiAddrList(){
        infoList.clear();
    }


    public interface OnAddressSelectItemClickListener{
        void onAddressSelectItemClick(PoiInfo info, int position);
    }

    public void setOnAddressSelectItemClickListener(OnAddressSelectItemClickListener listener){
        mItemClickListener = listener;
    }
}

main_item_poi_address.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/address_select_item_ll"
    android:layout_width="match_parent"
    android:padding="10dp"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_marginStart="10dp"
        android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_weight="10"
        android:layout_height="wrap_content">
        <TextView
            android:textSize="16sp"
            android:id="@+id/name_tv"
            android:textColor="@color/src_black"
            android:layout_width="wrap_content"
            android:layout_height="20dp"/>
        <TextView
            android:textSize="14sp"
            android:id="@+id/address_tv"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>
    </LinearLayout>
    <LinearLayout
        android:layout_gravity="center"
        android:layout_weight="1"
        android:layout_margin="5dp"
        android:layout_width="0dp"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/check_image_iv"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="20dp"/>
    </LinearLayout>
</LinearLayout>

DefaultItemDecoration.class

扫描二维码关注公众号,回复: 11355660 查看本文章
package com.lyw.myproject.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.View;

import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes;
import androidx.recyclerview.widget.RecyclerView;

/**
 * Created on 2018/10/13.
 *
 * @author lyw
 **/
public class DefaultItemDecoration extends RecyclerView.ItemDecoration {
    private int mDivideHeight;
    private int mPaddingLeft;
    private int mPaddingRight;
    private Paint paint;

    public DefaultItemDecoration(Context context, @DimenRes int divideHeight, @ColorRes int divideColor) {
        this(context, divideHeight, divideColor, 0, 0);
    }

    public DefaultItemDecoration(Context context, @DimenRes int divideHeight, @ColorRes int divideColor, @DimenRes int paddingLeft, @DimenRes int paddingRight) {
        mDivideHeight = context.getResources().getDimensionPixelSize(divideHeight);
        if (paddingRight != 0) {
            mPaddingRight = context.getResources().getDimensionPixelSize(paddingRight);
        }

        if (paddingLeft != 0) {
            mPaddingLeft = context.getResources().getDimensionPixelSize(paddingLeft);
        }

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(context.getResources().getColor(divideColor));
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        int childCount = parent.getChildCount();
        int width = parent.getWidth();

        int top;
        int bottom;
        for (int i = 0; i < childCount; i++) {
            View childAt = parent.getChildAt(i);
            top = childAt.getBottom();
            bottom = top + mDivideHeight;
            c.drawRect(mPaddingLeft, top, width - mPaddingRight, bottom, paint);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.bottom = mDivideHeight;
    }
}

PermissionUtil.class

package com.lyw.myproject.utils;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;

/**
 * Created by lyw on 2017/6/12.
 */
public class PermissionUtil {
    /**
     * 请求地理位置
     *
     * @param context
     */
    public static void requestLocationPermission(Context context) {
        if (Build.VERSION.SDK_INT >= 23) {
            if (!isHasLocationPermission(context)) {
                ActivityCompat.requestPermissions((Activity) context, PermissionManager.PERMISSION_LOCATION, PermissionManager.REQUEST_LOCATION);
            }
        }
    }

    /**
     * 判断是否有地理位置
     *
     * @param context
     * @return
     */
    public static boolean isHasLocationPermission(Context context) {
        return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
    }
}

PermissionManager.class

package com.lyw.myproject.utils;

import android.Manifest;

/**
 * Created by lyw on 2017/5/17.
 */

public final class PermissionManager {

    /**
     * sd卡
     */
    public static final int REQUEST_SD_WRITE = 101;

    /**
     * 地理位置
     */
    public static final int REQUEST_LOCATION = 102;

    /**
     * 相机
     */
    public static final int REQUEST_CAMERA = 103;

    /**
     * 录音
     */
    public static final int REQUEST_RECORD = 104;

    /**
     * 读取手机
     */
    public static final int REQUEST_READ_PHONE = 105;

    /**
     * 悬浮窗通知
     */
    public static final int REQUEST_ALERT_WINDOW = 106;

    /**
     * 读取MEDIA权限
     */
    public static final int REQUEST_READ_MEDIA = 107;

    /**
     * Android Q(10) 读取MEDIA权限
     */
    public static final String[] PERMISSION_READ_MEDIA = new String[]{"android.permission.READ_MEDIA_IMAGES","android.permission.READ_MEDIA_VIDEO","android.permission.READ_MEDIA_AUDIO"};

    public static final String[] PERMISSION_SD_WRITE = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    public static final String[] PERMISSION_LOCATION = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
    public static final String[] PERMISSION_CAMERA = new String[]{Manifest.permission.CAMERA};
    public static final String[] PERMISSION_RECORD = new String[]{Manifest.permission.RECORD_AUDIO};
    public static final String[] PERMISSION_READ_PHONE = new String[]{Manifest.permission.READ_PHONE_STATE};

}

StatusBarUtils.class

package com.lyw.myproject.utils;

import android.app.Activity;
import android.app.Dialog;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

/**
 * Created by Administrator on 2017/7/6.
 * 状态栏相关工具
 */

public class StatusBarUtils {

    public static void setWindowStatusBarColor(Activity activity, int colorResId) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Window window = activity.getWindow();
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.setStatusBarColor(activity.getResources().getColor(colorResId));

                //底部导航栏
                //window.setNavigationBarColor(activity.getResources().getColor(colorResId));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void setWindowStatusBarColor(Dialog dialog, int colorResId) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Window window = dialog.getWindow();
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.setStatusBarColor(dialog.getContext().getResources().getColor(colorResId));

                //底部导航栏
                //window.setNavigationBarColor(activity.getResources().getColor(colorResId));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void makeStatusBarTransparent(Activity activity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        Window window = activity.getWindow();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            int option = window.getDecorView().getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
            window.getDecorView().setSystemUiVisibility(option);
            window.setStatusBarColor(Color.TRANSPARENT);
        } else {
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }
}

center_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fillBefore="true"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toXDelta="0"
    android:toYDelta="-100">

</translate>

FullscreenInputWorkaroundUtil.class

package com.lyw.myproject.utils;

import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

/**
 * 功能描述:解决状态栏沉浸式,软键盘遮住布局的问题
 * Created on 2020/6/18.
 *
 * @author lyw
 */
public class FullscreenInputWorkaroundUtil {
    public static void assistActivity(Activity activity) {
        new FullscreenInputWorkaroundUtil(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private FullscreenInputWorkaroundUtil(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard / 4)) {
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_28002747/article/details/106824547