自定義地圖選擇器
根據傳入的經緯度定位到指定位置,如果爲空就定位到當前所在位置
根據用戶輸入的字符串顯示poi聯想數據列表,點擊item把對應的位置顯示在地圖上
點擊確認按鈕根據eventbus將數據回傳
好了。話不多說,直接開衝!!!
MapActivity
package cn.sunsapp.owner.controller.activity;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.amap.api.location.AMapLocation;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.basic.lattercore.activities.DBBaseActivity;
import com.basic.lattercore.util.SunsToastUtils;
import com.basic.lattercore.util.click.AntiShakeUtils;
import com.basic.lattercore.util.event.EventBusUtils;
import com.basic.lattercore.util.event.EventMessage;
import com.blankj.utilcode.util.LogUtils;
import com.heytap.mcssdk.utils.LogUtil;
import com.tencent.mm.opensdk.utils.Log;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
import cn.sunsapp.owner.EventCode;
import cn.sunsapp.owner.R;
import cn.sunsapp.owner.adapter.PoiListAdapter;
import cn.sunsapp.owner.adapter.SearchPlaceListAdapter;
import cn.sunsapp.owner.databinding.ActivityMapBinding;
import cn.sunsapp.owner.util.AMapLocationListener;
import cn.sunsapp.owner.util.AppUtil;
import cn.sunsapp.owner.viewmodel.DBMapActivityViewModel;
public class MapActivity extends DBBaseActivity implements PoiSearch.OnPoiSearchListener {
EditText etSearchCityPoi;
TextView tvEnsureCommitBtn;
MapView mvBranchAddressChoose;
RecyclerView rvBranchAddressChoose;
RecyclerView rvSearchByInputText;
MapView mapView;
private AMap aMap = null;
private PoiListAdapter poiListAdapter;
private SearchPlaceListAdapter searchAdapter;
private ActivityMapBinding mBinding;
private DBMapActivityViewModel mViewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewModelProvider viewModelProvider = new ViewModelProvider(this);
mViewModel = viewModelProvider.get(DBMapActivityViewModel.class);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_map);
mBinding.setLifecycleOwner(this);
mBinding.setModel(mViewModel);
onBindView(savedInstanceState);
}
protected void onBindView(Bundle savedInstanceState) {
initView();
initMap(savedInstanceState);
searchRange();
}
private void initMap(Bundle savedInstanceState) {
mapView = mBinding.mvBranchAddressChoose;
mapView.onCreate(savedInstanceState);
if (aMap == null) {
aMap = mapView.getMap();
}
MyLocationStyle myLocationStyle;
myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
myLocationStyle.showMyLocation(false);
myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));
myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));
mapView.getMap().setMyLocationEnabled(true);
mapView.getMap().setMyLocationStyle(myLocationStyle);
mapView.getMap().getUiSettings().setMyLocationButtonEnabled(true);
mapView.getMap().getUiSettings().setZoomControlsEnabled(false);
mapView.getMap().getUiSettings().setScaleControlsEnabled(true);
mapView.getMap().getUiSettings().setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_RIGHT);
mapView.getMap().setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
if (location == null) {
return;
}
Marker marker;
MarkerOptions markerOptions;
markerOptions = new MarkerOptions();
marker = mapView.getMap().addMarker(markerOptions);
int width = mapView.getRight() / 2;
int height = mapView.getBottom() / 2;
marker.setPositionByPixels(width, height);
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
if (!TextUtils.isEmpty(mViewModel.getProvLat()) && mViewModel.isFirstLoadList()) {
latLng = new LatLng(Double.valueOf(mViewModel.getProvLat()), Double.valueOf(mViewModel.getProvLng()));
}
moveCameraUpdate(mapView, latLng, 18f);
}
});
mapView.getMap().setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
}
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
if (cameraPosition == null) {
return;
}
if (mViewModel.isHandDrag() || mViewModel.isFirstLoadList()) {
LatLng target = cameraPosition.target;
AppUtil.getCircumInfo(mContext, target.latitude, target.longitude);
mViewModel.setFirstLoadList(false);
}
mViewModel.setHandDrag(true);
}
});
}
private void moveCameraUpdate(MapView mv, LatLng ll, Float zoom) {
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(ll, zoom);
mv.getMap().animateCamera(cameraUpdate);
}
private void initView() {
initToolbarNav(mBinding.toolbarContainer.toolbar);
mBinding.toolbarContainer.toolbarTitle.setText("地址選擇");
mViewModel.setEventCode(getIntent().getIntExtra("event_code", EventCode.CHOOSE_CITY_POI_SUCESS));
mViewModel.setProvLat(getIntent().getStringExtra("lat"));
mViewModel.setProvLng(getIntent().getStringExtra("lng"));
etSearchCityPoi = mBinding.etSearchCityPoi;
tvEnsureCommitBtn = mBinding.tvEnsureCommitBtn;
tvEnsureCommitBtn.setOnClickListener(v -> {
selectCity();
});
mvBranchAddressChoose = mBinding.mvBranchAddressChoose;
rvBranchAddressChoose = mBinding.rvBranchAddressChoose;
rvSearchByInputText = mBinding.rvSearchByInputText;
rvBranchAddressChoose.setLayoutManager(new LinearLayoutManager(mContext));
poiListAdapter = new PoiListAdapter(R.layout.item_branch_poi_list);
rvBranchAddressChoose.setAdapter(poiListAdapter);
poiListAdapter.setOnItemClickListener((adapter, view, position) -> {
poiListAdapter.changeCheckedPositon(position);
double latlonPointLat = poiListAdapter.getItem(position).getLatLonPoint().getLatitude();
double latlngPointLng = poiListAdapter.getItem(position).getLatLonPoint().getLongitude();
LatLng latLngPoint = new LatLng(latlonPointLat, latlngPointLng);
mViewModel.setHandDrag(false);
moveCameraUpdate(mapView, latLngPoint, 18f);
});
rvSearchByInputText.setLayoutManager(new LinearLayoutManager(mContext));
searchAdapter = new SearchPlaceListAdapter(R.layout.item_branch_poi_list);
rvSearchByInputText.setAdapter(searchAdapter);
searchAdapter.setOnItemClickListener((adapter, view, position) -> {
double selectLat = searchAdapter.getItem(position).getLatLonPoint().getLatitude();
double selectLng = searchAdapter.getItem(position).getLatLonPoint().getLongitude();
ArrayList<PoiItem> data = new ArrayList<>();
data.add(searchAdapter.getItem(position));
poiListAdapter.setNewData(data);
poiListAdapter.changeCheckedPositon(0);
LatLng selectPoint = new LatLng(selectLat, selectLng);
moveCameraUpdate(mapView, selectPoint, 18f);
mViewModel.setSearchClick(true);
mViewModel.getShowSearchList().setValue(false);
});
}
private void searchRange() {
mViewModel.getSearchWords().observe(this, s -> {
mViewModel.getShowSearchList().setValue(true);
if (s.trim().length() == 0) {
mViewModel.getShowSearchList().setValue(false);
}
PoiSearch.Query query = new PoiSearch.Query(s, "", "");
query.setPageSize(50);
query.setPageNum(1);
PoiSearch poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.searchPOIAsyn();
});
}
public void selectCity() {
PoiItem item = poiListAdapter.getItem(poiListAdapter.getCheckedPosition());
if (item != null) {
mViewModel.getEventMap().put("prov", item.getProvinceName());
mViewModel.getEventMap().put("city", item.getCityName());
mViewModel.getEventMap().put("county", item.getAdName());
if ("".equals(item.getSnippet())) {
mViewModel.getEventMap().put("detail", item.getTitle());
} else {
mViewModel.getEventMap().put("detail", item.getSnippet());
}
mViewModel.getEventMap().put("lat", item.getLatLonPoint().getLatitude());
mViewModel.getEventMap().put("lng", item.getLatLonPoint().getLongitude());
EventBusUtils.post(new EventMessage(mViewModel.getEventCode(), mViewModel.getEventMap()));
}
finish();
}
@Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
mapView.onSaveInstanceState(outState);
}
@Override
protected boolean isRegisteredEventBus() {
return true;
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onGetMessage(EventMessage message) {
switch (message.getCode()) {
case EventCode.BRANCH_ADDRESS_LOCATION_POI:
List<PoiItem> poiData = (List) message.getData();
rvBranchAddressChoose.scrollToPosition(0);
poiListAdapter.changeCheckedPositon(0);
if (mViewModel.isSearchClick()) {
poiListAdapter.addData(poiData);
} else {
poiListAdapter.setNewData(poiData);
}
mViewModel.setSearchClick(false);
EventBusUtils.removeSticky(message);
break;
}
}
@Override
public void onPoiSearched(PoiResult poiResult, int i) {
ArrayList<PoiItem> pois = poiResult.getPois();
searchAdapter.setNewData(pois);
}
@Override
public void onPoiItemSearched(PoiItem poiItem, int i) {
}
}
activity_map.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<import type="cn.sunsapp.owner.viewmodel.DBMapActivityViewModel"/>
<import type="android.view.View"/>
<variable
name="model"
type="DBMapActivityViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include android:id="@+id/toolbarContainer" layout="@layout/toolbar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@color/white"
android:orientation="horizontal">
<EditText
android:id="@+id/et_search_city_poi"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginTop="8dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="8dp"
android:layout_weight="1"
android:background="#FFF6F6F6"
android:drawableLeft="@drawable/search"
android:drawablePadding="11dp"
android:ellipsize="end"
android:hint="請輸入網點地址"
android:paddingLeft="10dp"
android:singleLine="true"
android:textColor="@color/normal_text"
android:textColorHint="#FFC2C2C2"
android:textSize="14sp"
android:text="@={model.searchWords}"
/>
<TextView
android:id="@+id/tv_ensure_commit_btn"
style="@style/style_tv_no_font_padding"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="8dp"
android:background="@drawable/shaper_radius5_red_bg"
android:gravity="center"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="確認"
android:textColor="@color/white"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_map_and_poi_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="@{model.showSearchList == true?View.GONE:View.VISIBLE}">
<com.amap.api.maps.MapView
android:id="@+id/mv_branch_address_choose"
android:layout_width="match_parent"
android:layout_height="250dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_branch_address_choose"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_search_place"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="@{model.showSearchList == true?View.VISIBLE:View.GONE}"
>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_search_by_input_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</layout>
PoiListAdapter
package cn.sunsapp.owner.adapter;
import androidx.annotation.NonNull;
import com.amap.api.services.core.PoiItem;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import cn.sunsapp.owner.R;
import static com.blankj.utilcode.util.ColorUtils.getColor;
public class PoiListAdapter extends BaseQuickAdapter<PoiItem, BaseViewHolder> {
public PoiListAdapter(int resLayoutId) {
super(resLayoutId);
}
private int checkedPosition = 0;
public int getCheckedPosition() {
return checkedPosition;
}
@Override
protected void convert(@NonNull BaseViewHolder helper, PoiItem item) {
helper.setText(R.id.tv_poi_address_name, item.getTitle());
helper.setText(R.id.tv_address_poi_detail_info, item.getSnippet());
if (checkedPosition == helper.getLayoutPosition()) {
helper.setBackgroundRes(R.id.textView21, R.drawable.btn_shape);
helper.setTextColor(R.id.tv_poi_address_name, getColor(R.color.red));
} else {
helper.setBackgroundRes(R.id.textView21, R.drawable.selector_poi_item_ischoose);
helper.setTextColor(R.id.tv_poi_address_name, getColor(R.color.black));
}
}
public void changeCheckedPositon(Integer position) {
this.checkedPosition = position;
this.notifyDataSetChanged();
}
}
SearchPlaceListAdapter
package cn.sunsapp.owner.adapter;
import androidx.annotation.NonNull;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.help.Tip;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import cn.sunsapp.owner.R;
public class SearchPlaceListAdapter extends BaseQuickAdapter<PoiItem, BaseViewHolder> {
public SearchPlaceListAdapter(int resLayoutId) {
super(resLayoutId);
}
@Override
protected void convert(@NonNull BaseViewHolder helper, PoiItem item) {
helper.setText(R.id.tv_poi_address_name, item.getTitle());
helper.setText(R.id.tv_address_poi_detail_info, item.getSnippet());
}
}
DBMapActivityViewModel
package cn.sunsapp.owner.viewmodel;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.blankj.utilcode.util.LogUtils;
import java.util.WeakHashMap;
public class DBMapActivityViewModel extends ViewModel {
private MutableLiveData<String> searchWords = new MutableLiveData<>();
public MutableLiveData<String> getSearchWords() {
return searchWords;
}
private MutableLiveData<Boolean> showSearchList = new MutableLiveData<>();
public MutableLiveData<Boolean> getShowSearchList() {
return showSearchList;
}
public DBMapActivityViewModel() {
showSearchList.setValue(false);
}
private boolean isHandDrag = true;
private boolean isFirstLoadList = true;
private boolean isSearchClick = false;
private int eventCode;
private WeakHashMap<String, Object> eventMap = new WeakHashMap<>();
String hasAddress = "";
String provLat = "";
String provLng = "";
public String getHasAddress() {
return hasAddress;
}
public void setHasAddress(String hasAddress) {
this.hasAddress = hasAddress;
}
public String getProvLat() {
return provLat;
}
public void setProvLat(String provLat) {
this.provLat = provLat;
}
public String getProvLng() {
return provLng;
}
public void setProvLng(String provLng) {
this.provLng = provLng;
}
public boolean isSearchClick() {
return isSearchClick;
}
public void setSearchClick(boolean searchClick) {
isSearchClick = searchClick;
}
public int getEventCode() {
return eventCode;
}
public void setEventCode(int eventCode) {
this.eventCode = eventCode;
}
public WeakHashMap<String, Object> getEventMap() {
return eventMap;
}
public void setEventMap(WeakHashMap<String, Object> eventMap) {
this.eventMap = eventMap;
}
public boolean isHandDrag() {
return isHandDrag;
}
public void setHandDrag(boolean handDrag) {
isHandDrag = handDrag;
}
public boolean isFirstLoadList() {
return isFirstLoadList;
}
public void setFirstLoadList(boolean firstLoadList) {
isFirstLoadList = firstLoadList;
}
}
總結
這個MapActivity用到了兩個adapter,一個是根據經緯度獲取附近poi聯想數據的adapter(PoiListAdapter),一個是根據用戶輸入的字符串獲取到的聯想數據(SearchPlaceListAdapter),點擊確認按鈕,將選中的item相應的數據傳回。
有啥問題或者我哪裏有寫的不對的地方歡迎在評論區留言,行行好吧,點個贊加個關注吧,蟹蟹您了!