首先先上一张开发效果图:
效果是模仿微信的发送位置,项目的框架上采用mvp模式,并用了我自己写的一套lib,地址ndileber
首先界面上的开发,我简单粘贴代码(笑)
activity_location_baidu.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"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/g_child_page_bg_color">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:titleTextAppearance="@style/Toolbar.TitleText">
<include layout="@layout/nim_action_bar_right_clickable_tv" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/search_view"
android:layout_above="@+id/search_list"
>
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />
<LinearLayout
android:id="@+id/location_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/location_pin"
android:layout_centerHorizontal="true"
android:background="@drawable/marker_info_bg"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:visibility="gone">
<TextView
android:id="@+id/marker_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/location_map"
android:textColor="@color/white"
android:textSize="12sp" />
</LinearLayout>
<Button
android:id="@+id/my_location"
android:layout_width="@dimen/friend_map_btn_height"
android:layout_height="@dimen/friend_map_btn_height"
android:background="@drawable/btn_location_selector"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginBottom="17dp" />
<ImageView
android:id="@+id/location_pin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/pin"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<!--<View-->
<!--android:id="@+id/assist_my_location"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="24dip"-->
<!--android:layout_alignParentBottom="true" />-->
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="230dp"
android:id="@+id/search_list"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true">
</android.support.v7.widget.RecyclerView>
<!--<EditText-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:id="@+id/search_text"-->
<!--android:layout_below="@+id/app_bar_layout"-->
<!--android:imeOptions="actionSearch"-->
<!--android:singleLine="true"-->
<!--android:inputType="text"-->
<!--android:layout_centerHorizontal="true" />-->
<include
android:id="@+id/search_view"
layout="@layout/search_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/app_bar_layout"/>
</RelativeLayout>
cell的界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="来广营"
android:textColor="@color/black"
android:textSize="@dimen/recy_kicatuib_item_title"
android:id="@+id/location_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="北京市朝阳区"
android:textSize="@dimen/recy_kicatuib_item_content"
android:textColor="#595959"
android:id="@+id/location_local" />
</LinearLayout>
当然很多资源文件我懒得剔除了,大家自己把资源那块全换为具体数值吧
LocationAdapter的代码,由于我写了两套,一套是百度地图的,一套是高德地图的,里面有切换方式,大家可以吧高德地图的那块去掉。
public class LocationAdapter extends RecyclerView.Adapter<LocationAdapter.LocationViewHolder>{
List<PoiItem> poiItems = null;
List<PoiInfo> poiInfos = null;
LocationAmapActivity.LocationOnCreateItem locationOnCreateItem = null;
LocationBaiduActivity.LocationOnCreateItem locationOnCreateItem2 = null;
public LocationAdapter(List<PoiItem> poiItems,LocationAmapActivity.LocationOnCreateItem locationOnCreateItem){
this.poiItems = poiItems;
this.locationOnCreateItem = locationOnCreateItem;
}
public LocationAdapter(List<PoiInfo> poiInfos, LocationBaiduActivity.LocationOnCreateItem locationOnCreateItem){
this.poiInfos = poiInfos;
this.locationOnCreateItem2 = locationOnCreateItem;
}
public void refData(List<PoiItem> poiItems){
this.poiItems = poiItems;
notifyDataSetChanged();
}
public void refData2(List<PoiInfo> poiInfos){
this.poiInfos = poiInfos;
notifyDataSetChanged();
}
@Override
public LocationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recy_location_item, parent, false);
return new LocationViewHolder(view);
}
@Override
public void onBindViewHolder(final LocationViewHolder holder, int position) {
if(App.MAP_TYPE == App.MAP_BAIDU){
holder.poiInfo = poiInfos.get(position);
holder.location_name.setText(holder.poiInfo.name);
holder.location_local.setText(holder.poiInfo.address);
if(locationOnCreateItem2!=null){
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
locationOnCreateItem2.onItemClick(holder.poiInfo);
}
});
}
}else{
holder.poiItem = poiItems.get(position);
holder.location_name.setText(holder.poiItem.getTitle());
holder.location_local.setText(holder.poiItem.getSnippet());
Logger.d(holder.poiItem.getCityName()+holder.poiItem.getProvinceName()+holder.poiItem.getSnippet()+holder.poiItem.getWebsite());
if(locationOnCreateItem!=null){
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
locationOnCreateItem.onItemClick(holder.poiItem);
}
});
}
}
}
@Override
public int getItemCount() {
if(App.MAP_TYPE == App.MAP_BAIDU){
if(poiInfos==null){
return 0;
}else{
return poiInfos.size();
}
}else{
if(poiItems==null){
return 0;
}else{
return poiItems.size();
}
}
}
public class LocationViewHolder extends RecyclerView.ViewHolder{
private final View mView;
private PoiItem poiItem;
private PoiInfo poiInfo;
private final TextView location_name;
private final TextView location_local;
public LocationViewHolder(View itemView) {
super(itemView);
mView = itemView;
location_name = (TextView) itemView.findViewById(R.id.location_name);
location_local = (TextView) itemView.findViewById(R.id.location_local);
}
}
}
建立接口的连接器:Contract
LocationBaiduContract.java
public interface LocationBaiduContract extends BaseContract{
public interface View extends BaseView<Presenter>{
void setAddress(String address);
void refData(List<PoiInfo> poiInfoList);
void sendButtonStatus(int status);
void pinInfoPanelStatus(int status);
MapView getMapView();
void keybordState(boolean show);
void searchText(String text);
void setPinInfoText(String text);
String getSearchText();
void deleteVisibility(int visiblility);
}
public interface Presenter extends BasePresenter,NimLocationManager.NimLocationListener,
android.view.View.OnClickListener,BaiduMap.OnMapStatusChangeListener,OnGetGeoCoderResultListener,OnGetPoiSearchResultListener,BDLocationListener,LocationBaiduActivity.LocationOnCreateItem,TextWatcher,TextView.OnEditorActionListener {
void initMap();
}
}
建立presenter,来操作业务,里面大部分代码都是百度地图开发的代码,基本不解释了
LocationBaiduPresenter.java
public class LocationBaiduPresenter implements LocationBaiduContract.Presenter{
LocationBaiduContract.View view;
public LocationBaiduPresenter(LocationBaiduContract.View view){
this.view = Check.checkNotNull(view, "view cannot be null!");
this.view.setPresenter(this);
}
@Override
public void start() {
}
@Override
public void onDestroy() {
// 退出时销毁定位
mLocClient.stop();
// 关闭定位图层
mBaiduMap.setMyLocationEnabled(false);
mSearch.destroy();
}
private double latitude; // 经度
private double longitude; // 维度
private boolean isChick = false;
private String addressInfo; // 对应的地址信息
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result == null result.error != SearchResult.ERRORNO.NO_ERROR) {
view.toast( "未找到结果", Toast.LENGTH_LONG);
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
if(!isChick){
view.setAddress(result.getAddress());
latitude = result.getLocation().latitude;
longitude = result.getLocation().longitude;
addressInfo = result.getAddress();
}
isChick = false;
List<PoiInfo> poiInfoList = result.getPoiList();
view.refData(poiInfoList);
return;
}
}
@Override
public void onGetPoiResult(PoiResult result) {
if (result == null result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
view.toast( "未找到结果", Toast.LENGTH_LONG);
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
view.refData(result.getAllPoi());
return;
}
}
@Override
public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
}
@Override
public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
}
@Override
public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
}
@Override
public void onLocationChanged(NimLocation location) {
}
private boolean isButtonLoc = false;
LocationClient mLocClient;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.my_location:
isButtonLoc = true;
mLocClient.start();
break;
case R.id.action_bar_right_clickable_textview:
sendLocation();
((Activity)(view.getContext())).finish();
break;
case R.id.dileber_search_editext_delete:
view.searchText("");
break;
case R.id.dileber_search_editext_button:
search(view.getSearchText());
break;
}
}
PoiSearch mPoiSearch;
private void search(String message){
mPoiSearch.searchNearby(new PoiNearbySearchOption().keyword(message).location(new LatLng(latitude,longitude)).radius(500).pageNum(1));
view.keybordState(false);
view.searchText("");
}
@Override
public void initMap() {
mBaiduMap = view.getMapView().getMap();
// 开启定位图层
mBaiduMap.setMyLocationEnabled(true);
// 定位初始化
mLocClient = new LocationClient(view.getContext());
mLocClient.registerLocationListener(this);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); // 打开gps
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(1000);
mLocClient.setLocOption(option);
mLocClient.start();
mBaiduMap.setOnMapStatusChangeListener(this);
mSearch = GeoCoder.newInstance();
mSearch.setOnGetGeoCodeResultListener(this);
mPoiSearch = PoiSearch.newInstance();
mPoiSearch.setOnGetPoiSearchResultListener(this);
}
private static LocationProvider.Callback mCallback;
public static void start(Context context, LocationProvider.Callback callback) {
mCallback = callback;
context.startActivity(new Intent(context, LocationBaiduActivity.class));
}
private void sendLocation() {
addressInfo = TextUtils.isEmpty(addressInfo) ? MainApplication.getAppContext().getString(R.string.location_address_unkown) : addressInfo;
if (mCallback != null) {
mCallback.onSuccess(longitude, latitude, addressInfo);
}
}
/**
* 手势操作地图,设置地图状态等操作导致地图状态开始改变。
* @param mapStatus 地图状态改变开始时的地图状态
*/
@Override
public void onMapStatusChangeStart(MapStatus mapStatus) {
}
/**
* 地图状态变化中
* @param mapStatus 当前地图状态
*/
@Override
public void onMapStatusChange(MapStatus mapStatus) {
}
/**
* 地图状态改变结束
* @param mapStatus 地图状态改变结束后的地图状态
*/
@Override
public void onMapStatusChangeFinish(MapStatus mapStatus) {
LatLng ll=mapStatus.target;
Logger.d("map change sts ch fs:"+ll.latitude+","+ll.longitude+"");
searchNearBy(ll);
}
GeoCoder mSearch;
public void searchNearBy(LatLng latLng){
mSearch.reverseGeoCode(new ReverseGeoCodeOption()
.location(latLng));
}
boolean isFirstLoc = true; // 是否首次定位
BaiduMap mBaiduMap;
@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null view.getMapView() == null) {
return;
}
view.sendButtonStatus(View.VISIBLE);
view.pinInfoPanelStatus(View.VISIBLE);
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
if (isFirstLocisButtonLoc) {
isFirstLoc = false;
isButtonLoc = false;
LatLng ll = new LatLng(location.getLatitude(),
location.getLongitude());
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(ll).zoom(18.0f);
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
searchNearBy(ll);
}
mLocClient.stop();
}
@Override
public void onItemClick(PoiInfo poiInfo) {
view.setPinInfoText(poiInfo.name);
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(poiInfo.location).zoom(18.0f);
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
latitude = poiInfo.location.latitude;
longitude = poiInfo.location.longitude;
addressInfo = poiInfo.name;
isChick = true;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
int size = view.getSearchText().length();
if(size>0){
view.deleteVisibility(View.VISIBLE);
}else{
view.deleteVisibility(View.GONE);
}
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
search(view.getSearchText());
}
return false;
}
}