Merge branch 'feature/v1.0.0' of gitlab.zhidaoauto.com:ecos/yycp-service/Launcher into feature/v1.0.0
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package com.mogo.module.common;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-02
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class TextWatcherAdapter implements TextWatcher {
|
||||
|
||||
@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 ) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -36,16 +36,16 @@ dependencies {
|
||||
implementation rootProject.ext.dependencies.arouter
|
||||
annotationProcessor rootProject.ext.dependencies.aroutercompiler
|
||||
if (Boolean.valueOf(RELEASE)) {
|
||||
implementation rootProject.ext.dependencies.mogomap
|
||||
implementation rootProject.ext.dependencies.mogomapapi
|
||||
implementation rootProject.ext.dependencies.mogoutils
|
||||
api rootProject.ext.dependencies.mogomap
|
||||
api rootProject.ext.dependencies.mogomapapi
|
||||
api rootProject.ext.dependencies.mogoutils
|
||||
api rootProject.ext.dependencies.mogocommons
|
||||
api rootProject.ext.dependencies.mogoserviceapi
|
||||
implementation rootProject.ext.dependencies.modulecommon
|
||||
} else {
|
||||
implementation project(":libraries:mogo-map")
|
||||
implementation project(":libraries:mogo-map-api")
|
||||
implementation project(":foudations:mogo-utils")
|
||||
api project(":libraries:mogo-map")
|
||||
api project(":libraries:mogo-map-api")
|
||||
api project(":foudations:mogo-utils")
|
||||
api project(":foudations:mogo-commons")
|
||||
api project(':services:mogo-service-api')
|
||||
implementation project(':modules:mogo-module-common')
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.mogo.module.map.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import com.amap.api.location.AMapLocation;
|
||||
import com.amap.api.location.AMapLocationClient;
|
||||
import com.amap.api.location.AMapLocationClientOption;
|
||||
import com.amap.api.location.AMapLocationListener;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
public class AMapLocationManager {
|
||||
|
||||
private static final String TAG = "AMapLocationManager";
|
||||
|
||||
private static final Set< AMapLocationListener > mLocationChangeListeners = new HashSet<>();
|
||||
private static final InternalLocationListener mInternalLocationListener = new InternalLocationListener();
|
||||
|
||||
private AMapLocationClient mLocationClient;
|
||||
|
||||
private static AMapLocation sLastKnowLocation = null;
|
||||
|
||||
private static volatile AMapLocationManager sInstance;
|
||||
|
||||
public static AMapLocationManager getInstance( Context context ) {
|
||||
if ( sInstance == null ) {
|
||||
synchronized ( AMapLocationManager.class ) {
|
||||
if ( sInstance == null ) {
|
||||
sInstance = new AMapLocationManager( context );
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public synchronized void release() {
|
||||
stop();
|
||||
mLocationChangeListeners.clear();
|
||||
mLocationClient = null;
|
||||
sLastKnowLocation = null;
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
private AMapLocationManager( Context context ) {
|
||||
if ( context == null ) {
|
||||
throw new NullPointerException( "context can't be null." );
|
||||
}
|
||||
mLocationClient = new AMapLocationClient( context.getApplicationContext() );
|
||||
mLocationClient.setLocationListener( mInternalLocationListener );
|
||||
}
|
||||
|
||||
private void setLocationOptions( long locateInterval ) {
|
||||
AMapLocationClientOption option = new AMapLocationClientOption();
|
||||
option.setLocationMode( AMapLocationClientOption.AMapLocationMode.Hight_Accuracy );
|
||||
option.setNeedAddress( true );
|
||||
option.setInterval( locateInterval );
|
||||
if ( mLocationClient != null ) {
|
||||
mLocationClient.setLocationOption( option );
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void start() {
|
||||
start( 2000L );
|
||||
}
|
||||
|
||||
public synchronized void start( long locateInterval ) {
|
||||
if ( mLocationClient != null && mLocationClient.isStarted() ) {
|
||||
stop();
|
||||
}
|
||||
setLocationOptions( locateInterval );
|
||||
mLocationClient.startLocation();
|
||||
Log.d( TAG, "start location, location interval is " + locateInterval );
|
||||
}
|
||||
|
||||
public synchronized void stop() {
|
||||
if ( mLocationClient != null ) {
|
||||
mLocationClient.stopLocation();
|
||||
}
|
||||
Log.d( TAG, "stop location" );
|
||||
}
|
||||
|
||||
public static AMapLocation getAMapLastKnowLocation() {
|
||||
return sLastKnowLocation;
|
||||
}
|
||||
|
||||
public static LatLng getLastKnowPoint() {
|
||||
final AMapLocation location = getAMapLastKnowLocation();
|
||||
if ( location != null ) {
|
||||
return new LatLng( location.getLatitude(), location.getLongitude() );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addLocationListener( AMapLocationListener listener ) {
|
||||
if ( listener != null ) {
|
||||
synchronized ( mLocationChangeListeners ) {
|
||||
mLocationChangeListeners.add( listener );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeLocationListener( AMapLocationListener listener ) {
|
||||
synchronized ( mLocationChangeListeners ) {
|
||||
mLocationChangeListeners.remove( listener );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位SDK监听函数
|
||||
*/
|
||||
private static class InternalLocationListener implements AMapLocationListener {
|
||||
@Override
|
||||
public void onLocationChanged( AMapLocation aMapLocation ) {
|
||||
if ( aMapLocation == null ||
|
||||
aMapLocation.getLatitude() == 0.0D ||
|
||||
aMapLocation.getLongitude() == 0.0D ) {
|
||||
return;
|
||||
}
|
||||
sLastKnowLocation = aMapLocation.clone();
|
||||
synchronized ( mLocationChangeListeners ) {
|
||||
Iterator iterator = mLocationChangeListeners.iterator();
|
||||
while ( iterator.hasNext() ) {
|
||||
AMapLocationListener listener = ( AMapLocationListener ) iterator.next();
|
||||
listener.onLocationChanged( sLastKnowLocation );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.mogo.module.map.location;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-09-27
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class LocationUtils {
|
||||
|
||||
public static float bearing( double lat1, double lon1, double lat2, double lon2 ) {
|
||||
|
||||
double longitude1 = lon1;
|
||||
double longitude2 = lon2;
|
||||
double latitude1 = Math.toRadians( lat1 );
|
||||
double latitude2 = Math.toRadians( lat2 );
|
||||
double longDiff = Math.toRadians( longitude2 - longitude1 );
|
||||
double y = Math.sin( longDiff ) * Math.cos( latitude2 );
|
||||
double x = Math.cos( latitude1 ) * Math.sin( latitude2 ) - Math.sin( latitude1 ) * Math.cos( latitude2 ) * Math
|
||||
.cos( longDiff );
|
||||
|
||||
double result = ( Math.toDegrees( Math.atan2( y, x ) ) + 360 ) % 360;
|
||||
if ( ( ( int ) result ) == ( ( int ) ( result + 0.5 ) ) ) {
|
||||
return ( ( int ) result );
|
||||
} else {
|
||||
return ( ( int ) result ) + 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.mogo.module.map.location;
|
||||
|
||||
import com.amap.api.maps.model.MyLocationStyle;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-17
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class MyLocationUtils {
|
||||
|
||||
public static final long INTERVAL_FAST_SPEED = 2_000L;
|
||||
public static final long INTERVAL_MIDDLE_SPEED = 2_000L;
|
||||
public static final long INTERVAL_SLOW_SPEED = 10_000L;
|
||||
|
||||
/**
|
||||
* 前台快速定位
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static MyLocationStyle wrapperAsFast( MyLocationStyle style ) {
|
||||
if ( style != null ) {
|
||||
style.interval( INTERVAL_FAST_SPEED );
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台慢速定位
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static MyLocationStyle wrapperAsMiddleSpeed( MyLocationStyle style ) {
|
||||
if ( style != null ) {
|
||||
style.interval( INTERVAL_MIDDLE_SPEED );
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台慢速定位
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static MyLocationStyle wrapperAsSlow( MyLocationStyle style ) {
|
||||
if ( style != null ) {
|
||||
style.interval( INTERVAL_SLOW_SPEED );
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,6 +27,11 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -38,8 +43,13 @@ dependencies {
|
||||
implementation rootProject.ext.dependencies.room
|
||||
annotationProcessor rootProject.ext.dependencies.roomAnnotationProcessor
|
||||
implementation rootProject.ext.dependencies.roomRxjava
|
||||
implementation rootProject.ext.dependencies.androidxrecyclerview
|
||||
annotationProcessor rootProject.ext.dependencies.aroutercompiler
|
||||
implementation rootProject.ext.dependencies.jetbrainsannotationsjava5
|
||||
implementation rootProject.ext.dependencies.rxandroid
|
||||
// api project(path: ':modules:mogo-module-common')
|
||||
// api project(path: ':foudations:mogo-utils')
|
||||
// api project(path: ':modules:mogo-module-map')
|
||||
|
||||
if( Boolean.valueOf(RELEASE) ){
|
||||
implementation rootProject.ext.dependencies.mogomap
|
||||
@@ -55,7 +65,7 @@ dependencies {
|
||||
implementation project(":foudations:mogo-utils")
|
||||
api project(":foudations:mogo-commons")
|
||||
api project(':services:mogo-service-api')
|
||||
implementation project(':modules:mogo-module-common')
|
||||
api project(':modules:mogo-module-common')
|
||||
implementation project(':modules:mogo-module-map')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.mogo.module.navi.bean;
|
||||
|
||||
import com.amap.api.location.AMapLocation;
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.services.core.LatLonPoint;
|
||||
import com.amap.api.services.geocoder.RegeocodeAddress;
|
||||
import com.amap.api.services.help.Tip;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-02
|
||||
* <p>
|
||||
* 实体类操作工具
|
||||
*/
|
||||
public class EntityConvertUtils {
|
||||
|
||||
public static List< Tip > pois2Tips( List< SearchPoi > datums ) {
|
||||
final List< Tip > output = new ArrayList<>();
|
||||
if ( datums == null || datums.isEmpty() ) {
|
||||
return output;
|
||||
}
|
||||
for ( SearchPoi poi : datums ) {
|
||||
Tip tip = poi2Tip( poi );
|
||||
if ( tip != null ) {
|
||||
output.add( tip );
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static Tip poi2Tip( SearchPoi poi ) {
|
||||
if ( poi == null ) {
|
||||
return null;
|
||||
}
|
||||
Tip tip = new Tip();
|
||||
tip.setID( poi.pId );
|
||||
tip.setAdcode( poi.getAdCode() );
|
||||
tip.setAddress( poi.getAddress() );
|
||||
tip.setDistrict( poi.getDistrict() );
|
||||
tip.setName( poi.getName() );
|
||||
tip.setTypeCode( poi.getTypeCode() );
|
||||
tip.setPostion( new LatLonPoint( poi.getLat(), poi.getLng() ) );
|
||||
return tip;
|
||||
}
|
||||
|
||||
public static SearchPoi tipToPoi( Tip tip ) {
|
||||
if ( tip == null ) {
|
||||
return null;
|
||||
}
|
||||
double lat = 0.0;
|
||||
double lng = 0.0;
|
||||
if ( tip.getPoint() != null ) {
|
||||
lat = tip.getPoint().getLatitude();
|
||||
lng = tip.getPoint().getLongitude();
|
||||
}
|
||||
return new SearchPoi( tip.getPoiID(),
|
||||
tip.getName(),
|
||||
tip.getAddress(),
|
||||
lat,
|
||||
lng,
|
||||
tip.getDistrict(),
|
||||
tip.getAdcode(),
|
||||
tip.getTypeCode() );
|
||||
}
|
||||
|
||||
public static SearchPoi aMapLocation2Poi( AMapLocation location ) {
|
||||
if ( location == null || location.getErrorCode() != AMapLocation.LOCATION_SUCCESS ) {
|
||||
return null;
|
||||
}
|
||||
return new SearchPoi( System.currentTimeMillis() + "",
|
||||
location.getPoiName(),
|
||||
location.getAddress(),
|
||||
location.getLatitude(),
|
||||
location.getLongitude(),
|
||||
location.getDistrict(),
|
||||
location.getAdCode(),
|
||||
location.getCoordType() );
|
||||
}
|
||||
|
||||
public static SearchPoi geocodeAddress2Poi( RegeocodeAddress address, CameraPosition position ) {
|
||||
if ( address == null || position == null ) {
|
||||
return null;
|
||||
}
|
||||
return new SearchPoi( System.currentTimeMillis() + "",
|
||||
address.getFormatAddress(),
|
||||
address.getFormatAddress(),
|
||||
position.target.latitude,
|
||||
position.target.longitude,
|
||||
address.getDistrict(),
|
||||
address.getAdCode(),
|
||||
"" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package com.mogo.module.navi.bean;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.PrimaryKey;
|
||||
import com.mogo.module.navi.constants.DataConstants;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-02
|
||||
* <p>
|
||||
* 搜索地址表数据结构
|
||||
*/
|
||||
@Entity( tableName = DataConstants.T_SEARCH_POI )
|
||||
public class SearchPoi implements Parcelable {
|
||||
|
||||
public static final SearchPoi NULL = new SearchPoi( null,
|
||||
null,
|
||||
null,
|
||||
0.0,
|
||||
0.0,
|
||||
null,
|
||||
null,
|
||||
null );
|
||||
|
||||
@PrimaryKey
|
||||
@NonNull
|
||||
public String pId;
|
||||
private String name;
|
||||
private String address;
|
||||
private double lat;
|
||||
private double lng;
|
||||
private String district;
|
||||
private String adCode;
|
||||
private String typeCode;
|
||||
private String province;
|
||||
private String city;
|
||||
|
||||
|
||||
/**
|
||||
* 插入poi数据类型
|
||||
* <p>
|
||||
* {@link DataConstants#TYPE_COMPANY_ADDRESS}
|
||||
* {@link DataConstants#TYPE_HOME_ADDRESS}
|
||||
* {@link DataConstants#TYPE_POI}
|
||||
*/
|
||||
private int type;
|
||||
|
||||
/**
|
||||
* 数据记录时间,自动赋值
|
||||
*/
|
||||
private long time;
|
||||
|
||||
public SearchPoi( String pId,
|
||||
String name,
|
||||
String address,
|
||||
double lat,
|
||||
double lng,
|
||||
String district,
|
||||
String adCode,
|
||||
String typeCode ) {
|
||||
this( pId, name, address, lat, lng, district, adCode, typeCode, "", "", DataConstants.TYPE_POI );
|
||||
}
|
||||
|
||||
private SearchPoi( String pId,
|
||||
String name,
|
||||
String address,
|
||||
double lat,
|
||||
double lng,
|
||||
String district,
|
||||
String adCode,
|
||||
String typeCode,
|
||||
String province,
|
||||
String city,
|
||||
int type ) {
|
||||
this.pId = pId;
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.lat = lat;
|
||||
this.lng = lng;
|
||||
this.district = district;
|
||||
this.adCode = adCode;
|
||||
this.typeCode = typeCode;
|
||||
this.province = province;
|
||||
this.city = city;
|
||||
this.type = type;
|
||||
this.time = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getpId() {
|
||||
return pId;
|
||||
}
|
||||
|
||||
public void setpId( @NonNull String pId ) {
|
||||
this.pId = pId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName( String name ) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress( String address ) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setLat( double lat ) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public double getLng() {
|
||||
return lng;
|
||||
}
|
||||
|
||||
public void setLng( double lng ) {
|
||||
this.lng = lng;
|
||||
}
|
||||
|
||||
public String getDistrict() {
|
||||
return district;
|
||||
}
|
||||
|
||||
public void setDistrict( String district ) {
|
||||
this.district = district;
|
||||
}
|
||||
|
||||
public String getAdCode() {
|
||||
return adCode;
|
||||
}
|
||||
|
||||
public void setAdCode( String adCode ) {
|
||||
this.adCode = adCode;
|
||||
}
|
||||
|
||||
public String getTypeCode() {
|
||||
return typeCode;
|
||||
}
|
||||
|
||||
public void setTypeCode( String typeCode ) {
|
||||
this.typeCode = typeCode;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setProvince( String province ) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity( String city ) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType( int type ) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime( long time ) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel( Parcel dest, int flags ) {
|
||||
dest.writeString( this.pId );
|
||||
dest.writeString( this.name );
|
||||
dest.writeString( this.address );
|
||||
dest.writeDouble( this.lat );
|
||||
dest.writeDouble( this.lng );
|
||||
dest.writeString( this.district );
|
||||
dest.writeString( this.adCode );
|
||||
dest.writeString( this.typeCode );
|
||||
dest.writeString( this.province );
|
||||
dest.writeString( this.city );
|
||||
dest.writeInt( this.type );
|
||||
dest.writeLong( this.time );
|
||||
}
|
||||
|
||||
protected SearchPoi( Parcel in ) {
|
||||
this.pId = in.readString();
|
||||
this.name = in.readString();
|
||||
this.address = in.readString();
|
||||
this.lat = in.readDouble();
|
||||
this.lng = in.readDouble();
|
||||
this.district = in.readString();
|
||||
this.adCode = in.readString();
|
||||
this.typeCode = in.readString();
|
||||
this.province = in.readString();
|
||||
this.city = in.readString();
|
||||
this.type = in.readInt();
|
||||
this.time = in.readLong();
|
||||
}
|
||||
|
||||
public static final Creator< SearchPoi > CREATOR = new Creator< SearchPoi >() {
|
||||
@Override
|
||||
public SearchPoi createFromParcel( Parcel source ) {
|
||||
return new SearchPoi( source );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchPoi[] newArray( int size ) {
|
||||
return new SearchPoi[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.mogo.module.navi.constants;
|
||||
|
||||
import com.amap.api.navi.enums.PathPlanningStrategy;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-04
|
||||
* <p>
|
||||
* 地图基本参数配置
|
||||
*/
|
||||
public class AMapConstants {
|
||||
|
||||
/**
|
||||
* 初始化地图缩放级别
|
||||
*/
|
||||
public static final float AMAP_ZOOM_COMMON_LEVEL = 15.0f;
|
||||
|
||||
/**
|
||||
* 点击当前位置按钮的地图缩放级别
|
||||
*/
|
||||
public static final float AMAP_ZOOM_CURRENT_LOCATION_LEVEL = AMAP_ZOOM_COMMON_LEVEL;
|
||||
|
||||
public static final float AMPA_BEARING = 0.0f;
|
||||
|
||||
public static final int DEFAULT_ROUTE_STRATEGY = PathPlanningStrategy.DRIVING_MULTIPLE_ROUTES_DEFAULT;
|
||||
|
||||
public static final float AMAP_ROUTE_OVERLAY_TRANSPARENCY_SELECTED = 1f;
|
||||
public static final float AMAP_ROUTE_OVERLAY_TRANSPARENCY_UNSELECTED = 0.3f;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mogo.module.navi.constants;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-12-12
|
||||
* <p>
|
||||
* 自定义地图样式
|
||||
*/
|
||||
public class CustomMapStyle {
|
||||
|
||||
public static final String STYLE_ID = "e3e33a3423230b219494b40c4d71d93a";
|
||||
|
||||
public static final String ASSET_STYLE_DATA = "style.data";
|
||||
|
||||
public static final String ASSET_STYLE_EXTRA_DATA = "style_extra.data";
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.mogo.module.navi.constants;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
/**
|
||||
* @author zyz
|
||||
* @since 2019-10-02
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class DataConstants {
|
||||
|
||||
public static final int DB_VERSION = 1;
|
||||
public static final String DB_NAME = "zhidao.amap.db";
|
||||
|
||||
public static final String T_SEARCH_POI = "t_search_poi";
|
||||
|
||||
public static final int TYPE_POI = 0; // 普通搜索的类型
|
||||
public static final int TYPE_HOME_ADDRESS = 1; // 家地址
|
||||
public static final int TYPE_COMPANY_ADDRESS = 2; // 公司地址
|
||||
|
||||
public static final String POI_ID_HOME = "common_address_home";
|
||||
public static final String POI_ID_COMPANY = "common_address_company";
|
||||
|
||||
public static final String CP_AUTHORITY = "com.zhidao.amap";
|
||||
|
||||
// 家的地址
|
||||
public static final Uri CONTENT_HOME_ADDRESS_URI = Uri.parse( "content://com.zhidao.amap/homeAddress" );
|
||||
public static final int HOME_ADDRESS_CODE = TYPE_HOME_ADDRESS;
|
||||
public static final String HOME_ADDRESS_PATH = "homeAddress";
|
||||
public static final String HOME_ADDRESS = "homeAddress";
|
||||
public static final String HOME_ADDRESS_NAME = "homeAddressName";
|
||||
public static final String HOME_ADDRESS_LATITUDE = "homeAddressLatitude";
|
||||
public static final String HOME_ADDRESS_LONGITUDE = "homeAddressLongitude";
|
||||
|
||||
// 公司地址
|
||||
public static final Uri CONTENT_COMPANY_ADDRESS_URI = Uri.parse( "content://com.zhidao.amap/companyAddress" );
|
||||
public static final int COMPANY_ADDRESS_CODE = TYPE_COMPANY_ADDRESS;
|
||||
public static final String COMPANY_ADDRESS_PATH = "companyAddress";
|
||||
public static final String COMPANY_ADDRESS = "companyAddress";
|
||||
public static final String COMPANY_ADDRESS_NAME = "companyAddressName";
|
||||
public static final String COMPANY_ADDRESS_LATITUDE = "companyAddressLatitude";
|
||||
public static final String COMPANY_ADDRESS_LONGITUDE = "companyAddressLongitude";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.mogo.module.navi.dao;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import com.mogo.module.navi.bean.SearchPoi;
|
||||
import com.mogo.module.navi.constants.DataConstants;
|
||||
import io.reactivex.Single;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-02
|
||||
* <p>
|
||||
* 搜索页面数据操作
|
||||
*/
|
||||
@Dao
|
||||
public interface SearchPoiDao {
|
||||
|
||||
@Insert( onConflict = OnConflictStrategy.REPLACE )
|
||||
List<Long> insert(SearchPoi... datums);
|
||||
|
||||
@Query( "SELECT * FROM " + DataConstants.T_SEARCH_POI + " WHERE type=" + DataConstants.TYPE_POI + " ORDER BY time DESC LIMIT :limit" )
|
||||
Single<List< SearchPoi >> getLastN(int limit);
|
||||
|
||||
@Query( "SELECT * FROM " + DataConstants.T_SEARCH_POI + " WHERE type=" + DataConstants.TYPE_POI )
|
||||
Single<List< SearchPoi >> getAll();
|
||||
|
||||
@Query( "SELECT * FROM " + DataConstants.T_SEARCH_POI + " WHERE type=" + DataConstants.TYPE_HOME_ADDRESS )
|
||||
Single<List< SearchPoi >> getHomeAddress();
|
||||
|
||||
@Query( "SELECT * FROM " + DataConstants.T_SEARCH_POI + " WHERE type=" + DataConstants.TYPE_COMPANY_ADDRESS )
|
||||
Single<List< SearchPoi >> getCompanyAddress();
|
||||
|
||||
@Delete
|
||||
int delete(SearchPoi poi);
|
||||
|
||||
@Delete
|
||||
int deleteAll(List<SearchPoi> list);
|
||||
}
|
||||
@@ -4,17 +4,17 @@ import android.content.Context;
|
||||
import androidx.room.Database;
|
||||
import androidx.room.Room;
|
||||
import androidx.room.RoomDatabase;
|
||||
import com.mogo.module.navi.database.bean.POIInfo;
|
||||
import com.mogo.module.navi.database.dao.POIDao;
|
||||
import com.mogo.module.navi.bean.SearchPoi;
|
||||
import com.mogo.module.navi.dao.SearchPoiDao;
|
||||
|
||||
/**
|
||||
* @author zyz
|
||||
* 2019-08-15.
|
||||
*/
|
||||
|
||||
@Database(entities = { POIInfo.class}, version = 1, exportSchema = false)
|
||||
@Database(entities = { SearchPoi.class}, version = 1, exportSchema = false)
|
||||
public abstract class AppDataBase extends RoomDatabase {
|
||||
public abstract POIDao poiDao();
|
||||
public abstract SearchPoiDao poiDao();
|
||||
|
||||
private static volatile AppDataBase INSTANCE;
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.mogo.module.navi.database.bean;
|
||||
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author zyz
|
||||
* 2019-08-15.
|
||||
*/
|
||||
@Entity
|
||||
public class POIInfo {
|
||||
@PrimaryKey
|
||||
@NotNull
|
||||
public String pId;
|
||||
private String name;
|
||||
private String address;
|
||||
private double lat;
|
||||
private double lot;
|
||||
|
||||
|
||||
public POIInfo(String pId, String name, String address, double lat, double lot) {
|
||||
this.pId = pId;
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.lat = lat;
|
||||
this.lot = lot;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setLat(double lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public double getLot() {
|
||||
return lot;
|
||||
}
|
||||
|
||||
public void setLot(double lot) {
|
||||
this.lot = lot;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.mogo.module.navi.database.dao;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import com.mogo.module.navi.database.bean.POIInfo;
|
||||
import io.reactivex.Flowable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zyz
|
||||
* 2019-08-15.
|
||||
*/
|
||||
@Dao
|
||||
public interface POIDao {
|
||||
|
||||
/**
|
||||
* 插入地址信息
|
||||
* @param poiInfos GEO信息
|
||||
* @return
|
||||
*/
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
List<Long> insert(POIInfo... poiInfos);
|
||||
|
||||
/**
|
||||
* 获取地址列表
|
||||
* @return
|
||||
*/
|
||||
@Query("SELECT * from poiinfo")
|
||||
Flowable<List<POIInfo>> load();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.mogo.module.navi.lib;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.navi.AMapNaviListener;
|
||||
import com.amap.api.navi.AMapNaviViewListener;
|
||||
import com.mogo.module.navi.database.wrapper.NaviInfoWrapper;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-09-27
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public interface AMapNaviStatusChangedListener extends AMapNaviListener,
|
||||
AMapNaviViewListener,
|
||||
AMap.OnCameraChangeListener {
|
||||
|
||||
void onNaviInfoUpdate(NaviInfoWrapper wrapper);
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
package com.mogo.module.navi.lib;
|
||||
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.navi.model.AMapCalcRouteResult;
|
||||
import com.amap.api.navi.model.AMapLaneInfo;
|
||||
import com.amap.api.navi.model.AMapModelCross;
|
||||
import com.amap.api.navi.model.AMapNaviCameraInfo;
|
||||
import com.amap.api.navi.model.AMapNaviCross;
|
||||
import com.amap.api.navi.model.AMapNaviInfo;
|
||||
import com.amap.api.navi.model.AMapNaviLocation;
|
||||
import com.amap.api.navi.model.AMapNaviRouteNotifyData;
|
||||
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
|
||||
import com.amap.api.navi.model.AMapServiceAreaInfo;
|
||||
import com.amap.api.navi.model.AimLessModeCongestionInfo;
|
||||
import com.amap.api.navi.model.AimLessModeStat;
|
||||
import com.amap.api.navi.model.NaviInfo;
|
||||
import com.autonavi.tbt.TrafficFacilityInfo;
|
||||
import com.mogo.module.navi.database.wrapper.NaviInfoWrapper;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-01
|
||||
* <p>
|
||||
*/
|
||||
public abstract class AMapNaviStatusChangedListenerDefault implements AMapNaviStatusChangedListener {
|
||||
|
||||
@Override
|
||||
public void onNaviInfoUpdate( NaviInfoWrapper wrapper ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraChange( CameraPosition cameraPosition ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraChangeFinish( CameraPosition cameraPosition ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitNaviFailure() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitNaviSuccess() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartNavi( int i ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrafficStatusUpdate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChange( AMapNaviLocation aMapNaviLocation ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText( int i, String s ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetNavigationText( String s ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndEmulatorNavi() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArriveDestination() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure( int i ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRouteForYaw() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReCalculateRouteForTrafficJam() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArrivedWayPoint( int i ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGpsOpenStatus( boolean b ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviInfoUpdate( NaviInfo naviInfo ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviInfoUpdated( AMapNaviInfo aMapNaviInfo ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCameraInfo( AMapNaviCameraInfo[] aMapNaviCameraInfos ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateIntervalCameraInfo( AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceAreaUpdate( AMapServiceAreaInfo[] aMapServiceAreaInfos ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCross( AMapNaviCross aMapNaviCross ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideCross() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showModeCross( AMapModelCross aMapModelCross ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideModeCross() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLaneInfo( AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1 ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLaneInfo( AMapLaneInfo aMapLaneInfo ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLaneInfo() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess( int[] ints ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyParallelRoad( int i ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility( AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility( AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void OnUpdateTrafficFacility( TrafficFacilityInfo trafficFacilityInfo ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAimlessModeStatistics( AimLessModeStat aimLessModeStat ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAimlessModeCongestionInfo( AimLessModeCongestionInfo aimLessModeCongestionInfo ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayRing( int i ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteSuccess( AMapCalcRouteResult aMapCalcRouteResult ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalculateRouteFailure( AMapCalcRouteResult aMapCalcRouteResult ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviRouteNotify( AMapNaviRouteNotifyData aMapNaviRouteNotifyData ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviSetting() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviCancel() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNaviBackClick() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviMapMode( int i ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviTurnClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextRoadClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanViewButtonClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLockMap( boolean b ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewLoaded() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapTypeChanged( int i ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewShowMode( int i ) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.mogo.module.navi.ui.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import com.amap.api.services.help.Tip;
|
||||
import com.mogo.module.navi.R;
|
||||
import com.mogo.module.navi.ui.adapter.base.RecycleBaseAdapter;
|
||||
import com.mogo.module.navi.ui.adapter.base.RecycleViewHolder;
|
||||
import com.mogo.utils.OnItemClickedListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zyz
|
||||
* 2019-08-13.
|
||||
*/
|
||||
public class SearchPoiAdapter extends RecycleBaseAdapter<Tip> {
|
||||
/**
|
||||
* @param context
|
||||
* @param list
|
||||
*/
|
||||
public SearchPoiAdapter(Context context, List<Tip> list) {
|
||||
super(context, list, R.layout.item_search_poi);
|
||||
}
|
||||
private OnItemClickedListener< Tip > mOnItemClickedListener;
|
||||
private OnItemClickedListener< Tip > mOnDeleteAllClickedListener;
|
||||
private OnItemClickedListener< Tip > mOnActionButtonClickedListener;
|
||||
private boolean mShowDelete = false;
|
||||
|
||||
private View.OnClickListener onClickListener;
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecycleViewHolder holder, Tip tip) {
|
||||
|
||||
holder.setText(R.id.tv_position, tip.getName());
|
||||
holder.setText(R.id.tv_position_des, tip.getAddress());
|
||||
|
||||
holder.itemView.setTag(R.id.tag_position, tip);
|
||||
holder.itemView.setOnClickListener(onClickListener);
|
||||
|
||||
}
|
||||
|
||||
public void setOnClickListener(View.OnClickListener onClickListener) {
|
||||
this.onClickListener = onClickListener;
|
||||
}
|
||||
public void setOnItemClickedListener( OnItemClickedListener< Tip > onItemClickedListener ) {
|
||||
this.mOnItemClickedListener = onItemClickedListener;
|
||||
}
|
||||
|
||||
public void setOnDeleteAllClickedListener( OnItemClickedListener< Tip > onDeleteAllClickedListener ) {
|
||||
this.mOnDeleteAllClickedListener = onDeleteAllClickedListener;
|
||||
}
|
||||
|
||||
public void setOnActionButtonClickedListener( OnItemClickedListener< Tip > onActionButtonClickedListener ) {
|
||||
this.mOnActionButtonClickedListener = onActionButtonClickedListener;
|
||||
}
|
||||
public void setShowDelete( boolean showDelete ) {
|
||||
this.mShowDelete = showDelete;
|
||||
}
|
||||
public void refresh( List< Tip > datums, boolean showDelete ) {
|
||||
//this.da = datums;
|
||||
setShowDelete( showDelete );
|
||||
setDatas(datums);
|
||||
//notifyDataSetChanged();
|
||||
}
|
||||
public void clear(){
|
||||
mOnItemClickedListener = null;
|
||||
mOnDeleteAllClickedListener = null;
|
||||
mOnActionButtonClickedListener = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.mogo.module.navi.ui.adapter.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Title: adapter
|
||||
* </p>
|
||||
* <p>
|
||||
* Description:
|
||||
* </p>
|
||||
* <p>
|
||||
* Copyright: Copyright (c) 2015
|
||||
* </p>
|
||||
* <p>
|
||||
* </p>
|
||||
*/
|
||||
public abstract class RecycleBaseAdapter<T> extends
|
||||
RecyclerView.Adapter<RecycleViewHolder>
|
||||
{
|
||||
|
||||
protected Context context;
|
||||
protected List<T> list;
|
||||
private int resourceID;
|
||||
private Toast toast;
|
||||
|
||||
/**
|
||||
* @param context
|
||||
*/
|
||||
public RecycleBaseAdapter(Context context, List<T> list, int resourceID)
|
||||
{
|
||||
super();
|
||||
this.context = context;
|
||||
this.list = list;
|
||||
this.resourceID = resourceID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecycleViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
|
||||
{
|
||||
View v = LayoutInflater.from(context).inflate(resourceID, viewGroup,
|
||||
false);
|
||||
|
||||
RecycleViewHolder holder = RecycleViewHolder
|
||||
.get(v);
|
||||
|
||||
initHolder(holder);
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(
|
||||
RecycleViewHolder viewHolder, int position)
|
||||
{
|
||||
onBindViewHolder(viewHolder, list.get(position % list.size()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount()
|
||||
{
|
||||
return list == null ? 0 : list.size();
|
||||
}
|
||||
|
||||
public abstract void onBindViewHolder(
|
||||
RecycleViewHolder holder, T t);
|
||||
|
||||
public void initHolder(RecycleViewHolder holder)
|
||||
{
|
||||
|
||||
}
|
||||
public void setDatas(List<T> list)
|
||||
{
|
||||
setDatas(list, false);
|
||||
}
|
||||
|
||||
public void setDatas(List<T> list, boolean add)
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
this.list.addAll(list);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.list = list;
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
public void messageShow(String mes)
|
||||
{
|
||||
if (toast==null){
|
||||
toast= Toast.makeText(context,mes, Toast.LENGTH_LONG);
|
||||
}
|
||||
else{
|
||||
toast.setText(mes);
|
||||
}
|
||||
toast.show();
|
||||
}
|
||||
|
||||
public T getItem(int position){
|
||||
if (list==null||list.size()==0){
|
||||
return null;
|
||||
}
|
||||
return list.get(position);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.mogo.module.navi.ui.adapter.base;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.text.SpannableString;
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class RecycleViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private SparseArray<View> mViews;
|
||||
|
||||
private View mConvertView;
|
||||
|
||||
public RecycleViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
this.mConvertView = itemView;
|
||||
mViews = new SparseArray<View>();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public static RecycleViewHolder get(View itemView) {
|
||||
return new RecycleViewHolder(itemView);
|
||||
}
|
||||
|
||||
public View getConvertView() {
|
||||
return mConvertView;
|
||||
}
|
||||
|
||||
public <T extends View> T getView(int viewId) {
|
||||
View view = mViews.get(viewId);
|
||||
if (view == null) {
|
||||
view = mConvertView.findViewById(viewId);
|
||||
mViews.put(viewId, view);
|
||||
}
|
||||
return (T) view;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewId
|
||||
* @param text
|
||||
* @return
|
||||
*/
|
||||
public RecycleViewHolder setText(int viewId, String text) {
|
||||
TextView tv = getView(viewId);
|
||||
if (tv==null)return this;
|
||||
tv.setText(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewId
|
||||
* @param text
|
||||
* @return
|
||||
*/
|
||||
public RecycleViewHolder setText(int viewId, SpannableString text) {
|
||||
TextView tv = getView(viewId);
|
||||
tv.setText(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewId
|
||||
* @param resId
|
||||
* @return
|
||||
*/
|
||||
public RecycleViewHolder setImageResource(int viewId, int resId) {
|
||||
ImageView view = getView(viewId);
|
||||
view.setImageResource(resId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewId
|
||||
* @return
|
||||
*/
|
||||
public RecycleViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
|
||||
ImageView view = getView(viewId);
|
||||
view.setImageBitmap(bitmap);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewId
|
||||
* @param resId
|
||||
* @return
|
||||
*/
|
||||
// public ViewHolder setImageURI(int viewId, String url) {
|
||||
// ImageView view = getView(viewId);
|
||||
// // ImageLoader.getInstance.loadImg(view,url);
|
||||
// return this;
|
||||
// }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewId
|
||||
* @param resId
|
||||
* @return
|
||||
*/
|
||||
public RecycleViewHolder setBackgroundImage(int viewId, int resId) {
|
||||
View view = getView(viewId);
|
||||
view.setBackgroundResource(resId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewId
|
||||
* @param resId
|
||||
* @return
|
||||
*/
|
||||
public RecycleViewHolder setTextColor(int viewId, int resId) {
|
||||
TextView view = getView(viewId);
|
||||
view.setTextColor(resId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param viewId
|
||||
* @return
|
||||
*/
|
||||
public RecycleViewHolder setOnClickListener(int viewId,
|
||||
OnClickListener listener) {
|
||||
getView(viewId).setOnClickListener(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.mogo.module.navi.ui.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-04
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public abstract class AMapBaseFragment extends com.mogo.module.navi.database.ui.base.BaseFragment {
|
||||
|
||||
private static final String TAG = "amap.AMapBaseFragment";
|
||||
|
||||
@Override
|
||||
public void onActivityCreated( @Nullable Bundle savedInstanceState ) {
|
||||
super.onActivityCreated( savedInstanceState );
|
||||
initViews();
|
||||
}
|
||||
|
||||
protected abstract void initViews();
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState( @NonNull Bundle outState ) {
|
||||
super.onSaveInstanceState( outState );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.mogo.module.navi.ui.base;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.navi.AMapNavi;
|
||||
import com.amap.api.navi.AMapNaviView;
|
||||
import com.amap.api.navi.model.AMapNaviPath;
|
||||
import com.mogo.module.navi.lib.AMapNaviStatusChangedListener;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-01
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public interface AMapServiceVisitor {
|
||||
|
||||
AMapNaviView getNaviView();
|
||||
|
||||
AMap getMap();
|
||||
|
||||
AMapNavi getAMapNavi();
|
||||
|
||||
void registerNaviListener(AMapNaviStatusChangedListener listener);
|
||||
|
||||
/**
|
||||
* 是否正在导航
|
||||
*/
|
||||
boolean isNaving();
|
||||
|
||||
void stopNavi();
|
||||
|
||||
void setHost(String host);
|
||||
|
||||
/**
|
||||
* 将导航路线发送给launcher
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
void pushNaviPathToLauncher(AMapNaviPath path);
|
||||
|
||||
/**
|
||||
* 将导航路线发送给launcher
|
||||
*
|
||||
* @param path 导航路线
|
||||
* @param directly 是否直接发送
|
||||
*/
|
||||
void pushNaviPathToLauncher(AMapNaviPath path, boolean directly);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.mogo.module.navi.ui.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import com.mogo.utils.SoftKeyBoardJobber;
|
||||
import com.mogo.utils.statusbar.Eyes;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-02
|
||||
* <p>
|
||||
* 地图 activity 基类
|
||||
*/
|
||||
public class BaseActivity extends AppCompatActivity {
|
||||
|
||||
//@Override
|
||||
//public Context getContext() {
|
||||
// return this;
|
||||
//}
|
||||
|
||||
@Override
|
||||
protected void onCreate( @Nullable Bundle savedInstanceState ) {
|
||||
super.onCreate( savedInstanceState );
|
||||
Eyes.setStatusBarStyle( this, false, Color.parseColor( "#66000000" ), true );
|
||||
getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN );
|
||||
hideSystemUI();
|
||||
}
|
||||
|
||||
protected void hideSystemUI() {
|
||||
//隐藏虚拟按键
|
||||
if ( Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19 ) { // lower api
|
||||
View v = this.getWindow().getDecorView();
|
||||
v.setSystemUiVisibility( View.GONE );
|
||||
} else if ( Build.VERSION.SDK_INT >= 19 ) {
|
||||
//for new api versions.
|
||||
View decorView = getWindow().getDecorView();
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
decorView.setSystemUiVisibility( uiOptions );
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean enableDispatchTouchEventToDismissSoftKeyBoard() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent( MotionEvent ev ) {
|
||||
if ( ev.getAction() == MotionEvent.ACTION_DOWN && enableDispatchTouchEventToDismissSoftKeyBoard() ) {
|
||||
SoftKeyBoardJobber.hideIfNecessary( this, ev );
|
||||
return super.dispatchTouchEvent( ev );
|
||||
}
|
||||
// 必不可少,否则所有的组件都不会有TouchEvent了
|
||||
if ( getWindow().superDispatchTouchEvent( ev ) ) {
|
||||
return true;
|
||||
}
|
||||
return onTouchEvent( ev );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.mogo.module.navi.ui.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.mogo.utils.NetworkUtils;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-03
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public abstract class BaseFragment extends Fragment {
|
||||
|
||||
protected Context mContext;
|
||||
private View mRootView;
|
||||
|
||||
@Override
|
||||
public void onAttach( Context context ) {
|
||||
super.onAttach( context );
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView( @NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable
|
||||
Bundle savedInstanceState ) {
|
||||
mRootView = inflater.inflate( getLayoutId(), container, false );
|
||||
return mRootView;
|
||||
}
|
||||
|
||||
protected abstract int getLayoutId();
|
||||
|
||||
protected < T extends View> T findViewById( @IdRes int id ) {
|
||||
if ( mRootView != null ) {
|
||||
return mRootView.findViewById( id );
|
||||
}
|
||||
if ( getView() != null ) {
|
||||
return getView().findViewById( id );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void overridePendingTransition( int enter, int exit ) {
|
||||
if ( getActivity() != null ) {
|
||||
getActivity().overridePendingTransition( enter, exit );
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean checkNetwork() {
|
||||
return NetworkUtils.isConnected( mContext );
|
||||
}
|
||||
|
||||
protected void shortToast( CharSequence msg ) {
|
||||
if ( mContext != null && msg != null ) {
|
||||
Toast.makeText( mContext, msg, Toast.LENGTH_SHORT ).show();
|
||||
}
|
||||
}
|
||||
|
||||
protected void longToast( CharSequence msg ) {
|
||||
if ( mContext != null && msg != null ) {
|
||||
Toast.makeText( mContext, msg, Toast.LENGTH_LONG ).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
package com.mogo.module.navi.ui.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.util.Log;
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.CameraUpdateFactory;
|
||||
import com.amap.api.maps.UiSettings;
|
||||
import com.amap.api.maps.model.BitmapDescriptorFactory;
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.maps.model.CustomMapStyleOptions;
|
||||
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.navi.AMapNaviView;
|
||||
import com.amap.api.navi.AMapNaviViewOptions;
|
||||
import com.mogo.module.navi.R;
|
||||
import com.mogo.module.navi.constants.AMapConstants;
|
||||
import com.mogo.module.navi.constants.CustomMapStyle;
|
||||
import com.mogo.utils.AssetsUtils;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-27
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class MapUIController {
|
||||
|
||||
private static final String TAG = "MapUIController";
|
||||
|
||||
private static volatile MapUIController sInstance;
|
||||
private int mLastZoomLevel;
|
||||
|
||||
private MapUIController() {
|
||||
}
|
||||
|
||||
public static MapUIController getInstance() {
|
||||
if ( sInstance == null ) {
|
||||
synchronized ( MapUIController.class ) {
|
||||
if ( sInstance == null ) {
|
||||
sInstance = new MapUIController();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public synchronized void release() {
|
||||
mContext = null;
|
||||
mMapView = null;
|
||||
mAMap = null;
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private AMapNaviView mMapView;
|
||||
private AMap mAMap;
|
||||
|
||||
public synchronized void init( Context context, AMapNaviView mapView, AMap aMap ) {
|
||||
this.mContext = context;
|
||||
this.mMapView = mapView;
|
||||
this.mAMap = aMap;
|
||||
initMap();
|
||||
changeMyLocationVisibility( true );
|
||||
}
|
||||
|
||||
private boolean checkAMap() {
|
||||
return mAMap != null;
|
||||
}
|
||||
|
||||
private boolean checkAMapView() {
|
||||
return mMapView != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除所有导航mapView的默认UI
|
||||
*/
|
||||
private void initMap() {
|
||||
if ( mMapView != null ) {
|
||||
AMapNaviViewOptions options = mMapView.getViewOptions();
|
||||
if ( options != null ) {
|
||||
// 设置是否开启自动黑夜模式切换,默认为false,不自动切换
|
||||
options.setAutoNaviViewNightMode( false );
|
||||
// 设置6秒后是否自动锁车
|
||||
options.setAutoLockCar( true );
|
||||
// 设置路线上的摄像头气泡是否显示
|
||||
options.setCameraBubbleShow( true );
|
||||
// 设置路线相关的配置属性,如:路线的路况颜色,路线上是否显示摄像头气泡等。
|
||||
// options.setRouteOverlayOptions( MapStyleUtils.getRouteOverlayOptions() );
|
||||
// 设置自车的图片对象
|
||||
options.setCarBitmap( BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_amap_navi_cursor ) );
|
||||
// 设置指南针图标否在导航界面显示,默认显示。true,显示;false,隐藏。
|
||||
options.setCompassEnabled( false );
|
||||
//设置路况光柱条是否显示(只适用于驾车导航,需要联网)。
|
||||
options.setTrafficBarEnabled( false );
|
||||
// 设置[实时交通图层开关按钮]是否显示(只适用于驾车导航,需要联网)。
|
||||
options.setTrafficLayerEnabled( false );
|
||||
// 设置导航界面是否显示路线全览按钮。
|
||||
options.setRouteListButtonShow( false );
|
||||
// 设置起点位图,须在画路前设置
|
||||
options.setStartPointBitmap( BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_current_location_cursor ) );
|
||||
// 设置终点位图,须在画路前设置
|
||||
options.setEndPointBitmap( BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_search_choice_point ) );
|
||||
// 设置导航状态下屏幕是否一直开启。
|
||||
options.setScreenAlwaysBright( true );
|
||||
// 设置交通播报是否打开(只适用于驾车导航,需要联网)。
|
||||
options.setTrafficInfoUpdateEnabled( true );
|
||||
// 设置摄像头播报是否打开(只适用于驾车导航)。
|
||||
options.setCameraInfoUpdateEnabled( true );
|
||||
// 设置菜单按钮是否在导航界面显示。
|
||||
options.setSettingMenuEnabled( false );
|
||||
// 设置是否绘制显示交通路况的线路(彩虹线),拥堵-红色,畅通-绿色,缓慢-黄色,未知-蓝色。默认不绘制彩虹线。
|
||||
options.setTrafficLine( true );
|
||||
// 设置是否绘制牵引线(当前位置到目的地的指引线)。默认不绘制牵引线。
|
||||
options.setLeaderLineEnabled( -1 );
|
||||
// 设置导航界面UI是否显示。
|
||||
options.setLayoutVisible( false );
|
||||
// 设置是否自动画路
|
||||
options.setAutoDrawRoute( false );
|
||||
// 设置是否显示路口放大图(实景图)
|
||||
options.setRealCrossDisplayShow( false );
|
||||
// 设置是否显示路口放大图(路口模型图)
|
||||
options.setModeCrossDisplayShow( false );
|
||||
// 设置是否显示道路信息view
|
||||
options.setLaneInfoShow( false );
|
||||
// 设置是否自动改变缩放等级
|
||||
options.setAutoChangeZoom( false );
|
||||
// 设置是否自动全览模式,即在算路成功后自动进入全览模式
|
||||
options.setAutoDisplayOverview( false );
|
||||
// 设置路线转向箭头隐藏和显示
|
||||
options.setNaviArrowVisible( false );
|
||||
// 通过路线是否自动置灰,仅支持驾车导航
|
||||
options.setAfterRouteAutoGray( true );
|
||||
options.setPointToCenter( 0.5D, 0.5D );
|
||||
mMapView.setViewOptions( options );
|
||||
}
|
||||
mMapView.setNaviMode( AMapNaviView.CAR_UP_MODE );
|
||||
}
|
||||
|
||||
if ( mAMap != null ) {
|
||||
|
||||
mAMap.setTrafficEnabled( true );
|
||||
|
||||
UiSettings uiSettings = mAMap.getUiSettings();
|
||||
if ( uiSettings != null ) {
|
||||
//设置所有手势是否可用
|
||||
uiSettings.setAllGesturesEnabled( true );
|
||||
//设置指南针是否可见。
|
||||
uiSettings.setCompassEnabled( false );
|
||||
//设置是否以地图中心点缩放
|
||||
uiSettings.setGestureScaleByMapCenter( true );
|
||||
//设置室内地图楼层切换控件是否可见。
|
||||
uiSettings.setIndoorSwitchEnabled( true );
|
||||
//设置定位按钮是否可见。
|
||||
uiSettings.setMyLocationButtonEnabled( false );
|
||||
//设置旋转手势是否可用。
|
||||
uiSettings.setRotateGesturesEnabled( false );
|
||||
//设置比例尺控件是否可见
|
||||
uiSettings.setScaleControlsEnabled( false );
|
||||
//设置拖拽手势是否可用。
|
||||
uiSettings.setScrollGesturesEnabled( true );
|
||||
//设置倾斜手势是否可用。
|
||||
uiSettings.setTiltGesturesEnabled( true );
|
||||
//设置缩放按钮是否可见。
|
||||
uiSettings.setZoomControlsEnabled( false );
|
||||
//设置双指缩放手势是否可用。
|
||||
uiSettings.setZoomGesturesEnabled( true );
|
||||
}
|
||||
mAMap.setCustomMapStyle( new CustomMapStyleOptions()
|
||||
.setEnable( true )
|
||||
.setStyleId( CustomMapStyle.STYLE_ID )
|
||||
.setStyleData( AssetsUtils.read( mContext, CustomMapStyle.ASSET_STYLE_DATA ) )
|
||||
.setStyleExtraData( AssetsUtils.read( mContext, CustomMapStyle.ASSET_STYLE_EXTRA_DATA ) )
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制我的位置图层及定位回调能力
|
||||
*
|
||||
* @param visibility
|
||||
*/
|
||||
public void changeMyLocationVisibility( boolean visibility ) {
|
||||
if ( mAMap == null ) {
|
||||
return;
|
||||
}
|
||||
mAMap.setMyLocationEnabled( visibility );
|
||||
Log.d( TAG, visibility ? "开启定位" : "关闭定位" );
|
||||
if ( visibility ) {
|
||||
MyLocationStyle style = mAMap.getMyLocationStyle();
|
||||
if ( style == null ) {
|
||||
style = new MyLocationStyle();
|
||||
}
|
||||
style.myLocationType( MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER )
|
||||
.strokeWidth( 0 )
|
||||
.interval( 2_000L )
|
||||
.showMyLocation( visibility )
|
||||
.myLocationIcon( BitmapDescriptorFactory.fromResource( R.drawable.ic_current_location_cursor ) )
|
||||
.radiusFillColor( Color.TRANSPARENT );
|
||||
mAMap.setMyLocationStyle( style );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航模式:中心点偏下
|
||||
*/
|
||||
public void showNaviUI() {
|
||||
changeMyLocationVisibility( false );
|
||||
changeCarOverlayVisibility( true );
|
||||
changeRouteOverlayVisibility( false );
|
||||
if ( mMapView != null ) {
|
||||
mMapView.setNaviMode( AMapNaviView.CAR_UP_MODE );
|
||||
mMapView.post( () -> {
|
||||
AMapNaviViewOptions options = mMapView.getViewOptions();
|
||||
if ( options != null ) {
|
||||
Log.d( TAG, "中心点切换到页面偏下" );
|
||||
options.setPointToCenter( 0.5D, 0.6666666666666666D );
|
||||
mMapView.setViewOptions( options );
|
||||
if ( checkAMap() ) {
|
||||
mAMap.moveCamera( CameraUpdateFactory.zoomBy( 15 ) );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 正常地图模式:中心点居中
|
||||
*/
|
||||
public void showMapUI() {
|
||||
changeMyLocationVisibility( true );
|
||||
changeCarOverlayVisibility( false );
|
||||
changeRouteOverlayVisibility( false );
|
||||
if ( mMapView != null ) {
|
||||
AMapNaviViewOptions options = mMapView.getViewOptions();
|
||||
if ( options != null ) {
|
||||
Log.d( TAG, "中心点切换到页面中心" );
|
||||
options.setPointToCenter( 0.5D, 0.5D );
|
||||
mMapView.setViewOptions( options );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示规划UI样式:中心点右移
|
||||
*/
|
||||
public void showCalculateUI() {
|
||||
changeMyLocationVisibility( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制自车marker
|
||||
*
|
||||
* @param visibility
|
||||
*/
|
||||
public void changeCarOverlayVisibility( boolean visibility ) {
|
||||
try {
|
||||
mMapView.setCarOverlayVisible( visibility );
|
||||
} catch ( Exception e ) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制导航路线图层
|
||||
*
|
||||
* @param visibility
|
||||
*/
|
||||
public void changeRouteOverlayVisibility( boolean visibility ) {
|
||||
try {
|
||||
mMapView.setRouteOverlayVisible( visibility );
|
||||
} catch ( Exception e ) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将地图移动到中心点,正北方向
|
||||
*
|
||||
* @param latlng
|
||||
*/
|
||||
public void moveCurrentPositionToCenter( LatLng latlng ) {
|
||||
if ( checkAMap() ) {
|
||||
mAMap.animateCamera( CameraUpdateFactory.newCameraPosition( new CameraPosition.Builder()
|
||||
.tilt( mMapView.getLockTilt() )
|
||||
.zoom( mMapView.getLockZoom() )
|
||||
.target( latlng )
|
||||
.bearing( AMapConstants.AMPA_BEARING )
|
||||
.build() ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变地图缩放级别
|
||||
*
|
||||
* @param level
|
||||
*/
|
||||
public void changeCameraZoomLevel( float level, boolean animate ) {
|
||||
if ( checkAMap() ) {
|
||||
if ( animate ) {
|
||||
mAMap.animateCamera( CameraUpdateFactory.zoomTo( level ) );
|
||||
} else {
|
||||
mAMap.moveCamera( CameraUpdateFactory.zoomTo( level ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加marker
|
||||
*
|
||||
* @param options
|
||||
* @return
|
||||
*/
|
||||
public Marker addMarker( MarkerOptions options ) {
|
||||
return mAMap.addMarker( options );
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存上次地图缩放级别
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean storeMapZoomLevel() {
|
||||
if ( checkAMapView() ) {
|
||||
final AMapNaviViewOptions options = mMapView.getViewOptions();
|
||||
if ( options != null ) {
|
||||
mLastZoomLevel = options.getZoom();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原上次的缩放级别
|
||||
*/
|
||||
public void restoreMapZoomLevel() {
|
||||
if ( checkAMapView() ) {
|
||||
final AMapNaviViewOptions options = mMapView.getViewOptions();
|
||||
if ( options != null ) {
|
||||
options.setZoom( mLastZoomLevel );
|
||||
mMapView.setViewOptions( options );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 交通态势开关
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
public void setTrafficEnabled( boolean enable ) {
|
||||
if ( checkAMap() ) {
|
||||
mAMap.setTrafficEnabled( enable );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩放地图
|
||||
*
|
||||
* @param zoomIn 放大
|
||||
*/
|
||||
public void changeZoom( boolean zoomIn ) {
|
||||
if ( checkAMapView() ) {
|
||||
if ( zoomIn ) {
|
||||
mMapView.zoomIn();
|
||||
} else {
|
||||
mMapView.zoomOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图类型
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
public void setMapType( int type ) {
|
||||
if ( checkAMap() ) {
|
||||
mAMap.setMapType( type );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航样式:
|
||||
*
|
||||
* @param naviMode
|
||||
*/
|
||||
public void setNaviMode( int naviMode ) {
|
||||
if ( checkAMapView() ) {
|
||||
mMapView.setNaviMode( naviMode );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图倾斜度
|
||||
*
|
||||
* @param tile
|
||||
*/
|
||||
public void setTilt( int tile ) {
|
||||
if ( checkAMapView() ) {
|
||||
final AMapNaviViewOptions options = mMapView.getViewOptions();
|
||||
if ( options != null ) {
|
||||
options.setTilt( tile );
|
||||
mMapView.setViewOptions( options );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览全程
|
||||
*/
|
||||
public void displayOverview() {
|
||||
if ( checkAMapView() ) {
|
||||
mMapView.displayOverview();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭全程预览
|
||||
*/
|
||||
public void recoverLockMode() {
|
||||
if ( checkAMapView() ) {
|
||||
mMapView.recoverLockMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.mogo.module.navi.ui.base;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-04
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public interface UiController {
|
||||
|
||||
/**
|
||||
* 显示地图模式
|
||||
*/
|
||||
void onMapMode();
|
||||
|
||||
/**
|
||||
* 显示导航模式
|
||||
*/
|
||||
void onNaviMode();
|
||||
|
||||
/**
|
||||
* 搜索地址
|
||||
*
|
||||
* @param searchType {@link com.zhidao.amap.splitunit.ui.search.SearchConstants}
|
||||
*/
|
||||
void onSearchMode(int searchType);
|
||||
|
||||
/**
|
||||
* 规划路径
|
||||
*/
|
||||
void onCalculateMode();
|
||||
|
||||
/**
|
||||
* 设置
|
||||
*/
|
||||
void onSettingsMode();
|
||||
|
||||
|
||||
/**
|
||||
* 直接退出应用
|
||||
*/
|
||||
void finishDirectly();
|
||||
|
||||
FragmentManager _getSupportFragmentManager();
|
||||
|
||||
AMapServiceVisitor getAMapServiceVisitor();
|
||||
|
||||
//CommonAddressModel getCommonAddressModel();
|
||||
|
||||
void popBackStackImmediate();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.mogo.module.navi.ui.search;
|
||||
|
||||
import com.mogo.module.navi.constants.DataConstants;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-12-08
|
||||
* <p>
|
||||
* 搜索页面常量字段
|
||||
*/
|
||||
public class SearchConstants {
|
||||
|
||||
/**
|
||||
* 搜索页面类型
|
||||
*/
|
||||
public static final String KEY_SEARCH_TYPE = "type";
|
||||
|
||||
/**
|
||||
* 普通搜索:首页搜索按钮点击
|
||||
*/
|
||||
public static final int SEARCH_TYPE_COMMON = DataConstants.TYPE_POI;
|
||||
|
||||
/**
|
||||
* 设置家:多种搜索方式:普通搜索、我的位置、地图选点
|
||||
*/
|
||||
public static final int SEARCH_TYPE_MULTI_HOME = DataConstants.TYPE_HOME_ADDRESS;
|
||||
|
||||
/**
|
||||
* 设置公司:多种搜索方式:普通搜索、我的位置、地图选点
|
||||
*/
|
||||
public static final int SEARCH_TYPE_MULTI_COMPANY = DataConstants.TYPE_COMPANY_ADDRESS;
|
||||
|
||||
/**
|
||||
* 搜索页面当前状态
|
||||
*/
|
||||
public static final int UI_MODE_COMMON = 1;
|
||||
/**
|
||||
* 搜索页面当前状态:常用地址搜索模式
|
||||
*/
|
||||
public static final int UI_MODE_MULTI = 2;
|
||||
|
||||
/**
|
||||
* 搜索页面当前状态:常用地址搜索模式
|
||||
*/
|
||||
public static final int UI_MODE_MULTI_SEARCH = 5;
|
||||
/**
|
||||
* 搜索页面当前状态:我的位置模式
|
||||
*/
|
||||
public static final int UI_MODE_MULTI_MY_LOCATION = 3;
|
||||
/**
|
||||
* 搜索页面当前状态:选点模式
|
||||
*/
|
||||
public static final int UI_MODE_MULTI_CHOICE_POINT = 4;
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
package com.mogo.module.navi.ui.search;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.amap.api.location.AMapLocation;
|
||||
import com.amap.api.location.AMapLocationListener;
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.AMapUtils;
|
||||
import com.amap.api.maps.model.BitmapDescriptorFactory;
|
||||
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.animation.Animation;
|
||||
import com.amap.api.maps.model.animation.TranslateAnimation;
|
||||
import com.amap.api.services.geocoder.RegeocodeAddress;
|
||||
import com.amap.api.services.help.Tip;
|
||||
|
||||
import com.mogo.module.map.location.AMapLocationManager;
|
||||
import com.mogo.module.navi.R;
|
||||
import com.mogo.module.navi.bean.EntityConvertUtils;
|
||||
import com.mogo.module.navi.bean.SearchPoi;
|
||||
import com.mogo.module.navi.ui.adapter.SearchPoiAdapter;
|
||||
import com.mogo.module.navi.ui.base.BaseFragment;
|
||||
import com.mogo.module.navi.ui.base.MapUIController;
|
||||
import com.mogo.module.navi.ui.base.UiController;
|
||||
import com.mogo.utils.WindowUtils;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 搜索页面
|
||||
* <p>
|
||||
* 普通搜索:从首页点击搜索按钮进入:包含:仅输入搜索(列表不包含设置按钮)
|
||||
* {@link SearchConstants#SEARCH_TYPE_COMMON}
|
||||
* <p>
|
||||
* 地址设置搜索:设置家、公司、其他的地址:包含当前位置、选点、搜索列表(列表包含设置按钮)、普通页面
|
||||
* {@link SearchConstants#SEARCH_TYPE_MULTI_COMPANY}
|
||||
* {@link SearchConstants#SEARCH_TYPE_MULTI_HOME}
|
||||
*/
|
||||
@Route( path = "/amap/search" )
|
||||
public class SearchFragment extends BaseFragment implements SearchView,
|
||||
AMapLocationListener {
|
||||
|
||||
public static final String TAG = "search";
|
||||
|
||||
public int mSearchType;
|
||||
|
||||
private SearchPresenter mSearchPresenter;
|
||||
|
||||
private View mClose;
|
||||
private EditText mSearchBox;
|
||||
|
||||
private RecyclerView mSearchResult;
|
||||
private SearchPoiAdapter mPoiAdapter;
|
||||
|
||||
private View mMyLocation;
|
||||
private View mChoicePoint;
|
||||
private View mCurrentLocation;
|
||||
|
||||
/**
|
||||
* 设置常用地址(我的位置、选点)时的设置按钮
|
||||
*/
|
||||
private TextView mActionButton;
|
||||
|
||||
private UiController mUiController;
|
||||
|
||||
private Bitmap mSearchBoxRightDrawableBitmap = null;
|
||||
|
||||
/**
|
||||
* 地址设置是否完成
|
||||
*/
|
||||
private boolean mActionSuccess = false;
|
||||
|
||||
/**
|
||||
* 当前UI的样式(具体是哪个操作)
|
||||
*/
|
||||
private int mUiMode = SearchConstants.UI_MODE_COMMON;
|
||||
|
||||
/**
|
||||
* 地图选点的marker
|
||||
*/
|
||||
private Marker mChoicePointMaker = null;
|
||||
private AMapLocation mLastAMapLocation;
|
||||
|
||||
@Override
|
||||
public void onAttach( Context context ) {
|
||||
super.onAttach( context );
|
||||
if ( context instanceof UiController) {
|
||||
mUiController = ( ( UiController ) context );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.fragment_search;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated( @Nullable Bundle savedInstanceState ) {
|
||||
super.onActivityCreated( savedInstanceState );
|
||||
initViews();
|
||||
getLifecycle().addObserver( mSearchPresenter = new SearchPresenter( this ) );
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
mClose = findViewById( R.id.amap_search_close );
|
||||
mClose.setOnClickListener( view -> {
|
||||
exitSearch();
|
||||
} );
|
||||
|
||||
mSearchBox = findViewById( R.id.amap_search_search_box );
|
||||
mSearchResult = findViewById( R.id.amap_search_poi_result );
|
||||
mSearchResult.setLayoutManager( new LinearLayoutManager( mContext, LinearLayoutManager.VERTICAL, false ) );
|
||||
|
||||
mMyLocation = findViewById( R.id.amap_search_poi_my_location );
|
||||
mMyLocation.setOnClickListener( view -> {
|
||||
if ( !checkNetwork() ) {
|
||||
shortToast( "网络未连接,请检查网络" );
|
||||
return;
|
||||
}
|
||||
multiSearchMyLocationUI();
|
||||
AMapLocationManager.getInstance( mContext ).addLocationListener( this );
|
||||
AMapLocationManager.getInstance( mContext ).start();
|
||||
} );
|
||||
mChoicePoint = findViewById( R.id.amap_search_poi_choice_point );
|
||||
mChoicePoint.setOnClickListener( view -> {
|
||||
multiSearchChoicePointUI();
|
||||
} );
|
||||
mCurrentLocation = findViewById( R.id.amap_search_current_location );
|
||||
mCurrentLocation.setOnClickListener( view -> {
|
||||
if ( !checkNetwork() ) {
|
||||
shortToast( "网络未连接,请检查网络" );
|
||||
return;
|
||||
}
|
||||
AMapLocationManager.getInstance( mContext ).addLocationListener( this );
|
||||
AMapLocationManager.getInstance( mContext ).start();
|
||||
} );
|
||||
|
||||
mActionButton = findViewById( R.id.amap_search_action_setting );
|
||||
mActionButton.setOnClickListener( view -> {
|
||||
if ( mUiMode == SearchConstants.UI_MODE_MULTI_MY_LOCATION ) {
|
||||
saveCurrentLocationAsCommonAddress();
|
||||
} else if ( mUiMode == SearchConstants.UI_MODE_MULTI_CHOICE_POINT ) {
|
||||
saveRegeoAddressAsCommonAddress();
|
||||
}
|
||||
} );
|
||||
|
||||
switch ( mSearchType ) {
|
||||
case SearchConstants.SEARCH_TYPE_COMMON:
|
||||
commonSearchUI();
|
||||
break;
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_HOME:
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_COMPANY:
|
||||
multiSearchUI();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通搜索UI:不显示我的位置、地图选点、我的定位
|
||||
*/
|
||||
private void commonSearchUI() {
|
||||
mUiMode = SearchConstants.UI_MODE_COMMON;
|
||||
mSearchBox.setEnabled( true );
|
||||
mMyLocation.setVisibility( View.GONE );
|
||||
mChoicePoint.setVisibility( View.GONE );
|
||||
mCurrentLocation.setVisibility( View.GONE );
|
||||
mActionButton.setVisibility( View.INVISIBLE );
|
||||
mSearchResult.setVisibility( View.GONE );
|
||||
if ( mSearchBox.getCompoundDrawables()[2] == null ) {
|
||||
Drawable rightDrawable = null;
|
||||
if ( mSearchBoxRightDrawableBitmap == null ) {
|
||||
mSearchBoxRightDrawableBitmap = BitmapFactory.decodeResource( getResources(), R.drawable.ic_search_unshadow );
|
||||
}
|
||||
rightDrawable = new BitmapDrawable( getResources(), mSearchBoxRightDrawableBitmap );
|
||||
mSearchBox.setCompoundDrawables( null, null, rightDrawable, null );
|
||||
rightDrawable.setBounds( 0, 0, rightDrawable.getIntrinsicWidth(), rightDrawable.getIntrinsicHeight() );
|
||||
}
|
||||
removeChoicePointMarker();
|
||||
mSearchBox.setTag( null );
|
||||
if ( mSearchBox.getLayoutParams() instanceof RelativeLayout.LayoutParams ) {
|
||||
final RelativeLayout.LayoutParams params = ( ( RelativeLayout.LayoutParams ) mSearchBox.getLayoutParams() );
|
||||
params.removeRule( RelativeLayout.LEFT_OF );
|
||||
mSearchBox.setPadding( 0, 0, WindowUtils.dip2px( mContext, 0 ), 0 );
|
||||
mSearchBox.setLayoutParams( params );
|
||||
}
|
||||
mLastAMapLocation = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多项搜索:显示我的位置、地图选点、我的定位
|
||||
*/
|
||||
private void multiSearchUI() {
|
||||
mUiMode = SearchConstants.UI_MODE_MULTI;
|
||||
mSearchBox.setText( "" );
|
||||
mSearchBox.setEnabled( true );
|
||||
mMyLocation.setVisibility( View.VISIBLE );
|
||||
mChoicePoint.setVisibility( View.VISIBLE );
|
||||
mCurrentLocation.setVisibility( View.VISIBLE );
|
||||
mSearchResult.setVisibility( View.GONE );
|
||||
if ( mSearchBox.getCompoundDrawables()[2] == null ) {
|
||||
Drawable rightDrawable = null;
|
||||
if ( mSearchBoxRightDrawableBitmap == null ) {
|
||||
mSearchBoxRightDrawableBitmap = BitmapFactory.decodeResource( getResources(), R.drawable.ic_search_unshadow );
|
||||
}
|
||||
rightDrawable = new BitmapDrawable( getResources(), mSearchBoxRightDrawableBitmap );
|
||||
rightDrawable.setBounds( 0, 0, rightDrawable.getIntrinsicWidth(), rightDrawable.getIntrinsicHeight() );
|
||||
mSearchBox.setCompoundDrawables( null, null, rightDrawable, null );
|
||||
}
|
||||
mActionButton.setVisibility( View.INVISIBLE );
|
||||
removeChoicePointMarker();
|
||||
mSearchBox.setTag( null );
|
||||
if ( mSearchBox.getLayoutParams() instanceof RelativeLayout.LayoutParams ) {
|
||||
final RelativeLayout.LayoutParams params = ( ( RelativeLayout.LayoutParams ) mSearchBox.getLayoutParams() );
|
||||
params.removeRule( RelativeLayout.LEFT_OF );
|
||||
mSearchBox.setPadding( 0, 0, WindowUtils.dip2px( mContext, 0 ), 0 );
|
||||
mSearchBox.setLayoutParams( params );
|
||||
}
|
||||
mLastAMapLocation = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示我的位置,并且可设置为家
|
||||
*/
|
||||
private void multiSearchMyLocationUI() {
|
||||
mUiMode = SearchConstants.UI_MODE_MULTI_MY_LOCATION;
|
||||
mSearchBox.setEnabled( false );
|
||||
mMyLocation.setVisibility( View.GONE );
|
||||
mChoicePoint.setVisibility( View.GONE );
|
||||
mCurrentLocation.setVisibility( View.GONE );
|
||||
mSearchResult.setVisibility( View.GONE );
|
||||
mActionButton.setVisibility( View.VISIBLE );
|
||||
mActionButton.setText( SearchUtils.getSearchTypeActionName( mSearchType ) );
|
||||
mSearchBox.setCompoundDrawables( null, null, null, null );
|
||||
removeChoicePointMarker();
|
||||
mSearchBox.setTag( null );
|
||||
if ( mSearchBox.getLayoutParams() instanceof RelativeLayout.LayoutParams ) {
|
||||
final RelativeLayout.LayoutParams params = ( ( RelativeLayout.LayoutParams ) mSearchBox.getLayoutParams() );
|
||||
params.addRule( RelativeLayout.LEFT_OF, R.id.amap_search_action_setting );
|
||||
mSearchBox.setPadding( 0, 0, WindowUtils.dip2px( mContext, 15 ), 0 );
|
||||
mSearchBox.setLayoutParams( params );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示我的位置,并且可设置为家
|
||||
*/
|
||||
private void multiSearchChoicePointUI() {
|
||||
mUiMode = SearchConstants.UI_MODE_MULTI_CHOICE_POINT;
|
||||
mSearchBox.setEnabled( false );
|
||||
mMyLocation.setVisibility( View.GONE );
|
||||
mChoicePoint.setVisibility( View.GONE );
|
||||
mCurrentLocation.setVisibility( View.GONE );
|
||||
mSearchResult.setVisibility( View.GONE );
|
||||
mActionButton.setVisibility( View.VISIBLE );
|
||||
mActionButton.setText( SearchUtils.getSearchTypeActionName( mSearchType ) );
|
||||
mSearchBox.setCompoundDrawables( null, null, null, null );
|
||||
showChoicePointMarker();
|
||||
mSearchBox.setTag( null );
|
||||
if ( mSearchBox.getLayoutParams() instanceof RelativeLayout.LayoutParams ) {
|
||||
final RelativeLayout.LayoutParams params = ( ( RelativeLayout.LayoutParams ) mSearchBox.getLayoutParams() );
|
||||
params.addRule( RelativeLayout.LEFT_OF, R.id.amap_search_action_setting );
|
||||
mSearchBox.setPadding( 0, 0, WindowUtils.dip2px( mContext, 15 ), 0 );
|
||||
mSearchBox.setLayoutParams( params );
|
||||
}
|
||||
mLastAMapLocation = null;
|
||||
}
|
||||
|
||||
private void saveCurrentLocationAsCommonAddress() {
|
||||
if ( mLastAMapLocation == null ) {
|
||||
shortToast( "定位失败,请重试" );
|
||||
return;
|
||||
}
|
||||
final Disposable disposable = mSearchPresenter.cacheCommonAddressPoi( mLastAMapLocation ).subscribe( output -> {
|
||||
Toast.makeText( mContext, "设置成功!", Toast.LENGTH_SHORT ).show();
|
||||
mActionSuccess = true;
|
||||
}, error -> {
|
||||
if ( error instanceof Exception) {
|
||||
Toast.makeText( mContext, ( (Exception) error ).getMessage(), Toast.LENGTH_SHORT ).show();
|
||||
mActionSuccess = false;
|
||||
}
|
||||
} );
|
||||
mSearchPresenter.addDisposable( disposable );
|
||||
}
|
||||
|
||||
private void saveRegeoAddressAsCommonAddress() {
|
||||
if ( mSearchBox.getTag() instanceof RegeocodeAddress ) {
|
||||
final Disposable disposable = mSearchPresenter.cacheCommonAddressPoi( ( ( RegeocodeAddress ) mSearchBox.getTag() ) ).subscribe( output -> {
|
||||
Toast.makeText( mContext, "设置成功!", Toast.LENGTH_SHORT ).show();
|
||||
mActionSuccess = true;
|
||||
}, error -> {
|
||||
if ( error instanceof Exception) {
|
||||
Toast.makeText( mContext, ( (Exception) error ).getMessage(), Toast.LENGTH_SHORT ).show();
|
||||
mActionSuccess = false;
|
||||
}
|
||||
} );
|
||||
mSearchPresenter.addDisposable( disposable );
|
||||
} else {
|
||||
Toast.makeText( mContext, "请选择位置", Toast.LENGTH_SHORT ).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged( AMapLocation aMapLocation ) {
|
||||
//final String checkMsg = AMapUtils.getAMapLocationErrorMsg( aMapLocation );
|
||||
//if ( AMapUtils.LOC_SUCCESS.equals( checkMsg ) ) {
|
||||
// mLastAMapLocation = aMapLocation;
|
||||
// MapUIController.getInstance().moveCurrentPositionToCenter( new LatLng( aMapLocation.getLatitude(), aMapLocation.getLongitude() ) );
|
||||
// if ( mUiMode == SearchConstants.UI_MODE_MULTI_MY_LOCATION ) {
|
||||
// showMyLocationAddress( aMapLocation );
|
||||
// } else if ( mUiMode == SearchConstants.UI_MODE_MULTI_CHOICE_POINT ) {
|
||||
// showChoicePointAddress( aMapLocation );// 显示当前中心点地址
|
||||
// }
|
||||
//} else {
|
||||
// Toast.makeText( mContext, checkMsg, Toast.LENGTH_SHORT ).show();
|
||||
//}
|
||||
AMapLocationManager.getInstance( mContext ).removeLocationListener( this );
|
||||
AMapLocationManager.getInstance( mContext ).stop();
|
||||
}
|
||||
|
||||
private void showMyLocationAddress( AMapLocation location ) {
|
||||
if ( location == null ) {
|
||||
return;
|
||||
}
|
||||
mSearchBox.setEnabled( false );
|
||||
mSearchBox.setText( location.getPoiName() );
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示点选marker,隐藏自车marker
|
||||
*/
|
||||
private void showChoicePointMarker() {
|
||||
|
||||
final AMap aMap = mUiController.getAMapServiceVisitor().getMap();
|
||||
if ( aMap == null ) {
|
||||
return;
|
||||
}
|
||||
// AMapService 里设置了监听,此处会覆盖
|
||||
LatLng latLng = aMap.getCameraPosition().target;
|
||||
Point screenPosition = aMap.getProjection().toScreenLocation( latLng );
|
||||
mChoicePointMaker = aMap.addMarker( new MarkerOptions().zIndex( 1 ).anchor( 0.5f, 0.5f ).position( latLng ).icon( BitmapDescriptorFactory.fromResource( R.drawable.ic_search_choice_point ) ) );
|
||||
mChoicePointMaker.setPositionByPixels( screenPosition.x, screenPosition.y );
|
||||
MapUIController.getInstance().changeMyLocationVisibility( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏点选marker,显示自车marker
|
||||
*/
|
||||
private void removeChoicePointMarker() {
|
||||
if ( mChoicePointMaker != null ) {
|
||||
mChoicePointMaker.remove();
|
||||
}
|
||||
mChoicePointMaker = null;
|
||||
MapUIController.getInstance().changeMyLocationVisibility( true );
|
||||
}
|
||||
|
||||
private void showChoicePointAddress( AMapLocation location ) {
|
||||
if ( location == null ) {
|
||||
return;
|
||||
}
|
||||
mSearchBox.setEnabled( false );
|
||||
mSearchBox.setText( location.getPoiName() );
|
||||
}
|
||||
|
||||
// view interface
|
||||
|
||||
@Override
|
||||
public EditText getSearchBox() {
|
||||
return mSearchBox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderSearchPoiResult( List< Tip > datums, boolean showDelete ) {
|
||||
|
||||
if ( datums == null || datums.isEmpty() ) {
|
||||
mSearchResult.setVisibility( View.GONE );
|
||||
} else {
|
||||
mSearchResult.setVisibility( View.VISIBLE );
|
||||
}
|
||||
|
||||
if ( mPoiAdapter == null ) {
|
||||
mPoiAdapter = new SearchPoiAdapter(getContext(), datums );
|
||||
mPoiAdapter.setOnItemClickedListener( item -> {
|
||||
if ( mSearchType == SearchConstants.SEARCH_TYPE_COMMON ) {
|
||||
final Disposable disposable = mSearchPresenter.cacheSelectPoiItem( item ).subscribe( output -> {
|
||||
navi2Location( EntityConvertUtils.tipToPoi( item ) );
|
||||
} );
|
||||
mSearchPresenter.addDisposable( disposable );
|
||||
} else {
|
||||
// do nothing.
|
||||
}
|
||||
} );
|
||||
mPoiAdapter.setOnDeleteAllClickedListener( NULL -> {
|
||||
mSearchPresenter.deleteAllCachedPoi();
|
||||
} );
|
||||
mPoiAdapter.setOnActionButtonClickedListener( poi -> {
|
||||
final Disposable disposable = mSearchPresenter.cacheCommonAddressPoi( poi ).subscribe( output -> {
|
||||
Toast.makeText( mContext, "设置成功!", Toast.LENGTH_SHORT ).show();
|
||||
mActionSuccess = true;
|
||||
} );
|
||||
mSearchPresenter.addDisposable( disposable );
|
||||
} );
|
||||
mPoiAdapter.setShowDelete( showDelete );
|
||||
mSearchResult.setAdapter( mPoiAdapter );
|
||||
} else {
|
||||
if ( datums != null && !datums.isEmpty() ) {
|
||||
mSearchResult.scrollToPosition( 0 );
|
||||
}
|
||||
mPoiAdapter.refresh( datums, showDelete );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSearchType() {
|
||||
return mSearchType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUiMode() {
|
||||
return mUiMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderChoicePointResult( RegeocodeAddress address ) {
|
||||
if ( address == null ) {
|
||||
mSearchBox.setTag( null );
|
||||
mSearchBox.setText( "" );
|
||||
return;
|
||||
}
|
||||
mSearchBox.setTag( address );
|
||||
mSearchBox.setText( address.getFormatAddress() );
|
||||
}
|
||||
|
||||
//@Override
|
||||
//public void renderErrorView() {
|
||||
//
|
||||
//}
|
||||
//
|
||||
//@Override
|
||||
//public void renderContentView() {
|
||||
//
|
||||
//}
|
||||
|
||||
// view interface end
|
||||
|
||||
/**
|
||||
* 屏幕中心marker 跳动
|
||||
*/
|
||||
@Override
|
||||
public void startJumpAnimation() {
|
||||
|
||||
final AMap aMap = mUiController.getAMapServiceVisitor().getMap();
|
||||
|
||||
if ( mChoicePointMaker != null ) {
|
||||
//根据屏幕距离计算需要移动的目标点
|
||||
final LatLng latLng = mChoicePointMaker.getPosition();
|
||||
Point point = aMap.getProjection().toScreenLocation( latLng );
|
||||
point.y -= WindowUtils.dip2px( mContext, 125 );
|
||||
LatLng target = aMap.getProjection()
|
||||
.fromScreenLocation( point );
|
||||
//使用TranslateAnimation,填写一个需要移动的目标点
|
||||
Animation animation = new TranslateAnimation( target );
|
||||
animation.setInterpolator( new Interpolator() {
|
||||
@Override
|
||||
public float getInterpolation( float input ) {
|
||||
// 模拟重加速度的interpolator
|
||||
if ( input <= 0.5 ) {
|
||||
return ( float ) ( 0.5f - 2 * ( 0.5 - input ) * ( 0.5 - input ) );
|
||||
} else {
|
||||
return ( float ) ( 0.5f - Math.sqrt( ( input - 0.5f ) * ( 1.5f - input ) ) );
|
||||
}
|
||||
}
|
||||
} );
|
||||
//整个移动所需要的时间
|
||||
animation.setDuration( 600 );
|
||||
//设置动画
|
||||
mChoicePointMaker.setAnimation( animation );
|
||||
//开始动画
|
||||
mChoicePointMaker.startAnimation();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param searchPoi 导航目的地
|
||||
*/
|
||||
private void navi2Location( SearchPoi searchPoi ) {
|
||||
|
||||
if ( searchPoi == null || searchPoi == SearchPoi.NULL ) {
|
||||
Toast.makeText( mContext, "未设置", Toast.LENGTH_SHORT ).show();
|
||||
return;
|
||||
}
|
||||
//SearchPoiLiveData.getInstance().postValue( searchPoi );
|
||||
exitSearch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出搜索,进行清理
|
||||
*/
|
||||
private void exitSearch() {
|
||||
|
||||
switch ( mSearchType ) {
|
||||
case SearchConstants.SEARCH_TYPE_COMMON:
|
||||
try {
|
||||
mUiController.popBackStackImmediate();
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_HOME:
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_COMPANY:
|
||||
if ( !mActionSuccess ) {
|
||||
// 通过搜索框搜索,在设置成功之前点击返回按钮,返回到未搜索状态
|
||||
if ( mUiMode != SearchConstants.UI_MODE_MULTI || mSearchResult.getVisibility() == View.VISIBLE ) {
|
||||
multiSearchUI();
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
mUiController.popBackStackImmediate();
|
||||
mUiController.onSettingsMode();
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if ( mSearchPresenter != null ) {
|
||||
mSearchPresenter.onDestroy( getViewLifecycleOwner() );
|
||||
getLifecycle().removeObserver( mSearchPresenter );
|
||||
mSearchPresenter = null;
|
||||
}
|
||||
mSearchBox.setTag( null );
|
||||
mUiController = null;
|
||||
if ( mSearchBoxRightDrawableBitmap != null ) {
|
||||
try {
|
||||
mSearchBoxRightDrawableBitmap.recycle();
|
||||
} catch ( Exception e ) {
|
||||
}
|
||||
}
|
||||
if ( mPoiAdapter != null ) {
|
||||
mPoiAdapter.clear();
|
||||
}
|
||||
mPoiAdapter = null;
|
||||
mSearchBoxRightDrawableBitmap = null;
|
||||
removeChoicePointMarker();
|
||||
AMapLocationManager.getInstance( mContext ).release();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
package com.mogo.module.navi.ui.search;
|
||||
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.EditText;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import com.amap.api.location.AMapLocation;
|
||||
import com.amap.api.maps.model.CameraPosition;
|
||||
import com.amap.api.services.core.LatLonPoint;
|
||||
import com.amap.api.services.geocoder.GeocodeResult;
|
||||
import com.amap.api.services.geocoder.GeocodeSearch;
|
||||
import com.amap.api.services.geocoder.RegeocodeAddress;
|
||||
import com.amap.api.services.geocoder.RegeocodeQuery;
|
||||
import com.amap.api.services.geocoder.RegeocodeResult;
|
||||
import com.amap.api.services.help.Inputtips;
|
||||
import com.amap.api.services.help.InputtipsQuery;
|
||||
import com.amap.api.services.help.Tip;
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
import com.mogo.module.common.TextWatcherAdapter;
|
||||
import com.mogo.module.navi.bean.EntityConvertUtils;
|
||||
import com.mogo.module.navi.bean.SearchPoi;
|
||||
import com.mogo.module.navi.constants.DataConstants;
|
||||
import com.mogo.module.navi.database.AppDataBase;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.SingleEmitter;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-02
|
||||
* <p>
|
||||
* 搜搜页逻辑处理
|
||||
*/
|
||||
public class SearchPresenter extends Presenter< SearchView >
|
||||
implements Inputtips.InputtipsListener, GeocodeSearch.OnGeocodeSearchListener {
|
||||
|
||||
private Inputtips mSearchEngine;
|
||||
private GeocodeSearch mGeocodeSearch;
|
||||
|
||||
private CompositeDisposable mCompositeDisposable;
|
||||
private CameraPosition mLastCameraPosition;
|
||||
|
||||
public SearchPresenter( SearchView view ) {
|
||||
super( view );
|
||||
mCompositeDisposable = new CompositeDisposable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate( @NonNull LifecycleOwner owner ) {
|
||||
super.onCreate( owner );
|
||||
attachSearchBoxTextWatcher( mView.getSearchBox() );
|
||||
switch ( mView.getSearchType() ) {
|
||||
case SearchConstants.SEARCH_TYPE_COMMON:
|
||||
loadHistories();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void loadHistories() {
|
||||
}
|
||||
|
||||
private void attachSearchBoxTextWatcher( EditText editText ) {
|
||||
if ( editText == null ) {
|
||||
return;
|
||||
}
|
||||
editText.addTextChangedListener(watcherAdapter);
|
||||
}
|
||||
|
||||
private final TextWatcherAdapter watcherAdapter = new TextWatcherAdapter() {
|
||||
@Override
|
||||
public void afterTextChanged( Editable s ) {
|
||||
// 避免 disable 设置内容时触发
|
||||
final String input = s.toString();
|
||||
startSearchPoiByInput( input );
|
||||
}
|
||||
};
|
||||
|
||||
private void startSearchPoiByInput( String keyword ) {
|
||||
switch ( mView.getUiMode() ) {
|
||||
// 如果是普通搜索,清空搜索内容后需要加载缓存历史,否则不需要
|
||||
case SearchConstants.UI_MODE_COMMON:
|
||||
if ( TextUtils.isEmpty( keyword ) ) {
|
||||
loadHistories();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SearchConstants.UI_MODE_MULTI_CHOICE_POINT:
|
||||
case SearchConstants.UI_MODE_MULTI_MY_LOCATION:
|
||||
return;
|
||||
case SearchConstants.UI_MODE_MULTI:
|
||||
if ( TextUtils.isEmpty( keyword ) ) {
|
||||
mView.renderSearchPoiResult( null, false );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
final InputtipsQuery searchQuery = new InputtipsQuery( keyword, "" );
|
||||
if ( mSearchEngine == null ) {
|
||||
mSearchEngine = new Inputtips( getContext(), searchQuery );
|
||||
mSearchEngine.setInputtipsListener( this );
|
||||
} else {
|
||||
mSearchEngine.setQuery( searchQuery );
|
||||
}
|
||||
mSearchEngine.requestInputtipsAsyn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetInputtips( List<Tip> list, int i ) {
|
||||
if ( mView != null ) {
|
||||
mView.renderSearchPoiResult( list, false );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存搜索到的导航地址
|
||||
*
|
||||
* @param tip
|
||||
* @return
|
||||
*/
|
||||
public Single cacheSelectPoiItem( Tip tip ) {
|
||||
return Single.create( emitter -> {
|
||||
SearchPoi poi = EntityConvertUtils.tipToPoi( tip );
|
||||
//ignore insert result
|
||||
final List<Long> output = AppDataBase.getDatabase( getContext() ).poiDao().insert( poi );
|
||||
emitter.onSuccess( output );
|
||||
} ).subscribeOn( Schedulers.io() ).observeOn( AndroidSchedulers.mainThread() );
|
||||
}
|
||||
|
||||
public void addDisposable( Disposable disposable ) {
|
||||
mCompositeDisposable.add( disposable );
|
||||
}
|
||||
|
||||
public void deleteAllCachedPoi() {
|
||||
|
||||
new AlertDialog.Builder( getContext() )
|
||||
.setMessage( "清空历史记录?" )
|
||||
.setPositiveButton( "立即清空", ( dlg, which ) -> {
|
||||
dlg.dismiss();
|
||||
deleteAllCachedPoiImpl();
|
||||
} )
|
||||
.setNegativeButton( "取消", ( dlg, which ) -> {
|
||||
dlg.dismiss();
|
||||
} )
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
private void deleteAllCachedPoiImpl() {
|
||||
final Disposable disposable = AppDataBase.getDatabase( getContext() )
|
||||
.poiDao()
|
||||
.getAll()
|
||||
.map( input -> {
|
||||
return AppDataBase.getDatabase( getContext() ).poiDao().deleteAll( input );
|
||||
} )
|
||||
.subscribeOn( Schedulers.io() )
|
||||
.observeOn( AndroidSchedulers.mainThread() )
|
||||
.subscribe( count -> {
|
||||
mView.renderSearchPoiResult( null, false );
|
||||
} );
|
||||
mCompositeDisposable.add( disposable );
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存搜索位置为常用地址设置
|
||||
*
|
||||
* @param tip
|
||||
* @return
|
||||
*/
|
||||
public Single cacheCommonAddressPoi( Tip tip ) {
|
||||
return Single.<List<Long>>create( emitter -> {
|
||||
SearchPoi poi = EntityConvertUtils.tipToPoi( tip );
|
||||
emitterCommonAddress( emitter, poi );
|
||||
} ).subscribeOn( Schedulers.io() ).observeOn( AndroidSchedulers.mainThread() );
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存地理位置常用地址设置
|
||||
*
|
||||
* @param location
|
||||
* @return
|
||||
*/
|
||||
public Single cacheCommonAddressPoi( AMapLocation location ) {
|
||||
return Single.
|
||||
<List<Long>>create( emitter -> {
|
||||
SearchPoi poi = EntityConvertUtils.aMapLocation2Poi( location );
|
||||
emitterCommonAddress( emitter, poi );
|
||||
} )
|
||||
.subscribeOn( Schedulers.io() )
|
||||
.observeOn( AndroidSchedulers.mainThread() );
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存反地理位置编码常用地址设置
|
||||
*
|
||||
* @param address
|
||||
* @return
|
||||
*/
|
||||
public Single cacheCommonAddressPoi( RegeocodeAddress address ) {
|
||||
|
||||
return Single.
|
||||
<List<Long>>create( emitter -> {
|
||||
SearchPoi poi = EntityConvertUtils.geocodeAddress2Poi( address, mLastCameraPosition );
|
||||
emitterCommonAddress( emitter, poi );
|
||||
} )
|
||||
.subscribeOn( Schedulers.io() )
|
||||
.observeOn( AndroidSchedulers.mainThread() );
|
||||
}
|
||||
|
||||
private void emitterCommonAddress( SingleEmitter<List<Long>> emitter, SearchPoi poi ) {
|
||||
String poiId = null;
|
||||
switch ( mView.getSearchType() ) {
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_HOME:
|
||||
poiId = DataConstants.POI_ID_HOME;
|
||||
break;
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_COMPANY:
|
||||
poiId = DataConstants.POI_ID_COMPANY;
|
||||
break;
|
||||
}
|
||||
if ( TextUtils.isEmpty( poiId ) ) {
|
||||
emitter.onError( new IllegalArgumentException( "设置类型错误,请重试" ) );
|
||||
return;
|
||||
}
|
||||
if ( poi == null ) {
|
||||
emitter.onError( new IllegalArgumentException( "位置类型转换错误,请重试" ) );
|
||||
return;
|
||||
}
|
||||
poi.setpId( poiId );
|
||||
poi.setType( mView.getSearchType() );
|
||||
//ignore insert result
|
||||
final List<Long> output = AppDataBase.getDatabase( getContext() ).poiDao().insert( poi );
|
||||
notifyAIAssistCommonAddressChanged();
|
||||
emitter.onSuccess( output );
|
||||
}
|
||||
|
||||
private void notifyAIAssistCommonAddressChanged() {
|
||||
//if ( view.getSearchType() == SearchConstants.SEARCH_TYPE_MULTI_HOME ) {
|
||||
// AddressHelper.notifyHomeAddressChanged( getContext() );
|
||||
//} else if ( view.getSearchType() == SearchConstants.SEARCH_TYPE_MULTI_COMPANY ) {
|
||||
// AddressHelper.notifyCompanyAddressChanged( getContext() );
|
||||
//
|
||||
//}
|
||||
}
|
||||
|
||||
private void startSearchPoiByPoint( CameraPosition position ) {
|
||||
if ( position == null ) {
|
||||
return;
|
||||
}
|
||||
RegeocodeQuery
|
||||
query = new RegeocodeQuery( new LatLonPoint( position.target.latitude, position.target.longitude ), 200, GeocodeSearch.AMAP );
|
||||
if ( mGeocodeSearch == null ) {
|
||||
mGeocodeSearch = new GeocodeSearch( getContext() );
|
||||
mGeocodeSearch.setOnGeocodeSearchListener( this );
|
||||
}
|
||||
mGeocodeSearch.getFromLocationAsyn( query );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegeocodeSearched( RegeocodeResult regeocodeResult, int resultID ) {
|
||||
if ( resultID == 1000 ) { // success
|
||||
mView.renderChoicePointResult( regeocodeResult.getRegeocodeAddress() );
|
||||
} else {
|
||||
mView.renderChoicePointResult( null );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGeocodeSearched( GeocodeResult geocodeResult, int resultID ) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy( @NonNull LifecycleOwner owner ) {
|
||||
super.onDestroy( owner );
|
||||
if ( mView.getSearchBox() != null ) {
|
||||
mView.getSearchBox().removeTextChangedListener( watcherAdapter );
|
||||
}
|
||||
if ( mCompositeDisposable != null && !mCompositeDisposable.isDisposed() ) {
|
||||
mCompositeDisposable.dispose();
|
||||
mCompositeDisposable = null;
|
||||
}
|
||||
//CameraChangedLiveData.getInstance().removeAllObserver();
|
||||
mSearchEngine = null;
|
||||
mGeocodeSearch = null;
|
||||
mLastCameraPosition = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.mogo.module.navi.ui.search;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-12-08
|
||||
* <p>
|
||||
* 搜索工具类
|
||||
*/
|
||||
public class SearchUtils {
|
||||
|
||||
/**
|
||||
* @param searchType
|
||||
* @return
|
||||
*/
|
||||
public static int checkAndResetSearchType( int searchType ) {
|
||||
switch ( searchType ) {
|
||||
case SearchConstants.SEARCH_TYPE_COMMON:
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_HOME:
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_COMPANY:
|
||||
break;
|
||||
default:
|
||||
searchType = SearchConstants.SEARCH_TYPE_COMMON;
|
||||
break;
|
||||
}
|
||||
return searchType;
|
||||
}
|
||||
|
||||
public static String getSearchTypeActionName( int searchType ) {
|
||||
switch ( searchType ) {
|
||||
case SearchConstants.SEARCH_TYPE_COMMON:
|
||||
return null;
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_HOME:
|
||||
return "设为家";
|
||||
case SearchConstants.SEARCH_TYPE_MULTI_COMPANY:
|
||||
return "设为公司";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.mogo.module.navi.ui.search;
|
||||
|
||||
import android.widget.EditText;
|
||||
import com.amap.api.services.geocoder.RegeocodeAddress;
|
||||
import com.amap.api.services.help.Tip;
|
||||
import com.mogo.commons.mvp.IView;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-02
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public interface SearchView extends IView {
|
||||
|
||||
EditText getSearchBox();
|
||||
|
||||
/**
|
||||
* @param datums
|
||||
* @param showDelete 是否显示清空历史记录项
|
||||
*/
|
||||
void renderSearchPoiResult(List<Tip> datums, boolean showDelete);
|
||||
|
||||
int getSearchType();
|
||||
|
||||
/**
|
||||
* 当前是哪一个操作
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getUiMode();
|
||||
|
||||
/**
|
||||
* 显示逆地理位置编码结果
|
||||
*
|
||||
* @param address
|
||||
*/
|
||||
void renderChoicePointResult(RegeocodeAddress address);
|
||||
|
||||
/**
|
||||
* 选点完毕后marker动画
|
||||
*/
|
||||
void startJumpAnimation();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.mogo.module.navi.wrapper;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import com.amap.api.navi.model.AMapCalcRouteResult;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-09-27
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class AMapCalcRouteResultWrapper implements Parcelable {
|
||||
|
||||
private final int errorCode;
|
||||
private final int[] routeId;
|
||||
private final int calcRouteType;
|
||||
private final String errorDetail;
|
||||
|
||||
public AMapCalcRouteResultWrapper( AMapCalcRouteResult result ) {
|
||||
errorCode = result.getErrorCode();
|
||||
routeId = result.getRouteid();
|
||||
calcRouteType = result.getCalcRouteType();
|
||||
errorDetail = result.getErrorDetail();
|
||||
}
|
||||
|
||||
public AMapCalcRouteResult parse() {
|
||||
final AMapCalcRouteResult inst = new AMapCalcRouteResult();
|
||||
inst.setErrorCode( getErrorCode() );
|
||||
inst.setRouteid( getRouteId() );
|
||||
inst.setCalcRouteType( getCalcRouteType() );
|
||||
inst.setErrorDetail( getErrorDetail() );
|
||||
return inst;
|
||||
}
|
||||
|
||||
public int getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public int[] getRouteId() {
|
||||
return routeId;
|
||||
}
|
||||
|
||||
public int getCalcRouteType() {
|
||||
return calcRouteType;
|
||||
}
|
||||
|
||||
public String getErrorDetail() {
|
||||
return errorDetail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel( Parcel dest, int flags ) {
|
||||
dest.writeInt( this.errorCode );
|
||||
dest.writeIntArray( this.routeId );
|
||||
dest.writeInt( this.calcRouteType );
|
||||
dest.writeString( this.errorDetail );
|
||||
}
|
||||
|
||||
protected AMapCalcRouteResultWrapper( Parcel in ) {
|
||||
this.errorCode = in.readInt();
|
||||
this.routeId = in.createIntArray();
|
||||
this.calcRouteType = in.readInt();
|
||||
this.errorDetail = in.readString();
|
||||
}
|
||||
|
||||
public static final Creator< AMapCalcRouteResultWrapper > CREATOR = new Creator< AMapCalcRouteResultWrapper >() {
|
||||
@Override
|
||||
public AMapCalcRouteResultWrapper createFromParcel( Parcel source ) {
|
||||
return new AMapCalcRouteResultWrapper( source );
|
||||
}
|
||||
|
||||
@Override
|
||||
public AMapCalcRouteResultWrapper[] newArray( int size ) {
|
||||
return new AMapCalcRouteResultWrapper[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.mogo.module.navi.wrapper;
|
||||
|
||||
import com.amap.api.navi.model.AMapNaviCameraInfo;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-10-10
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class AMapNaviCameraInfoWrapper {
|
||||
|
||||
private int cameraDistance;
|
||||
private double x;
|
||||
private double y;
|
||||
/**
|
||||
* {@link AMapNaviCameraInfo#getCameraType()}
|
||||
* {@link com.amap.api.navi.enums.CameraType#SPEED} 测速摄像
|
||||
* {@link com.amap.api.navi.enums.CameraType#SURVEILLANCE}监控摄像
|
||||
* {@link com.amap.api.navi.enums.CameraType#TRAFFICLIGHT} 闯红灯拍照
|
||||
* {@link com.amap.api.navi.enums.CameraType#BREAKRULE} 违章拍照
|
||||
* {@link com.amap.api.navi.enums.CameraType#BUSWAY} 公交专用道摄像头
|
||||
* {@link com.amap.api.navi.enums.CameraType#EMERGENCY}应急车道拍照
|
||||
* {@link com.amap.api.navi.enums.CameraType#BICYCLE}非机动车道(暂未使用)
|
||||
* {@link com.amap.api.navi.enums.CameraType#INTERVALVELOCITYSTART}区间测速起始
|
||||
* {@link com.amap.api.navi.enums.CameraType#INTERVALVELOCITYEND}区间测速解除
|
||||
*/
|
||||
private int cameraType;
|
||||
private int cameraSpeed;
|
||||
private int averageSpeed;
|
||||
private int reasonableSpeedInRemainDist;
|
||||
private int distance;
|
||||
private int[] speed;
|
||||
|
||||
public AMapNaviCameraInfoWrapper( AMapNaviCameraInfo info ) {
|
||||
if ( info != null ) {
|
||||
cameraDistance = info.getCameraDistance();
|
||||
x = info.getX();
|
||||
y = info.getY();
|
||||
cameraType = info.getCameraType();
|
||||
cameraSpeed = info.getCameraSpeed();
|
||||
averageSpeed = info.getAverageSpeed();
|
||||
reasonableSpeedInRemainDist = info.getReasonableSpeedInRemainDist();
|
||||
distance = info.getDistance();
|
||||
speed = info.getSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append( "cameraDistance" ).append( "=" ).append( cameraDistance ).append( "\n" );
|
||||
builder.append( "cameraType" ).append( "=" ).append( cameraType ).append( "\n" );
|
||||
builder.append( "cameraSpeed" ).append( "=" ).append( cameraSpeed ).append( "\n" );
|
||||
builder.append( "averageSpeed" ).append( "=" ).append( averageSpeed ).append( "\n" );
|
||||
builder.append( "reasonableSpeedInRemainDist" ).append( "=" ).append( reasonableSpeedInRemainDist ).append( "\n" );
|
||||
builder.append( "distance" ).append( "=" ).append( distance ).append( "\n" );
|
||||
if ( speed != null ) {
|
||||
builder.append( "speed" ).append( "=" ).append( speed ).append( "\n" );
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public int getCameraDistance() {
|
||||
return cameraDistance;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getCameraType() {
|
||||
return cameraType;
|
||||
}
|
||||
|
||||
public int getCameraSpeed() {
|
||||
return cameraSpeed;
|
||||
}
|
||||
|
||||
public int getAverageSpeed() {
|
||||
return averageSpeed;
|
||||
}
|
||||
|
||||
public int getReasonableSpeedInRemainDist() {
|
||||
return reasonableSpeedInRemainDist;
|
||||
}
|
||||
|
||||
public int getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public int[] getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.mogo.module.navi.wrapper;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import com.amap.api.navi.model.AMapNaviLocation;
|
||||
import com.amap.api.navi.model.NaviLatLng;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-09-26
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class AMapNaviLocationWrapper implements Parcelable {
|
||||
|
||||
private final float accuracy;
|
||||
private final double altitude;
|
||||
private final float bearing;
|
||||
private final float speed;
|
||||
private final long time;
|
||||
private final int matchStatus;
|
||||
private final NaviLatLng coord;
|
||||
private final int curStepIndex;
|
||||
private final int curLinkIndex;
|
||||
private final int curPointIndex;
|
||||
private final int type;
|
||||
|
||||
public AMapNaviLocationWrapper( AMapNaviLocation aMapNaviLocation ) {
|
||||
this.accuracy = aMapNaviLocation.getAccuracy();
|
||||
this.altitude = aMapNaviLocation.getAltitude();
|
||||
this.bearing = aMapNaviLocation.getBearing();
|
||||
this.speed = aMapNaviLocation.getSpeed();
|
||||
this.time = aMapNaviLocation.getTime();
|
||||
this.matchStatus = aMapNaviLocation.getMatchStatus();
|
||||
this.coord = aMapNaviLocation.getCoord();
|
||||
this.curStepIndex = aMapNaviLocation.getCurStepIndex();
|
||||
this.curLinkIndex = aMapNaviLocation.getCurLinkIndex();
|
||||
this.curPointIndex = aMapNaviLocation.getCurPointIndex();
|
||||
this.type = aMapNaviLocation.getType();
|
||||
}
|
||||
|
||||
public AMapNaviLocation parse() {
|
||||
final AMapNaviLocation inst = new AMapNaviLocation();
|
||||
inst.setAccuracy( getAccuracy() );
|
||||
inst.setAltitude( getAltitude() );
|
||||
inst.setBearing( getBearing() );
|
||||
inst.setSpeed( getSpeed() );
|
||||
inst.setTime( getTime() );
|
||||
inst.setMatchStatus( getMatchStatus() );
|
||||
inst.setCoord( getCoord() );
|
||||
inst.setCurStepIndex( getCurStepIndex() );
|
||||
inst.setCurLinkIndex( getCurLinkIndex() );
|
||||
inst.setCurPointIndex( getCurPointIndex() );
|
||||
inst.setType( getType() );
|
||||
return inst;
|
||||
}
|
||||
|
||||
public float getAccuracy() {
|
||||
return accuracy;
|
||||
}
|
||||
|
||||
public double getAltitude() {
|
||||
return altitude;
|
||||
}
|
||||
|
||||
public float getBearing() {
|
||||
return bearing;
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public int getMatchStatus() {
|
||||
return matchStatus;
|
||||
}
|
||||
|
||||
public NaviLatLng getCoord() {
|
||||
return coord;
|
||||
}
|
||||
|
||||
public int getCurStepIndex() {
|
||||
return curStepIndex;
|
||||
}
|
||||
|
||||
public int getCurLinkIndex() {
|
||||
return curLinkIndex;
|
||||
}
|
||||
|
||||
public int getCurPointIndex() {
|
||||
return curPointIndex;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel( Parcel dest, int flags ) {
|
||||
dest.writeFloat( this.accuracy );
|
||||
dest.writeDouble( this.altitude );
|
||||
dest.writeFloat( this.bearing );
|
||||
dest.writeFloat( this.speed );
|
||||
dest.writeLong( this.time );
|
||||
dest.writeInt( this.matchStatus );
|
||||
dest.writeParcelable( this.coord, flags );
|
||||
dest.writeInt( this.curStepIndex );
|
||||
dest.writeInt( this.curLinkIndex );
|
||||
dest.writeInt( this.curPointIndex );
|
||||
dest.writeInt( this.type );
|
||||
}
|
||||
|
||||
protected AMapNaviLocationWrapper( Parcel in ) {
|
||||
this.accuracy = in.readFloat();
|
||||
this.altitude = in.readDouble();
|
||||
this.bearing = in.readFloat();
|
||||
this.speed = in.readFloat();
|
||||
this.time = in.readLong();
|
||||
this.matchStatus = in.readInt();
|
||||
this.coord = in.readParcelable( NaviLatLng.class.getClassLoader() );
|
||||
this.curStepIndex = in.readInt();
|
||||
this.curLinkIndex = in.readInt();
|
||||
this.curPointIndex = in.readInt();
|
||||
this.type = in.readInt();
|
||||
}
|
||||
|
||||
public static final Creator< AMapNaviLocationWrapper >
|
||||
CREATOR = new Parcelable.Creator< AMapNaviLocationWrapper >() {
|
||||
@Override
|
||||
public AMapNaviLocationWrapper createFromParcel( Parcel source ) {
|
||||
return new AMapNaviLocationWrapper( source );
|
||||
}
|
||||
|
||||
@Override
|
||||
public AMapNaviLocationWrapper[] newArray( int size ) {
|
||||
return new AMapNaviLocationWrapper[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.mogo.module.navi.wrapper;
|
||||
|
||||
import android.location.Location;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.navi.model.AMapNaviLocation;
|
||||
import com.amap.api.navi.model.NaviLatLng;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-09-26
|
||||
* <p>
|
||||
* 经纬度
|
||||
*/
|
||||
public class LatLngWrapper implements Parcelable {
|
||||
|
||||
private final double lat;
|
||||
private final double lng;
|
||||
|
||||
public LatLngWrapper( double lat, double lng ) {
|
||||
this.lat = lat;
|
||||
this.lng = lng;
|
||||
}
|
||||
|
||||
public double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public double getLng() {
|
||||
return lng;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel( Parcel dest, int flags ) {
|
||||
dest.writeDouble( this.lat );
|
||||
dest.writeDouble( this.lng );
|
||||
}
|
||||
|
||||
protected LatLngWrapper( Parcel in ) {
|
||||
this.lat = in.readDouble();
|
||||
this.lng = in.readDouble();
|
||||
}
|
||||
|
||||
public static final Creator< LatLngWrapper > CREATOR = new Creator< LatLngWrapper >() {
|
||||
@Override
|
||||
public LatLngWrapper createFromParcel( Parcel source ) {
|
||||
return new LatLngWrapper( source );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLngWrapper[] newArray( int size ) {
|
||||
return new LatLngWrapper[size];
|
||||
}
|
||||
};
|
||||
|
||||
public static LatLngWrapper from( LatLng latlng ) {
|
||||
return new LatLngWrapper( latlng.latitude, latlng.longitude );
|
||||
}
|
||||
|
||||
public static LatLngWrapper from( NaviLatLng latlng ) {
|
||||
return new LatLngWrapper( latlng.getLatitude(), latlng.getLongitude() );
|
||||
}
|
||||
|
||||
public static LatLngWrapper from( AMapNaviLocation latlng ) {
|
||||
return from( latlng.getCoord() );
|
||||
}
|
||||
|
||||
public LatLng parseLatLngInst() {
|
||||
return new LatLng( getLat(), getLng() );
|
||||
}
|
||||
|
||||
public static LatLng parse( NaviLatLng latLng ) {
|
||||
if ( latLng == null ) {
|
||||
return null;
|
||||
}
|
||||
return new LatLng( latLng.getLatitude(), latLng.getLongitude() );
|
||||
}
|
||||
|
||||
public static LatLng parse( Location location ) {
|
||||
if ( location == null ) {
|
||||
return null;
|
||||
}
|
||||
return new LatLng( location.getLatitude(), location.getLongitude() );
|
||||
}
|
||||
|
||||
public static LatLng parse( double lat, double lng ) {
|
||||
if ( isRightLatLng( lat, lng ) ) {
|
||||
return new LatLng( lat, lng );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isRightLatLng( double lat, double lng ) {
|
||||
return lat > 0 && lat < 90 && lng > 0 && lng < 180;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.mogo.module.navi.wrapper;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import com.amap.api.navi.model.NaviInfo;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2019-09-29
|
||||
* <p>
|
||||
* 导航信息对象
|
||||
*/
|
||||
public class NaviInfoWrapper implements Parcelable {
|
||||
|
||||
private static final NaviInfoWrapper INST = new NaviInfoWrapper();
|
||||
|
||||
private int nextIconType;
|
||||
private int nextDistance;
|
||||
private String nextRoad;
|
||||
private int surplusDistance;
|
||||
private int surplusTime;
|
||||
private int currentSpeed;
|
||||
|
||||
private NaviInfoWrapper() {
|
||||
|
||||
}
|
||||
|
||||
public static NaviInfoWrapper getInst() {
|
||||
return INST;
|
||||
}
|
||||
|
||||
public synchronized NaviInfoWrapper fillWith( NaviInfo naviInfo ) {
|
||||
INST.nextIconType = naviInfo.getIconType();
|
||||
INST.nextDistance = naviInfo.getCurStepRetainDistance();
|
||||
INST.nextRoad = naviInfo.getNextRoadName();
|
||||
INST.surplusDistance = naviInfo.getPathRetainDistance();
|
||||
INST.surplusTime = naviInfo.getPathRetainTime();
|
||||
INST.currentSpeed = naviInfo.getCurrentSpeed();
|
||||
return INST;
|
||||
}
|
||||
|
||||
public NaviInfoWrapper( NaviInfo naviInfo ) {
|
||||
this.nextIconType = naviInfo.getIconType();
|
||||
this.nextDistance = naviInfo.getCurStepRetainDistance();
|
||||
this.nextRoad = naviInfo.getNextRoadName();
|
||||
this.surplusDistance = naviInfo.getPathRetainDistance();
|
||||
this.surplusTime = naviInfo.getPathRetainTime();
|
||||
this.currentSpeed = naviInfo.getCurrentSpeed();
|
||||
}
|
||||
|
||||
public synchronized int getNextIconType() {
|
||||
return nextIconType;
|
||||
}
|
||||
|
||||
public synchronized int getNextDistance() {
|
||||
return nextDistance;
|
||||
}
|
||||
|
||||
public synchronized String getNextRoad() {
|
||||
return nextRoad;
|
||||
}
|
||||
|
||||
public synchronized int getSurplusDistance() {
|
||||
return surplusDistance;
|
||||
}
|
||||
|
||||
public synchronized int getSurplusTime() {
|
||||
return surplusTime;
|
||||
}
|
||||
|
||||
public synchronized int getCurrentSpeed() {
|
||||
return currentSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel( Parcel dest, int flags ) {
|
||||
dest.writeInt( getNextIconType() );
|
||||
dest.writeInt( getNextDistance() );
|
||||
dest.writeString( getNextRoad() );
|
||||
dest.writeInt( getSurplusDistance() );
|
||||
dest.writeInt( getSurplusTime() );
|
||||
dest.writeInt( getCurrentSpeed() );
|
||||
}
|
||||
|
||||
protected NaviInfoWrapper( Parcel in ) {
|
||||
this.nextIconType = in.readInt();
|
||||
this.nextDistance = in.readInt();
|
||||
this.nextRoad = in.readString();
|
||||
this.surplusDistance = in.readInt();
|
||||
this.surplusTime = in.readInt();
|
||||
this.currentSpeed = in.readInt();
|
||||
}
|
||||
|
||||
public static final Creator< NaviInfoWrapper > CREATOR = new Parcelable.Creator< NaviInfoWrapper >() {
|
||||
@Override
|
||||
public NaviInfoWrapper createFromParcel( Parcel source ) {
|
||||
return new NaviInfoWrapper( source );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NaviInfoWrapper[] newArray( int size ) {
|
||||
return new NaviInfoWrapper[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
137
modules/mogo-module-navi/src/main/res/layout/fragment_search.xml
Normal file
137
modules/mogo-module-navi/src/main/res/layout/fragment_search.xml
Normal file
@@ -0,0 +1,137 @@
|
||||
<?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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/amap_fragment_container_padding_style"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.search.SearchFragment">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/amap_search_search_box_width_container"
|
||||
android:layout_width="692dp"
|
||||
android:layout_height="81dp"
|
||||
android:background="@drawable/amap_white_shadow_bkg">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/amap_search_close"
|
||||
android:layout_width="@dimen/amap_search_back_size"
|
||||
android:layout_height="@dimen/amap_search_back_size"
|
||||
android:layout_alignTop="@+id/amap_search_search_box"
|
||||
android:layout_alignBottom="@+id/amap_search_search_box"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_back_dark" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/amap_search_search_box"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="58dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_toRightOf="@+id/amap_search_close"
|
||||
android:background="@color/transparent"
|
||||
android:drawableRight="@drawable/ic_search_unshadow"
|
||||
android:drawablePadding="15dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="@string/navi_search_hint"
|
||||
android:maxLines="1"
|
||||
android:paddingTop="@dimen/amap_search_search_box_paddingLTop"
|
||||
android:paddingBottom="@dimen/amap_search_search_box_paddingBottom"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/black"
|
||||
android:textColorHint="#848484"
|
||||
android:textCursorDrawable="@drawable/amap_search_cursor_drawable"
|
||||
android:textSize="@dimen/amap_search_search_box_textSize"
|
||||
tools:text="@string/amap_long_text" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/amap_search_action_setting"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/amap_search_search_box"
|
||||
android:layout_alignBottom="@+id/amap_search_search_box"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginTop="8.5dp"
|
||||
android:layout_marginRight="7.5dp"
|
||||
android:layout_marginBottom="8.5dp"
|
||||
android:background="@drawable/amap_search_action_button_bkg"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="25dp"
|
||||
android:paddingRight="25dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20dp"
|
||||
android:visibility="gone"
|
||||
tools:text="设为家"
|
||||
tools:visibility="visible" />
|
||||
</RelativeLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/amap_search_current_location_tag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/amap_search_search_box_width_container"
|
||||
android:layout_alignLeft="@+id/amap_search_search_box_width_container"
|
||||
android:layout_marginBottom="@dimen/amap_main_navi_current_location_marginBottom"
|
||||
android:src="@drawable/ic_current_location"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_goneMarginBottom="@dimen/amap_main_navi_current_location_goneMarginBottom" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/amap_search_poi_my_location"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/amap_search_current_location_tag"
|
||||
android:layout_alignBottom="@+id/amap_search_current_location_tag"
|
||||
android:background="@drawable/amap_white_shadow_bkg"
|
||||
android:drawableLeft="@drawable/ic_search_poi_location"
|
||||
android:drawablePadding="15.5dp"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="23.5dp"
|
||||
android:paddingRight="27.5dp"
|
||||
android:text="我的位置"
|
||||
android:textColor="#595959"
|
||||
android:textSize="20dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/amap_search_poi_choice_point"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/amap_search_current_location_tag"
|
||||
android:layout_alignBottom="@+id/amap_search_current_location_tag"
|
||||
android:layout_toRightOf="@+id/amap_search_poi_my_location"
|
||||
android:background="@drawable/amap_white_shadow_bkg"
|
||||
android:drawableLeft="@drawable/ic_search_poi_location"
|
||||
android:drawablePadding="15.5dp"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="23.5dp"
|
||||
android:paddingRight="27.5dp"
|
||||
android:text="地图选点"
|
||||
android:textColor="#595959"
|
||||
android:textSize="20dp" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/amap_search_current_location"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginBottom="@dimen/amap_main_navi_current_location_marginBottom"
|
||||
android:src="@drawable/ic_current_location" />
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/amap_search_poi_result"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/amap_search_search_box_width_container"
|
||||
android:layout_alignRight="@+id/amap_search_search_box_width_container"
|
||||
android:layout_marginBottom="@dimen/amap_main_navi_current_location_marginBottom"
|
||||
android:background="@drawable/amap_white_shadow_bkg"
|
||||
android:overScrollMode="never"
|
||||
android:visibility="invisible" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.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="130dp">
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginLeft="130dp"
|
||||
android:layout_marginRight="60dp"
|
||||
|
||||
android:background="#802D3256"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_position"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginLeft="130dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_position"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="28dp"
|
||||
android:layout_marginRight="60dp"
|
||||
android:textColor="@color/white"
|
||||
|
||||
android:textSize="30sp"
|
||||
app:layout_constraintLeft_toRightOf="@id/iv_position"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_position_des"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginRight="60dp"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/white_7f"
|
||||
android:textSize="22sp"
|
||||
app:layout_constraintLeft_toRightOf="@id/iv_position"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_position" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
15
modules/mogo-module-navi/src/main/res/values/colors.xml
Normal file
15
modules/mogo-module-navi/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#008577</color>
|
||||
<color name="colorPrimaryDark">#00574B</color>
|
||||
<color name="colorAccent">#D81B60</color>
|
||||
<color name="bg_gray_common_page">#ff080625</color>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="white_7f">#7FFFFFFF</color>
|
||||
<color name="arrow_color">#00BFFF</color>
|
||||
<color name="white_30">#4DFFFFFF</color>
|
||||
<color name="txt_gray_day">#4D080625</color>
|
||||
|
||||
<color name="bg_common">#080625</color>
|
||||
|
||||
</resources>
|
||||
4
modules/mogo-module-navi/src/main/res/values/ids.xml
Normal file
4
modules/mogo-module-navi/src/main/res/values/ids.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<item name="tag_position" type="id"/>
|
||||
</resources>
|
||||
19
modules/mogo-module-navi/src/main/res/values/styles.xml
Normal file
19
modules/mogo-module-navi/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<resources>
|
||||
|
||||
<style name="amap_fragment_container_padding_style">
|
||||
<item name="android:paddingTop">25dp</item>
|
||||
<item name="android:paddingLeft">48dp</item>
|
||||
</style>
|
||||
|
||||
<style name="amap_fragment_container_margin_style">
|
||||
<item name="android:layout_marginTop">25dp</item>
|
||||
<item name="android:layout_marginLeft">48dp</item>
|
||||
<item name="android:background">@drawable/amap_white_shadow_bkg</item>
|
||||
</style>
|
||||
|
||||
<style name="amap_fragment_container_shadow_style">
|
||||
<item name="android:paddingTop">25dp</item>
|
||||
<item name="android:paddingLeft">48dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
Reference in New Issue
Block a user