From c3df548d0462ae4e73e7e8f7fa5db3407fd4bf3e Mon Sep 17 00:00:00 2001 From: zhangyuanzhen Date: Thu, 2 Jan 2020 16:56:16 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=BC=E8=88=AA?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mogo/utils/NetworkUtils.java | 110 ++++ .../com/mogo/utils/OnItemClickedListener.java | 12 + .../java/com/mogo/utils/statusbar/Eyes.java | 177 ++++++ .../com/mogo/utils/statusbar/EyesKitKat.java | 277 +++++++++ .../mogo/utils/statusbar/EyesLollipop.java | 219 +++++++ libraries/map-amap/build.gradle | 6 +- modules/mogo-module-map/build.gradle | 12 +- modules/mogo-module-navi/build.gradle | 9 +- .../navi/{database => }/bean/POIInfo.java | 2 +- .../module/navi/constants/DataConstants.java | 45 ++ .../navi/{database => }/dao/POIDao.java | 4 +- .../lib/AMapNaviStatusChangedListener.java | 19 + .../AMapNaviStatusChangedListenerDefault.java | 281 +++++++++ .../navi/ui/adapter/SearchPoiAdapter.java | 40 ++ .../ui/adapter/base/RecycleBaseAdapter.java | 112 ++++ .../ui/adapter/base/RecycleViewHolder.java | 138 +++++ .../module/navi/ui/base/AMapBaseFragment.java | 50 ++ .../navi/ui/base/AMapServiceVisitor.java | 48 ++ .../module/navi/ui/base/BaseActivity.java | 65 ++ .../module/navi/ui/base/BaseFragment.java | 73 +++ .../module/navi/ui/base/UiController.java | 53 ++ .../navi/ui/search/SearchConstants.java | 54 ++ .../module/navi/ui/search/SearchFragment.java | 566 ++++++++++++++++++ .../navi/ui/search/SearchPresenter.java | 289 +++++++++ .../module/navi/ui/search/SearchUtils.java | 39 ++ .../module/navi/ui/search/SearchView.java | 46 ++ .../wrapper/AMapCalcRouteResultWrapper.java | 83 +++ .../wrapper/AMapNaviCameraInfoWrapper.java | 99 +++ .../navi/wrapper/AMapNaviLocationWrapper.java | 148 +++++ .../module/navi/wrapper/LatLngWrapper.java | 104 ++++ .../module/navi/wrapper/NaviInfoWrapper.java | 116 ++++ .../src/main/res/layout/item_search_poi.xml | 58 ++ .../src/main/res/values/colors.xml | 15 + .../src/main/res/values/ids.xml | 4 + 34 files changed, 3360 insertions(+), 13 deletions(-) create mode 100644 foudations/mogo-utils/src/main/java/com/mogo/utils/NetworkUtils.java create mode 100644 foudations/mogo-utils/src/main/java/com/mogo/utils/OnItemClickedListener.java create mode 100644 foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/Eyes.java create mode 100644 foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesKitKat.java create mode 100644 foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesLollipop.java rename modules/mogo-module-navi/src/main/java/com/mogo/module/navi/{database => }/bean/POIInfo.java (96%) create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/DataConstants.java rename modules/mogo-module-navi/src/main/java/com/mogo/module/navi/{database => }/dao/POIDao.java (85%) create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/lib/AMapNaviStatusChangedListener.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/lib/AMapNaviStatusChangedListenerDefault.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/SearchPoiAdapter.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/base/RecycleBaseAdapter.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/base/RecycleViewHolder.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/AMapBaseFragment.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/AMapServiceVisitor.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/BaseActivity.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/BaseFragment.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/UiController.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchConstants.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchFragment.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchPresenter.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchUtils.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchView.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapCalcRouteResultWrapper.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapNaviCameraInfoWrapper.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapNaviLocationWrapper.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/LatLngWrapper.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/NaviInfoWrapper.java create mode 100644 modules/mogo-module-navi/src/main/res/layout/item_search_poi.xml create mode 100644 modules/mogo-module-navi/src/main/res/values/colors.xml create mode 100644 modules/mogo-module-navi/src/main/res/values/ids.xml diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/NetworkUtils.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/NetworkUtils.java new file mode 100644 index 0000000000..4481f10508 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/NetworkUtils.java @@ -0,0 +1,110 @@ +package com.mogo.utils; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import androidx.annotation.Nullable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NetworkUtils { + private static final String TAG = NetworkUtils.class.getSimpleName(); + + /** + * Returns true if device is connected to wifi or mobile network, false + * otherwise. + * + * @param context + * @return + */ + public static boolean isConnected( Context context ) { + + if ( context == null ) { + return false; + } + + ConnectivityManager conMan = (ConnectivityManager) context + .getSystemService( Context.CONNECTIVITY_SERVICE ); + + if ( conMan == null ) { + return false; + } + + NetworkInfo infoWifi = conMan.getNetworkInfo( ConnectivityManager.TYPE_WIFI ); + if ( infoWifi != null ) { + NetworkInfo.State wifi = infoWifi.getState(); + if ( wifi == NetworkInfo.State.CONNECTED ) { + return true; + } + } + + NetworkInfo infoMobile = conMan.getNetworkInfo( ConnectivityManager.TYPE_MOBILE ); + if ( infoMobile != null ) { + NetworkInfo.State mobile = infoMobile.getState(); + if ( mobile == NetworkInfo.State.CONNECTED ) { + return true; + } + } + return false; + } + + /** + * Check if there is any connectivity to a Wifi network + * + * @param context + * @return + */ + public static boolean isConnectedWifi( Context context ) { + if ( context == null ) { + return false; + } + NetworkInfo info = getNetworkInfo( context ); + return ( info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI ); + } + + /** + * Check if there is any connectivity to a mobile network + * + * @param context + * @return + */ + public static boolean isConnectedMobile( Context context ) { + if ( context == null ) { + return false; + } + NetworkInfo info = getNetworkInfo( context ); + return ( info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE ); + } + + /** + * Get the network info + * + * @param context + * @return + */ + @Nullable + public static NetworkInfo getNetworkInfo( Context context ) { + if ( context == null ) { + return null; + } + ConnectivityManager cm = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE ); + if ( cm != null ) { + return cm.getActiveNetworkInfo(); + } + return null; + } + + /** + * URL + * + * @param url + * @return true ,false + */ + public static boolean isNetworkUrl( String url ) { + String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; + Pattern patt = Pattern.compile( regex ); + Matcher matcher = patt.matcher( url ); + return matcher.matches(); + } + +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/OnItemClickedListener.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/OnItemClickedListener.java new file mode 100644 index 0000000000..fa7065448e --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/OnItemClickedListener.java @@ -0,0 +1,12 @@ +package com.mogo.utils; + +/** + * @author congtaowang + * @since 2019-10-02 + *

+ * recyclerview item 点击回调 + */ +public interface OnItemClickedListener< T > { + + void onItemClicked(T obj); +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/Eyes.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/Eyes.java new file mode 100644 index 0000000000..b0eecffd79 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/Eyes.java @@ -0,0 +1,177 @@ +package com.mogo.utils.statusbar; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Color; +import android.os.Build; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import androidx.core.view.ViewCompat; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class Eyes { + + + public static void setStatusBarColor( Activity activity, int statusColor ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + EyesLollipop.setStatusBarColor( activity, statusColor ); + } else if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ) { + EyesKitKat.setStatusBarColor( activity, statusColor ); + } + } + + public static void translucentStatusBar( Activity activity ) { + translucentStatusBar( activity, false ); + } + + public static void translucentStatusBar( Activity activity, boolean hideStatusBarBackground ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + EyesLollipop.translucentStatusBar( activity, hideStatusBarBackground ); + } else if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ) { + EyesKitKat.translucentStatusBar( activity ); + } + } +// +// public static void setStatusBarColorForCollapsingToolbar(@NonNull Activity activity, AppBarLayout appBarLayout, CollapsingToolbarLayout collapsingToolbarLayout, +// Toolbar toolbar, @ColorInt int statusColor) { +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { +// EyesLollipop.setStatusBarColorForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusColor); +// } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { +// EyesKitKat.setStatusBarColorForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusColor); +// } +// } + + public static void setStatusBarLightMode( Activity activity, int color ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ) { + //判断是否为小米或魅族手机,如果是则将状态栏文字改为黑色 + if ( MIUISetStatusBarLightMode( activity, true ) || FlymeSetStatusBarLightMode( activity, true ) ) { + //设置状态栏为指定颜色 + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) {//5.0 + activity.getWindow().setStatusBarColor( color ); + } else {//4.4 + //调用修改状态栏颜色的方法 + setStatusBarColor( activity, color ); + } + } else if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) { + //如果是6.0以上将状态栏文字改为黑色,并设置状态栏颜色 + activity.getWindow().setBackgroundDrawableResource( android.R.color.transparent ); + activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ); + activity.getWindow().setStatusBarColor( color ); + + //fitsSystemWindow 为 false, 不预留系统栏位置. + ViewGroup mContentView = activity.getWindow().findViewById( Window.ID_ANDROID_CONTENT ); + View mChildView = mContentView.getChildAt( 0 ); + if ( mChildView != null ) { + mChildView.setFitsSystemWindows( true ); + ViewCompat.requestApplyInsets( mChildView ); + } + } + } + } + +// +// public static void setStatusBarLightForCollapsingToolbar(Activity activity, AppBarLayout appBarLayout, +// CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, int statusBarColor) { +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { +// EyesLollipop.setStatusBarWhiteForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusBarColor); +// } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { +// EyesKitKat.setStatusBarWhiteForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusBarColor); +// } +// } + + + /** + * MIUI的沉浸支持透明白色字体和透明黑色字体 + * https://dev.mi.com/console/doc/detail?pId=1159 + */ + static boolean MIUISetStatusBarLightMode( Activity activity, boolean darkmode ) { + try { + Class< ? > layoutParams = Class.forName( "android.view.MiuiWindowManager$LayoutParams" ); + + Window window = activity.getWindow(); + window.addFlags( WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS ); + window.clearFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); + window.getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ); + + Class< ? extends Window> clazz = activity.getWindow().getClass(); + Field field = layoutParams.getField( "EXTRA_FLAG_STATUS_BAR_DARK_MODE" ); + int darkModeFlag = field.getInt( layoutParams ); + Method extraFlagField = clazz.getMethod( "setExtraFlags", int.class, int.class ); + extraFlagField.invoke( activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag ); + return true; + } catch ( Exception e ) { + } + return false; + } + + /** + * 设置状态栏图标为深色和魅族特定的文字风格,Flyme4.0以上 + */ + static boolean FlymeSetStatusBarLightMode( Activity activity, boolean darkmode ) { + try { + WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); + Field darkFlag = WindowManager.LayoutParams.class + .getDeclaredField( "MEIZU_FLAG_DARK_STATUS_BAR_ICON" ); + Field meizuFlags = WindowManager.LayoutParams.class + .getDeclaredField( "meizuFlags" ); + darkFlag.setAccessible( true ); + meizuFlags.setAccessible( true ); + int bit = darkFlag.getInt( null ); + int value = meizuFlags.getInt( lp ); + if ( darkmode ) { + value |= bit; + } else { + value &= ~bit; + } + meizuFlags.setInt( lp, value ); + activity.getWindow().setAttributes( lp ); + return true; + } catch ( Exception e ) { + } + return false; + } + + static void setContentTopPadding( Activity activity, int padding ) { + ViewGroup mContentView = activity.getWindow().findViewById( Window.ID_ANDROID_CONTENT ); + mContentView.setPadding( 0, padding, 0, 0 ); + } + + static int getPxFromDp( Context context, float dp ) { + return ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics() ); + } + + /** + * 设置状态栏颜色 + * + * @param activity + * @param isBlackText true黑色 false 白字 + */ + public static void setStatusBarStyle( Activity activity, boolean isBlackText, boolean isFitSystem ) { + setStatusBarStyle( activity, isBlackText, isBlackText ? Color.WHITE : Color.TRANSPARENT, isFitSystem ); + } + + public static void setStatusBarStyle( Activity activity, boolean isBlackText, int statusBarBgColor, boolean isFitSystem ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + activity.getWindow().setBackgroundDrawableResource( android.R.color.transparent ); + if ( isBlackText ) { + activity.getWindow().getDecorView().setSystemUiVisibility( ( isFitSystem ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : View.SYSTEM_UI_FLAG_VISIBLE ) | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ); + } else { + activity.getWindow().getDecorView().setSystemUiVisibility( ( isFitSystem ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : View.SYSTEM_UI_FLAG_VISIBLE ) ); + } + activity.getWindow().setStatusBarColor( statusBarBgColor ); + } + } + + + public static void setMessageFragmentStatus( Activity activity ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + activity.getWindow().setBackgroundDrawableResource( android.R.color.transparent ); + activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ); + } + } + +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesKitKat.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesKitKat.java new file mode 100644 index 0000000000..c922602529 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesKitKat.java @@ -0,0 +1,277 @@ +package com.mogo.utils.statusbar; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.os.Build; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.FrameLayout; +import com.mogo.utils.R; + +@TargetApi( Build.VERSION_CODES.KITKAT ) +class EyesKitKat { + private static final String TAG_FAKE_STATUS_BAR_VIEW = "statusBarView"; + private static final String TAG_MARGIN_ADDED = "marginAdded"; + + static void setStatusBarColor( Activity activity, int statusColor ) { + Window window = activity.getWindow(); + //设置Window为全透明 + window.addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); + + ViewGroup mContentView = window.findViewById( Window.ID_ANDROID_CONTENT ); + //获取父布局 + View mContentChild = mContentView.getChildAt( 0 ); + //获取状态栏高度 + int statusBarHeight = getStatusBarHeight( activity ); + + //如果已经存在假状态栏则移除,防止重复添加 + removeFakeStatusBarViewIfExist( activity ); + //添加一个View来作为状态栏的填充 + addFakeStatusBarView( activity, statusColor, statusBarHeight ); + //设置子控件到状态栏的间距 + addMarginTopToContentChild( mContentChild, statusBarHeight ); + //不预留系统栏位置 + if ( mContentChild != null ) { + mContentChild.setFitsSystemWindows( false ); + } + //如果在Activity中使用了ActionBar则需要再将布局与状态栏的高度跳高一个ActionBar的高度,否则内容会被ActionBar遮挡 + int action_bar_id = activity.getResources().getIdentifier( "action_bar", "id", activity.getPackageName() ); + View view = activity.findViewById( action_bar_id ); + if ( view != null ) { + TypedValue typedValue = new TypedValue(); + if ( activity.getTheme().resolveAttribute( R.attr.actionBarSize, typedValue, true ) ) { + int actionBarHeight = TypedValue.complexToDimensionPixelSize( typedValue.data, activity.getResources().getDisplayMetrics() ); + Eyes.setContentTopPadding( activity, actionBarHeight ); + } + } + } + + static void translucentStatusBar( Activity activity ) { + Window window = activity.getWindow(); + //设置Window为透明 + window.addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); + + ViewGroup mContentView = activity.findViewById( Window.ID_ANDROID_CONTENT ); + View mContentChild = mContentView.getChildAt( 0 ); + + //移除已经存在假状态栏则,并且取消它的Margin间距 + removeFakeStatusBarViewIfExist( activity ); + removeMarginTopOfContentChild( mContentChild, getStatusBarHeight( activity ) ); + if ( mContentChild != null ) { + //fitsSystemWindow 为 false, 不预留系统栏位置. + mContentChild.setFitsSystemWindows( false ); + } + } + +// static void setStatusBarColorForCollapsingToolbar( final Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, +// Toolbar toolbar, int statusColor ) { +// Window window = activity.getWindow(); +// //设置Window为全透明 +// window.addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); +// ViewGroup mContentView = window.findViewById( Window.ID_ANDROID_CONTENT ); +// +// //AppBarLayout,CollapsingToolbarLayout,ToolBar,ImageView的fitsSystemWindow统一改为false, 不预留系统栏位置. +// View mContentChild = mContentView.getChildAt( 0 ); +// mContentChild.setFitsSystemWindows( false ); +// ( ( View ) appBarLayout.getParent() ).setFitsSystemWindows( false ); +// appBarLayout.setFitsSystemWindows( false ); +// collapsingToolbarLayout.setFitsSystemWindows( false ); +// collapsingToolbarLayout.getChildAt( 0 ).setFitsSystemWindows( false ); +// +// toolbar.setFitsSystemWindows( false ); +// //为Toolbar添加一个状态栏的高度, 同时为Toolbar添加paddingTop,使Toolbar覆盖状态栏,ToolBar的title可以正常显示. +// if ( toolbar.getTag() == null ) { +// CollapsingToolbarLayout.LayoutParams lp = ( CollapsingToolbarLayout.LayoutParams ) toolbar.getLayoutParams(); +// int statusBarHeight = getStatusBarHeight( activity ); +// lp.height += statusBarHeight; +// toolbar.setLayoutParams( lp ); +// toolbar.setPadding( toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom() ); +// toolbar.setTag( true ); +// } +// //移除已经存在假状态栏则,并且取消它的Margin间距 +// int statusBarHeight = getStatusBarHeight( activity ); +// removeFakeStatusBarViewIfExist( activity ); +// removeMarginTopOfContentChild( mContentChild, statusBarHeight ); +// //添加一个View来作为状态栏的填充 +// final View statusView = addFakeStatusBarView( activity, statusColor, statusBarHeight ); +// +// CoordinatorLayout.Behavior behavior = ( ( CoordinatorLayout.LayoutParams ) appBarLayout.getLayoutParams() ).getBehavior(); +// if ( behavior != null && behavior instanceof AppBarLayout.Behavior ) { +// int verticalOffset = ( ( AppBarLayout.Behavior ) behavior ).getTopAndBottomOffset(); +// if ( Math.abs( verticalOffset ) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger() ) { +// statusView.setAlpha( 1f ); +// } else { +// statusView.setAlpha( 0f ); +// } +// } else { +// statusView.setAlpha( 0f ); +// } +// appBarLayout.addOnOffsetChangedListener( new AppBarLayout.OnOffsetChangedListener() { +// @Override +// public void onOffsetChanged( AppBarLayout appBarLayout, int verticalOffset ) { +// if ( Math.abs( verticalOffset ) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger() ) { +// //toolbar被折叠时显示状态栏 +// if ( statusView.getAlpha() == 0 ) { +// statusView.animate().cancel(); +// statusView.animate().alpha( 1f ).setDuration( collapsingToolbarLayout.getScrimAnimationDuration() ).start(); +// } +// } else { +// //toolbar展开时显示状态栏 +// if ( statusView.getAlpha() == 1 ) { +// statusView.animate().cancel(); +// statusView.animate().alpha( 0f ).setDuration( collapsingToolbarLayout.getScrimAnimationDuration() ).start(); +// } +// } +// } +// } ); +// } +// +// static void setStatusBarWhiteForCollapsingToolbar( final Activity activity, AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, final int statusBarColor ) { +// final Window window = activity.getWindow(); +// window.addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); +// +// ViewGroup mContentView = window.findViewById( Window.ID_ANDROID_CONTENT ); +// View mContentChild = mContentView.getChildAt( 0 ); +// mContentChild.setFitsSystemWindows( false ); +// ( ( View ) appBarLayout.getParent() ).setFitsSystemWindows( false ); +// appBarLayout.setFitsSystemWindows( false ); +// collapsingToolbarLayout.setFitsSystemWindows( false ); +// collapsingToolbarLayout.getChildAt( 0 ).setFitsSystemWindows( false ); +// toolbar.setFitsSystemWindows( false ); +// +// if ( toolbar.getTag() == null ) { +// CollapsingToolbarLayout.LayoutParams lp = ( CollapsingToolbarLayout.LayoutParams ) toolbar.getLayoutParams(); +// int statusBarHeight = getStatusBarHeight( activity ); +// lp.height += statusBarHeight; +// toolbar.setLayoutParams( lp ); +// toolbar.setPadding( toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom() ); +// toolbar.setTag( true ); +// } +// +// int statusBarHeight = getStatusBarHeight( activity ); +// int color = Color.BLACK; +// try { +// Class< ? > layoutParams = Class.forName( "android.view.MiuiWindowManager$LayoutParams" ); +// color = statusBarColor; +// } catch ( ClassNotFoundException e ) { +// e.printStackTrace(); +// } +// try { +// Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField( "MEIZU_FLAG_DARK_STATUS_BAR_ICON" ); +// color = statusBarColor; +// } catch ( NoSuchFieldException e ) { +// e.printStackTrace(); +// } +// final View statusView = addFakeStatusBarView( activity, color, statusBarHeight ); +// CoordinatorLayout.Behavior behavior = ( ( CoordinatorLayout.LayoutParams ) appBarLayout.getLayoutParams() ).getBehavior(); +// if ( behavior != null && behavior instanceof AppBarLayout.Behavior ) { +// int verticalOffset = ( ( AppBarLayout.Behavior ) behavior ).getTopAndBottomOffset(); +// if ( Math.abs( verticalOffset ) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger() ) { +// statusView.setAlpha( 1f ); +// } else { +// statusView.setAlpha( 0f ); +// } +// } else { +// statusView.setAlpha( 0f ); +// } +// +// appBarLayout.addOnOffsetChangedListener( new AppBarLayout.OnOffsetChangedListener() { +// private final static int EXPANDED = 0; +// private final static int COLLAPSED = 1; +// private int appBarLayoutState; +// +// @Override +// public void onOffsetChanged( AppBarLayout appBarLayout, int verticalOffset ) { +// if ( Math.abs( verticalOffset ) >= ( appBarLayout.getTotalScrollRange() - Eyes.getPxFromDp( activity, 56 ) ) ) { +// if ( appBarLayoutState != COLLAPSED ) { +// appBarLayoutState = COLLAPSED; +// +// if ( Eyes.MIUISetStatusBarLightMode( activity, true ) || Eyes.FlymeSetStatusBarLightMode( activity, true ) ) { +// } +// if ( statusView.getAlpha() == 0 ) { +// statusView.animate().cancel(); +// statusView.animate().alpha( 1f ).setDuration( collapsingToolbarLayout.getScrimAnimationDuration() ).start(); +// } +// } +// } else { +// if ( appBarLayoutState != EXPANDED ) { +// appBarLayoutState = EXPANDED; +// +// if ( Eyes.MIUISetStatusBarLightMode( activity, false ) || Eyes.FlymeSetStatusBarLightMode( activity, false ) ) { +// } +// if ( statusView.getAlpha() == 1 ) { +// statusView.animate().cancel(); +// statusView.animate().alpha( 0f ).setDuration( collapsingToolbarLayout.getScrimAnimationDuration() ).start(); +// } +// translucentStatusBar( activity ); +// } +// } +// } +// } ); +// } + + private static void removeFakeStatusBarViewIfExist( Activity activity ) { + Window window = activity.getWindow(); + ViewGroup mDecorView = (ViewGroup) window.getDecorView(); + + View fakeView = mDecorView.findViewWithTag( TAG_FAKE_STATUS_BAR_VIEW ); + if ( fakeView != null ) { + mDecorView.removeView( fakeView ); + } + } + + private static View addFakeStatusBarView( Activity activity, int statusBarColor, int statusBarHeight ) { + Window window = activity.getWindow(); + ViewGroup mDecorView = (ViewGroup) window.getDecorView(); + + View mStatusBarView = new View( activity ); + FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight ); + layoutParams.gravity = Gravity.TOP; + mStatusBarView.setLayoutParams( layoutParams ); + mStatusBarView.setBackgroundColor( statusBarColor ); + mStatusBarView.setTag( TAG_FAKE_STATUS_BAR_VIEW ); + + mDecorView.addView( mStatusBarView ); + return mStatusBarView; + } + + private static void addMarginTopToContentChild( View mContentChild, int statusBarHeight ) { + if ( mContentChild == null ) { + return; + } + if ( !TAG_MARGIN_ADDED.equals( mContentChild.getTag() ) ) { + FrameLayout.LayoutParams lp = ( FrameLayout.LayoutParams ) mContentChild.getLayoutParams(); + lp.topMargin += statusBarHeight; + mContentChild.setLayoutParams( lp ); + mContentChild.setTag( TAG_MARGIN_ADDED ); + } + } + + private static int getStatusBarHeight( Context context ) { + int result = 0; + int resId = context.getResources().getIdentifier( "status_bar_height", "dimen", "android" ); + if ( resId > 0 ) { + result = context.getResources().getDimensionPixelOffset( resId ); + } + return result; + } + + private static void removeMarginTopOfContentChild( View mContentChild, int statusBarHeight ) { + if ( mContentChild == null ) { + return; + } + if ( TAG_MARGIN_ADDED.equals( mContentChild.getTag() ) ) { + FrameLayout.LayoutParams lp = ( FrameLayout.LayoutParams ) mContentChild.getLayoutParams(); + lp.topMargin -= statusBarHeight; + mContentChild.setLayoutParams( lp ); + mContentChild.setTag( null ); + } + } + + +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesLollipop.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesLollipop.java new file mode 100644 index 0000000000..f7426867ca --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesLollipop.java @@ -0,0 +1,219 @@ +package com.mogo.utils.statusbar; + + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.graphics.Color; +import android.os.Build; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import androidx.core.view.ViewCompat; + +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +class EyesLollipop { + + static void setStatusBarColor(Activity activity, int statusColor) { + Window window = activity.getWindow(); + //取消状态栏透明 + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + //添加Flag把状态栏设为可绘制模式 + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + //设置状态栏颜色 + window.setStatusBarColor(statusColor); + //设置系统状态栏处于可见状态 + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + //让view不根据系统窗口来调整自己的布局 + ViewGroup mContentView = window.findViewById(Window.ID_ANDROID_CONTENT); + View mChildView = mContentView.getChildAt(0); + if (mChildView != null) { + mChildView.setFitsSystemWindows(false); + ViewCompat.requestApplyInsets(mChildView); + } + } + + static void translucentStatusBar(Activity activity, boolean hideStatusBarBackground) { + Window window = activity.getWindow(); + //添加Flag把状态栏设为可绘制模式 + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + if (hideStatusBarBackground) { + //如果为全透明模式,取消设置Window半透明的Flag + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + //设置状态栏为透明 + window.setStatusBarColor(Color.TRANSPARENT); + //设置window的状态栏不可见 + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } else { + //如果为半透明模式,添加设置Window半透明的Flag + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + //设置系统状态栏处于可见状态 + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + } + //view不根据系统窗口来调整自己的布局 + ViewGroup mContentView = window.findViewById(Window.ID_ANDROID_CONTENT); + View mChildView = mContentView.getChildAt(0); + if (mChildView != null) { + mChildView.setFitsSystemWindows(false); + ViewCompat.requestApplyInsets(mChildView); + } + } + +// static void setStatusBarColorForCollapsingToolbar(final Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, +// Toolbar toolbar, final int statusColor) { +// final Window window = activity.getWindow(); +// //取消设置Window半透明的Flag +// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); +// ////添加Flag把状态栏设为可绘制模式 +// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); +// //设置状态栏为透明 +// window.setStatusBarColor(Color.TRANSPARENT); +// //设置系统状态栏处于可见状态 +// window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); +// //通过OnApplyWindowInsetsListener()使Layout在绘制过程中将View向下偏移了,使collapsingToolbarLayout可以占据状态栏 +// ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, new OnApplyWindowInsetsListener() { +// @Override +// public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { +// return insets; +// } +// }); +// +// ViewGroup mContentView = window.findViewById(Window.ID_ANDROID_CONTENT); +// View mChildView = mContentView.getChildAt(0); +// //view不根据系统窗口来调整自己的布局 +// if (mChildView != null) { +// mChildView.setFitsSystemWindows(false); +// ViewCompat.requestApplyInsets(mChildView); +// } +// +// ((View) appBarLayout.getParent()).setFitsSystemWindows(false); +// appBarLayout.setFitsSystemWindows(false); +// collapsingToolbarLayout.setFitsSystemWindows(false); +// collapsingToolbarLayout.getChildAt(0).setFitsSystemWindows(false); +// //设置状态栏的颜色 +// collapsingToolbarLayout.setStatusBarScrimColor(statusColor); +// toolbar.setFitsSystemWindows(false); +// //为Toolbar添加一个状态栏的高度, 同时为Toolbar添加paddingTop,使Toolbar覆盖状态栏,ToolBar的title可以正常显示. +// if (toolbar.getTag() == null) { +// CollapsingToolbarLayout.LayoutParams lp = (CollapsingToolbarLayout.LayoutParams) toolbar.getLayoutParams(); +// int statusBarHeight = getStatusBarHeight(activity); +// lp.height += statusBarHeight; +// toolbar.setLayoutParams(lp); +// toolbar.setPadding(toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom()); +// toolbar.setTag(true); +// } +// +// appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { +// private final static int EXPANDED = 0; +// private final static int COLLAPSED = 1; +// private int appBarLayoutState; +// +// @Override +// public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { +// //toolbar被折叠时显示状态栏 +// if (Math.abs(verticalOffset) > collapsingToolbarLayout.getScrimVisibleHeightTrigger()) { +// if (appBarLayoutState != COLLAPSED) { +// appBarLayoutState = COLLAPSED;//修改状态标记为折叠 +// setStatusBarColor(activity, statusColor); +// } +// } else { +// //toolbar显示时同时显示状态栏 +// if (appBarLayoutState != EXPANDED) { +// appBarLayoutState = EXPANDED;//修改状态标记为展开 +// translucentStatusBar(activity, true); +// } +// } +// } +// }); +// } +// +// static void setStatusBarWhiteForCollapsingToolbar(final Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, final Toolbar toolbar, final int statusBarColor) { +// final Window window = activity.getWindow(); +// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); +// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); +// window.setStatusBarColor(Color.TRANSPARENT); +// window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); +// +// ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, new OnApplyWindowInsetsListener() { +// @Override +// public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { +// return insets; +// } +// }); +// +// ViewGroup mContentView = window.findViewById(Window.ID_ANDROID_CONTENT); +// View mChildView = mContentView.getChildAt(0); +// if (mChildView != null) { +// mChildView.setFitsSystemWindows(false); +// ViewCompat.requestApplyInsets(mChildView); +// } +// +// ((View) appBarLayout.getParent()).setFitsSystemWindows(false); +// appBarLayout.setFitsSystemWindows(false); +// toolbar.setFitsSystemWindows(false); +// if (toolbar.getTag() == null) { +// CollapsingToolbarLayout.LayoutParams lp = (CollapsingToolbarLayout.LayoutParams) toolbar.getLayoutParams(); +// int statusBarHeight = getStatusBarHeight(activity); +// lp.height += statusBarHeight; +// toolbar.setLayoutParams(lp); +// toolbar.setPadding(toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom()); +// toolbar.setTag(true); +// } +// +// collapsingToolbarLayout.setFitsSystemWindows(false); +// collapsingToolbarLayout.getChildAt(0).setFitsSystemWindows(false); +// collapsingToolbarLayout.setStatusBarScrimColor(statusBarColor); +// appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { +// private final static int EXPANDED = 0; +// private final static int COLLAPSED = 1; +// private int appBarLayoutState; +// +// @Override +// public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { +// //toolbar被折叠时显示状态栏 +// if (Math.abs(verticalOffset) > collapsingToolbarLayout.getScrimVisibleHeightTrigger()) { +// if (appBarLayoutState != COLLAPSED) { +// appBarLayoutState = COLLAPSED;//修改状态标记为折叠 +// +// //先判断是否为小米设备,设置状态栏不成功判断是否为6.0以上设备,不是6.0以上设备再判断是否为魅族设备,不是魅族设备就只设置状态栏颜色 +// if (Eyes.MIUISetStatusBarLightMode(activity, true)) { +// return; +// } +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +// activity.getWindow().setBackgroundDrawableResource(android.R.color.transparent); +// activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); +// activity.getWindow().setStatusBarColor(statusBarColor); +// } else if (!Eyes.FlymeSetStatusBarLightMode(activity, true)) { +// setStatusBarColor(activity, statusBarColor); +// } +// } +// } else { +// //toolbar显示时同时显示状态栏 +// if (appBarLayoutState != EXPANDED) { +// appBarLayoutState = EXPANDED;//修改状态标记为展开 +// +// if (Eyes.MIUISetStatusBarLightMode(activity, false)) { +// translucentStatusBar(activity, true); +// return; +// } +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +// activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); +// } else if (Eyes.FlymeSetStatusBarLightMode(activity, true)) { +// } +// translucentStatusBar(activity, true); +// } +// } +// } +// }); +// } + + private static int getStatusBarHeight(Context context) { + int result = 0; + int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resId > 0) { + result = context.getResources().getDimensionPixelOffset(resId); + } + return result; + } +} diff --git a/libraries/map-amap/build.gradle b/libraries/map-amap/build.gradle index ae38f90032..b70d651de7 100644 --- a/libraries/map-amap/build.gradle +++ b/libraries/map-amap/build.gradle @@ -26,9 +26,9 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation rootProject.ext.dependencies.androidxappcompat - implementation rootProject.ext.dependencies.amapnavi3dmap - implementation rootProject.ext.dependencies.amapsearch - implementation rootProject.ext.dependencies.amaplocation + api rootProject.ext.dependencies.amapnavi3dmap + api rootProject.ext.dependencies.amapsearch + api rootProject.ext.dependencies.amaplocation if (Boolean.valueOf(RELEASE)) { implementation rootProject.ext.dependencies.mogoutils diff --git a/modules/mogo-module-map/build.gradle b/modules/mogo-module-map/build.gradle index d6c47f5377..e412f0b9f2 100644 --- a/modules/mogo-module-map/build.gradle +++ b/modules/mogo-module-map/build.gradle @@ -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') diff --git a/modules/mogo-module-navi/build.gradle b/modules/mogo-module-navi/build.gradle index 71c043611c..4d52cee8cd 100644 --- a/modules/mogo-module-navi/build.gradle +++ b/modules/mogo-module-navi/build.gradle @@ -20,6 +20,11 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { @@ -36,7 +41,9 @@ dependencies { implementation rootProject.ext.dependencies.androidxconstraintlayout implementation rootProject.ext.dependencies.arouter implementation rootProject.ext.dependencies.room - implementation rootProject.ext.dependencies.roomAnnotationProcessor + implementation rootProject.ext.dependencies.androidxrecyclerview + annotationProcessor rootProject.ext.dependencies.roomAnnotationProcessor implementation rootProject.ext.dependencies.roomRxjava annotationProcessor rootProject.ext.dependencies.aroutercompiler + implementation 'org.jetbrains:annotations-java5:15.0' } diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/bean/POIInfo.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/POIInfo.java similarity index 96% rename from modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/bean/POIInfo.java rename to modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/POIInfo.java index 21e963e2f2..8d479b3172 100644 --- a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/bean/POIInfo.java +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/POIInfo.java @@ -1,4 +1,4 @@ -package com.mogo.module.navi.database.bean; +package com.mogo.module.navi.bean; import androidx.room.Entity; import androidx.room.PrimaryKey; diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/DataConstants.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/DataConstants.java new file mode 100644 index 0000000000..a0dc988880 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/DataConstants.java @@ -0,0 +1,45 @@ +package com.mogo.module.navi.constants; + +import android.net.Uri; + +/** + * @author zyz + * @since 2019-10-02 + *

+ * 描述 + */ +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"; + +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/dao/POIDao.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/POIDao.java similarity index 85% rename from modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/dao/POIDao.java rename to modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/POIDao.java index 729bf7bf4d..c795afc872 100644 --- a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/dao/POIDao.java +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/POIDao.java @@ -1,10 +1,10 @@ -package com.mogo.module.navi.database.dao; +package com.mogo.module.navi.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 com.mogo.module.navi.bean.POIInfo; import io.reactivex.Flowable; import java.util.List; diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/lib/AMapNaviStatusChangedListener.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/lib/AMapNaviStatusChangedListener.java new file mode 100644 index 0000000000..60d98b8933 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/lib/AMapNaviStatusChangedListener.java @@ -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 + *

+ * 描述 + */ +public interface AMapNaviStatusChangedListener extends AMapNaviListener, + AMapNaviViewListener, + AMap.OnCameraChangeListener { + + void onNaviInfoUpdate(NaviInfoWrapper wrapper); +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/lib/AMapNaviStatusChangedListenerDefault.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/lib/AMapNaviStatusChangedListenerDefault.java new file mode 100644 index 0000000000..90eaf15fc1 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/lib/AMapNaviStatusChangedListenerDefault.java @@ -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 + *

+ */ +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 ) { + + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/SearchPoiAdapter.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/SearchPoiAdapter.java new file mode 100644 index 0000000000..e8f6d7d7fd --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/SearchPoiAdapter.java @@ -0,0 +1,40 @@ +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 java.util.List; + +/** + * @author zyz + * 2019-08-13. + */ +public class SearchPoiAdapter extends RecycleBaseAdapter { + /** + * @param context + * @param list + */ + public SearchPoiAdapter(Context context, List list) { + super(context, list, R.layout.item_search_poi); + } + + 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; + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/base/RecycleBaseAdapter.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/base/RecycleBaseAdapter.java new file mode 100644 index 0000000000..5817c1457d --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/base/RecycleBaseAdapter.java @@ -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; + +/** + *

+ * Title: adapter + *

+ *

+ * Description: + *

+ *

+ * Copyright: Copyright (c) 2015 + *

+ *

+ *

+ */ +public abstract class RecycleBaseAdapter extends + RecyclerView.Adapter +{ + + protected Context context; + protected List list; + private int resourceID; + private Toast toast; + + /** + * @param context + */ + public RecycleBaseAdapter(Context context, List 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 list) + { + setDatas(list, false); + } + + public void setDatas(List 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); + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/base/RecycleViewHolder.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/base/RecycleViewHolder.java new file mode 100644 index 0000000000..d069ad309e --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/base/RecycleViewHolder.java @@ -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 mViews; + + private View mConvertView; + + public RecycleViewHolder(View itemView) { + super(itemView); + this.mConvertView = itemView; + mViews = new SparseArray(); + // TODO Auto-generated constructor stub + } + + public static RecycleViewHolder get(View itemView) { + return new RecycleViewHolder(itemView); + } + + public View getConvertView() { + return mConvertView; + } + + public 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; + } + +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/AMapBaseFragment.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/AMapBaseFragment.java new file mode 100644 index 0000000000..62757ec200 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/AMapBaseFragment.java @@ -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 + *

+ * 描述 + */ +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(); + } +} + diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/AMapServiceVisitor.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/AMapServiceVisitor.java new file mode 100644 index 0000000000..167b80fa83 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/AMapServiceVisitor.java @@ -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 + *

+ * 描述 + */ +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); +} \ No newline at end of file diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/BaseActivity.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/BaseActivity.java new file mode 100644 index 0000000000..907a9685dc --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/BaseActivity.java @@ -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 + *

+ * 地图 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 ); + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/BaseFragment.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/BaseFragment.java new file mode 100644 index 0000000000..369cf25c78 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/BaseFragment.java @@ -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 + *

+ * 描述 + */ +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(); + } + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/UiController.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/UiController.java new file mode 100644 index 0000000000..8530553011 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/UiController.java @@ -0,0 +1,53 @@ +package com.mogo.module.navi.ui.base; + +import androidx.fragment.app.FragmentManager; + +/** + * @author congtaowang + * @since 2019-10-04 + *

+ * 描述 + */ +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(); +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchConstants.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchConstants.java new file mode 100644 index 0000000000..5c81a6339c --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchConstants.java @@ -0,0 +1,54 @@ +package com.mogo.module.navi.ui.search; + +import com.mogo.module.navi.constants.DataConstants; + +/** + * @author congtaowang + * @since 2019-12-08 + *

+ * 搜索页面常量字段 + */ +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; +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchFragment.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchFragment.java new file mode 100644 index 0000000000..3b092841f5 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchFragment.java @@ -0,0 +1,566 @@ +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.navi.R; +import com.mogo.module.navi.ui.adapter.SearchPoiAdapter; +import com.mogo.module.navi.ui.base.BaseFragment; +import com.mogo.module.navi.ui.base.UiController; +import com.mogo.utils.WindowUtils; +import io.reactivex.disposables.Disposable; +import java.util.List; + +/** + * 搜索页面 + *

+ * 普通搜索:从首页点击搜索按钮进入:包含:仅输入搜索(列表不包含设置按钮) + * {@link SearchConstants#SEARCH_TYPE_COMMON} + *

+ * 地址设置搜索:设置家、公司、其他的地址:包含当前位置、选点、搜索列表(列表包含设置按钮)、普通页面 + * {@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 com.mogo.module.navi.database.ui.search.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( com.mogo.module.navi.database.ui.search.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( com.mogo.module.navi.database.ui.search.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( datums, com.mogo.module.navi.database.ui.search.SearchUtils + .getSearchTypeActionName( mSearchType ) ); + 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(); + + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchPresenter.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchPresenter.java new file mode 100644 index 0000000000..50690be5f6 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchPresenter.java @@ -0,0 +1,289 @@ +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.navi.constants.DataConstants; +import io.reactivex.Single; +import io.reactivex.SingleEmitter; +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 + *

+ * 搜搜页逻辑处理 + */ +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 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 output = AMapDatabase.getInstance( getContext() ).getSearchPoiDao().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 = AMapDatabase.getInstance( getContext() ) + .getSearchPoiDao() + .getAll() + .map( input -> { + return AMapDatabase.getInstance( getContext() ).getSearchPoiDao().deleteAll( input ); + } ) + .subscribeOn( Schedulers.io() ) + .observeOn( AndroidSchedulers.mainThread() ) + .subscribe( count -> { + view.renderSearchPoiResult( null, false ); + } ); + mCompositeDisposable.add( disposable ); + } + + /** + * 缓存搜索位置为常用地址设置 + * + * @param tip + * @return + */ + public Single cacheCommonAddressPoi( Tip tip ) { + return Single.>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. + >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. + >create( emitter -> { + SearchPoi poi = EntityConvertUtils.geocodeAddress2Poi( address, mLastCameraPosition ); + emitterCommonAddress( emitter, poi ); + } ) + .subscribeOn( Schedulers.io() ) + .observeOn( AndroidSchedulers.mainThread() ); + } + + private void emitterCommonAddress( SingleEmitter> emitter, SearchPoi poi ) { + String poiId = null; + switch ( view.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( view.getSearchType() ); + //ignore insert result + final List output = AMapDatabase.getInstance( getContext() ).getSearchPoiDao().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 + view.renderChoicePointResult( regeocodeResult.getRegeocodeAddress() ); + } else { + view.renderChoicePointResult( null ); + } + } + + @Override + public void onGeocodeSearched( GeocodeResult geocodeResult, int resultID ) { + + } + + @Override + public void onDestroy( @NonNull LifecycleOwner owner ) { + super.onDestroy( owner ); + if ( view.getSearchBox() != null ) { + view.getSearchBox().removeTextChangedListener( watcherAdapter ); + } + if ( mCompositeDisposable != null && !mCompositeDisposable.isDisposed() ) { + mCompositeDisposable.dispose(); + mCompositeDisposable = null; + } + CameraChangedLiveData.getInstance().removeAllObserver(); + mSearchEngine = null; + mGeocodeSearch = null; + mLastCameraPosition = null; + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchUtils.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchUtils.java new file mode 100644 index 0000000000..976a5e209e --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchUtils.java @@ -0,0 +1,39 @@ +package com.mogo.module.navi.ui.search; + +/** + * @author congtaowang + * @since 2019-12-08 + *

+ * 搜索工具类 + */ +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; + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchView.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchView.java new file mode 100644 index 0000000000..feee118364 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchView.java @@ -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 + *

+ * 描述 + */ +public interface SearchView extends IView { + + EditText getSearchBox(); + + /** + * @param datums + * @param showDelete 是否显示清空历史记录项 + */ + void renderSearchPoiResult(List datums, boolean showDelete); + + int getSearchType(); + + /** + * 当前是哪一个操作 + * + * @return + */ + int getUiMode(); + + /** + * 显示逆地理位置编码结果 + * + * @param address + */ + void renderChoicePointResult(RegeocodeAddress address); + + /** + * 选点完毕后marker动画 + */ + void startJumpAnimation(); + +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapCalcRouteResultWrapper.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapCalcRouteResultWrapper.java new file mode 100644 index 0000000000..5a96daf444 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapCalcRouteResultWrapper.java @@ -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 + *

+ * 描述 + */ +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]; + } + }; +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapNaviCameraInfoWrapper.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapNaviCameraInfoWrapper.java new file mode 100644 index 0000000000..9463cdc52a --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapNaviCameraInfoWrapper.java @@ -0,0 +1,99 @@ +package com.mogo.module.navi.wrapper; + +import com.amap.api.navi.model.AMapNaviCameraInfo; + +/** + * @author congtaowang + * @since 2019-10-10 + *

+ * 描述 + */ +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; + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapNaviLocationWrapper.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapNaviLocationWrapper.java new file mode 100644 index 0000000000..0bba71fdd9 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/AMapNaviLocationWrapper.java @@ -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 + *

+ * 描述 + */ +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]; + } + }; +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/LatLngWrapper.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/LatLngWrapper.java new file mode 100644 index 0000000000..e8dedf1ef8 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/LatLngWrapper.java @@ -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 + *

+ * 经纬度 + */ +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; + } + + +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/NaviInfoWrapper.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/NaviInfoWrapper.java new file mode 100644 index 0000000000..7ec2849867 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/wrapper/NaviInfoWrapper.java @@ -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 + *

+ * 导航信息对象 + */ +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(); + } +} diff --git a/modules/mogo-module-navi/src/main/res/layout/item_search_poi.xml b/modules/mogo-module-navi/src/main/res/layout/item_search_poi.xml new file mode 100644 index 0000000000..fe43a9d083 --- /dev/null +++ b/modules/mogo-module-navi/src/main/res/layout/item_search_poi.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-navi/src/main/res/values/colors.xml b/modules/mogo-module-navi/src/main/res/values/colors.xml new file mode 100644 index 0000000000..4add7088b2 --- /dev/null +++ b/modules/mogo-module-navi/src/main/res/values/colors.xml @@ -0,0 +1,15 @@ + + + #008577 + #00574B + #D81B60 + #ff080625 + #FFFFFF + #7FFFFFFF + #00BFFF + #4DFFFFFF + #4D080625 + + #080625 + + diff --git a/modules/mogo-module-navi/src/main/res/values/ids.xml b/modules/mogo-module-navi/src/main/res/values/ids.xml new file mode 100644 index 0000000000..ed4cc2c662 --- /dev/null +++ b/modules/mogo-module-navi/src/main/res/values/ids.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 887898a920198971d36aeafb945bab7b4941972b Mon Sep 17 00:00:00 2001 From: zhangyuanzhen Date: Thu, 2 Jan 2020 18:08:53 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=90=9C=E7=B4=A2UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/mogo/utils/AssetsUtils.java | 37 ++ gradle.properties | 2 +- .../module/common/TextWatcherAdapter.java | 28 ++ .../map/location/AMapLocationManager.java | 131 ++++++ .../module/map/location/LocationUtils.java | 29 ++ .../module/map/location/MyLocationUtils.java | 53 +++ modules/mogo-module-navi/build.gradle | 7 +- .../module/navi/bean/EntityConvertUtils.java | 95 ++++ .../com/mogo/module/navi/bean/POIInfo.java | 65 --- .../com/mogo/module/navi/bean/SearchPoi.java | 236 ++++++++++ .../module/navi/constants/AMapConstants.java | 29 ++ .../module/navi/constants/CustomMapStyle.java | 16 + .../java/com/mogo/module/navi/dao/POIDao.java | 32 -- .../mogo/module/navi/dao/SearchPoiDao.java | 42 ++ .../module/navi/database/AppDataBase.java | 8 +- .../navi/ui/adapter/SearchPoiAdapter.java | 30 ++ .../module/navi/ui/base/MapUIController.java | 430 ++++++++++++++++++ .../module/navi/ui/search/SearchFragment.java | 57 +-- .../navi/ui/search/SearchPresenter.java | 43 +- .../res/drawable/amap_white_shadow_bkg.9.png | Bin 0 -> 1316 bytes .../src/main/res/layout/fragment_search.xml | 137 ++++++ .../src/main/res/values/styles.xml | 19 + 22 files changed, 1377 insertions(+), 149 deletions(-) create mode 100644 foudations/mogo-utils/src/main/java/com/mogo/utils/AssetsUtils.java create mode 100644 modules/mogo-module-common/src/main/java/com/mogo/module/common/TextWatcherAdapter.java create mode 100644 modules/mogo-module-map/src/main/java/com/mogo/module/map/location/AMapLocationManager.java create mode 100644 modules/mogo-module-map/src/main/java/com/mogo/module/map/location/LocationUtils.java create mode 100644 modules/mogo-module-map/src/main/java/com/mogo/module/map/location/MyLocationUtils.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/EntityConvertUtils.java delete mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/POIInfo.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/SearchPoi.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/AMapConstants.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/CustomMapStyle.java delete mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/POIDao.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/SearchPoiDao.java create mode 100644 modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/MapUIController.java create mode 100644 modules/mogo-module-navi/src/main/res/drawable/amap_white_shadow_bkg.9.png create mode 100644 modules/mogo-module-navi/src/main/res/layout/fragment_search.xml create mode 100644 modules/mogo-module-navi/src/main/res/values/styles.xml diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/AssetsUtils.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/AssetsUtils.java new file mode 100644 index 0000000000..7ec9448cd7 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/AssetsUtils.java @@ -0,0 +1,37 @@ +package com.mogo.utils; + +import android.content.Context; +import android.text.TextUtils; +import android.util.Log; +import java.io.BufferedInputStream; +import java.io.InputStream; + +/** + * @author congtaowang + * @since 2019-12-12 + *

+ * 读取asset文件 + */ +public class AssetsUtils { + + private static final String TAG = "amap.AssetsUtils"; + + public static byte[] read( Context context, String fileName ) { + if ( context == null || TextUtils.isEmpty( fileName ) ) { + return null; + } + byte[] buffer = null; + try { + InputStream is = context.getAssets().open( fileName ); + BufferedInputStream bis = new BufferedInputStream( is ); + buffer = new byte[is.available()]; + bis.read( buffer ); + bis.close(); + is.close(); + Log.d( TAG, "read assets success: " + fileName + " size=" + buffer.length ); + } catch ( Exception e ) { + e.printStackTrace(); + } + return buffer; + } +} diff --git a/gradle.properties b/gradle.properties index 8aa999532c..ac1785fca2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,7 @@ SNAPSHOT_REPOSITORY_URL=http://nexus.zhidaoauto.com/repository/maven-snapshots/ USERNAME=xintai PASSWORD=xintai2018 # 编译模式: false - 依赖本地版本, true - 依赖 maven 版本 -RELEASE=true +RELEASE=false # 模块版本 DEMO_MODULE_MAP_VERSION=1.0.0-SNAPSHOT DEMO_MODULE_MAP2_VERSION=1.0.0-SNAPSHOT diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/TextWatcherAdapter.java b/modules/mogo-module-common/src/main/java/com/mogo/module/common/TextWatcherAdapter.java new file mode 100644 index 0000000000..469b5f538d --- /dev/null +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/TextWatcherAdapter.java @@ -0,0 +1,28 @@ +package com.mogo.module.common; + +import android.text.Editable; +import android.text.TextWatcher; + +/** + * @author congtaowang + * @since 2019-10-02 + *

+ * 描述 + */ +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 ) { + + } +} diff --git a/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/AMapLocationManager.java b/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/AMapLocationManager.java new file mode 100644 index 0000000000..2aeee6ba15 --- /dev/null +++ b/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/AMapLocationManager.java @@ -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 ); + } + } + } + } +} \ No newline at end of file diff --git a/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/LocationUtils.java b/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/LocationUtils.java new file mode 100644 index 0000000000..f989358fa4 --- /dev/null +++ b/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/LocationUtils.java @@ -0,0 +1,29 @@ +package com.mogo.module.map.location; + +/** + * @author congtaowang + * @since 2019-09-27 + *

+ * 描述 + */ +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; + } + } +} diff --git a/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/MyLocationUtils.java b/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/MyLocationUtils.java new file mode 100644 index 0000000000..51118e107c --- /dev/null +++ b/modules/mogo-module-map/src/main/java/com/mogo/module/map/location/MyLocationUtils.java @@ -0,0 +1,53 @@ +package com.mogo.module.map.location; + +import com.amap.api.maps.model.MyLocationStyle; + +/** + * @author congtaowang + * @since 2019-10-17 + *

+ * 描述 + */ +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; + } + +} diff --git a/modules/mogo-module-navi/build.gradle b/modules/mogo-module-navi/build.gradle index dd4d1204fa..315cd98809 100644 --- a/modules/mogo-module-navi/build.gradle +++ b/modules/mogo-module-navi/build.gradle @@ -43,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 @@ -60,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') } } diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/EntityConvertUtils.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/EntityConvertUtils.java new file mode 100644 index 0000000000..6254ab5068 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/EntityConvertUtils.java @@ -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 + *

+ * 实体类操作工具 + */ +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(), + "" ); + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/POIInfo.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/POIInfo.java deleted file mode 100644 index d2d3618410..0000000000 --- a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/POIInfo.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.mogo.module.navi.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; - } - - -} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/SearchPoi.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/SearchPoi.java new file mode 100644 index 0000000000..7226cbcc11 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/bean/SearchPoi.java @@ -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 + *

+ * 搜索地址表数据结构 + */ +@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数据类型 + *

+ * {@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]; + } + }; +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/AMapConstants.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/AMapConstants.java new file mode 100644 index 0000000000..3b056b4c6c --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/AMapConstants.java @@ -0,0 +1,29 @@ +package com.mogo.module.navi.constants; + +import com.amap.api.navi.enums.PathPlanningStrategy; + +/** + * @author congtaowang + * @since 2019-10-04 + *

+ * 地图基本参数配置 + */ +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; +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/CustomMapStyle.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/CustomMapStyle.java new file mode 100644 index 0000000000..d23454c140 --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/constants/CustomMapStyle.java @@ -0,0 +1,16 @@ +package com.mogo.module.navi.constants; + +/** + * @author congtaowang + * @since 2019-12-12 + *

+ * 自定义地图样式 + */ +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"; +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/POIDao.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/POIDao.java deleted file mode 100644 index c795afc872..0000000000 --- a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/POIDao.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mogo.module.navi.dao; - -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; -import com.mogo.module.navi.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 insert(POIInfo... poiInfos); - - /** - * 获取地址列表 - * @return - */ - @Query("SELECT * from poiinfo") - Flowable> load(); -} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/SearchPoiDao.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/SearchPoiDao.java new file mode 100644 index 0000000000..56a799272c --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/dao/SearchPoiDao.java @@ -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 + *

+ * 搜索页面数据操作 + */ +@Dao +public interface SearchPoiDao { + + @Insert( onConflict = OnConflictStrategy.REPLACE ) + List insert(SearchPoi... datums); + + @Query( "SELECT * FROM " + DataConstants.T_SEARCH_POI + " WHERE type=" + DataConstants.TYPE_POI + " ORDER BY time DESC LIMIT :limit" ) + Single> getLastN(int limit); + + @Query( "SELECT * FROM " + DataConstants.T_SEARCH_POI + " WHERE type=" + DataConstants.TYPE_POI ) + Single> getAll(); + + @Query( "SELECT * FROM " + DataConstants.T_SEARCH_POI + " WHERE type=" + DataConstants.TYPE_HOME_ADDRESS ) + Single> getHomeAddress(); + + @Query( "SELECT * FROM " + DataConstants.T_SEARCH_POI + " WHERE type=" + DataConstants.TYPE_COMPANY_ADDRESS ) + Single> getCompanyAddress(); + + @Delete + int delete(SearchPoi poi); + + @Delete + int deleteAll(List list); +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/AppDataBase.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/AppDataBase.java index 6db187784e..be21d6ee4f 100644 --- a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/AppDataBase.java +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/database/AppDataBase.java @@ -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; diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/SearchPoiAdapter.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/SearchPoiAdapter.java index e8f6d7d7fd..18c9f06343 100644 --- a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/SearchPoiAdapter.java +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/adapter/SearchPoiAdapter.java @@ -6,6 +6,7 @@ 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; /** @@ -20,6 +21,10 @@ public class SearchPoiAdapter extends RecycleBaseAdapter { public SearchPoiAdapter(Context context, List 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; @@ -37,4 +42,29 @@ public class SearchPoiAdapter extends RecycleBaseAdapter { 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; + } } diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/MapUIController.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/MapUIController.java new file mode 100644 index 0000000000..1a0564ac6d --- /dev/null +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/base/MapUIController.java @@ -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 + *

+ * 描述 + */ +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(); + } + } +} diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchFragment.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchFragment.java index 3b092841f5..8beea1b768 100644 --- a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchFragment.java +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchFragment.java @@ -30,9 +30,13 @@ 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; @@ -110,7 +114,7 @@ public class SearchFragment extends BaseFragment implements SearchView, public void onActivityCreated( @Nullable Bundle savedInstanceState ) { super.onActivityCreated( savedInstanceState ); initViews(); - getLifecycle().addObserver( mSearchPresenter = new com.mogo.module.navi.database.ui.search.SearchPresenter( this ) ); + getLifecycle().addObserver( mSearchPresenter = new SearchPresenter( this ) ); } private void initViews() { @@ -241,7 +245,7 @@ public class SearchFragment extends BaseFragment implements SearchView, mCurrentLocation.setVisibility( View.GONE ); mSearchResult.setVisibility( View.GONE ); mActionButton.setVisibility( View.VISIBLE ); - mActionButton.setText( com.mogo.module.navi.database.ui.search.SearchUtils.getSearchTypeActionName( mSearchType ) ); + mActionButton.setText( SearchUtils.getSearchTypeActionName( mSearchType ) ); mSearchBox.setCompoundDrawables( null, null, null, null ); removeChoicePointMarker(); mSearchBox.setTag( null ); @@ -264,7 +268,7 @@ public class SearchFragment extends BaseFragment implements SearchView, mCurrentLocation.setVisibility( View.GONE ); mSearchResult.setVisibility( View.GONE ); mActionButton.setVisibility( View.VISIBLE ); - mActionButton.setText( com.mogo.module.navi.database.ui.search.SearchUtils.getSearchTypeActionName( mSearchType ) ); + mActionButton.setText( SearchUtils.getSearchTypeActionName( mSearchType ) ); mSearchBox.setCompoundDrawables( null, null, null, null ); showChoicePointMarker(); mSearchBox.setTag( null ); @@ -313,18 +317,18 @@ public class SearchFragment extends BaseFragment implements SearchView, @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(); - } + //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(); } @@ -390,8 +394,7 @@ public class SearchFragment extends BaseFragment implements SearchView, } if ( mPoiAdapter == null ) { - mPoiAdapter = new SearchPoiAdapter( datums, com.mogo.module.navi.database.ui.search.SearchUtils - .getSearchTypeActionName( mSearchType ) ); + mPoiAdapter = new SearchPoiAdapter(getContext(), datums ); mPoiAdapter.setOnItemClickedListener( item -> { if ( mSearchType == SearchConstants.SEARCH_TYPE_COMMON ) { final Disposable disposable = mSearchPresenter.cacheSelectPoiItem( item ).subscribe( output -> { @@ -443,15 +446,15 @@ public class SearchFragment extends BaseFragment implements SearchView, mSearchBox.setText( address.getFormatAddress() ); } - @Override - public void renderErrorView() { - - } - - @Override - public void renderContentView() { - - } + //@Override + //public void renderErrorView() { + // + //} + // + //@Override + //public void renderContentView() { + // + //} // view interface end @@ -502,7 +505,7 @@ public class SearchFragment extends BaseFragment implements SearchView, Toast.makeText( mContext, "未设置", Toast.LENGTH_SHORT ).show(); return; } - SearchPoiLiveData.getInstance().postValue( searchPoi ); + //SearchPoiLiveData.getInstance().postValue( searchPoi ); exitSearch(); } diff --git a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchPresenter.java b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchPresenter.java index 50690be5f6..717f37044f 100644 --- a/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchPresenter.java +++ b/modules/mogo-module-navi/src/main/java/com/mogo/module/navi/ui/search/SearchPresenter.java @@ -19,9 +19,14 @@ 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; @@ -124,7 +129,7 @@ public class SearchPresenter extends Presenter< SearchView > return Single.create( emitter -> { SearchPoi poi = EntityConvertUtils.tipToPoi( tip ); //ignore insert result - final List output = AMapDatabase.getInstance( getContext() ).getSearchPoiDao().insert( poi ); + final List output = AppDataBase.getDatabase( getContext() ).poiDao().insert( poi ); emitter.onSuccess( output ); } ).subscribeOn( Schedulers.io() ).observeOn( AndroidSchedulers.mainThread() ); } @@ -149,16 +154,16 @@ public class SearchPresenter extends Presenter< SearchView > } private void deleteAllCachedPoiImpl() { - final Disposable disposable = AMapDatabase.getInstance( getContext() ) - .getSearchPoiDao() + final Disposable disposable = AppDataBase.getDatabase( getContext() ) + .poiDao() .getAll() .map( input -> { - return AMapDatabase.getInstance( getContext() ).getSearchPoiDao().deleteAll( input ); + return AppDataBase.getDatabase( getContext() ).poiDao().deleteAll( input ); } ) .subscribeOn( Schedulers.io() ) .observeOn( AndroidSchedulers.mainThread() ) .subscribe( count -> { - view.renderSearchPoiResult( null, false ); + mView.renderSearchPoiResult( null, false ); } ); mCompositeDisposable.add( disposable ); } @@ -211,7 +216,7 @@ public class SearchPresenter extends Presenter< SearchView > private void emitterCommonAddress( SingleEmitter> emitter, SearchPoi poi ) { String poiId = null; - switch ( view.getSearchType() ) { + switch ( mView.getSearchType() ) { case SearchConstants.SEARCH_TYPE_MULTI_HOME: poiId = DataConstants.POI_ID_HOME; break; @@ -228,20 +233,20 @@ public class SearchPresenter extends Presenter< SearchView > return; } poi.setpId( poiId ); - poi.setType( view.getSearchType() ); + poi.setType( mView.getSearchType() ); //ignore insert result - final List output = AMapDatabase.getInstance( getContext() ).getSearchPoiDao().insert( poi ); + final List 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() ); - - } + //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 ) { @@ -260,9 +265,9 @@ public class SearchPresenter extends Presenter< SearchView > @Override public void onRegeocodeSearched( RegeocodeResult regeocodeResult, int resultID ) { if ( resultID == 1000 ) { // success - view.renderChoicePointResult( regeocodeResult.getRegeocodeAddress() ); + mView.renderChoicePointResult( regeocodeResult.getRegeocodeAddress() ); } else { - view.renderChoicePointResult( null ); + mView.renderChoicePointResult( null ); } } @@ -274,14 +279,14 @@ public class SearchPresenter extends Presenter< SearchView > @Override public void onDestroy( @NonNull LifecycleOwner owner ) { super.onDestroy( owner ); - if ( view.getSearchBox() != null ) { - view.getSearchBox().removeTextChangedListener( watcherAdapter ); + if ( mView.getSearchBox() != null ) { + mView.getSearchBox().removeTextChangedListener( watcherAdapter ); } if ( mCompositeDisposable != null && !mCompositeDisposable.isDisposed() ) { mCompositeDisposable.dispose(); mCompositeDisposable = null; } - CameraChangedLiveData.getInstance().removeAllObserver(); + //CameraChangedLiveData.getInstance().removeAllObserver(); mSearchEngine = null; mGeocodeSearch = null; mLastCameraPosition = null; diff --git a/modules/mogo-module-navi/src/main/res/drawable/amap_white_shadow_bkg.9.png b/modules/mogo-module-navi/src/main/res/drawable/amap_white_shadow_bkg.9.png new file mode 100644 index 0000000000000000000000000000000000000000..0c5f028dbe6c99bc589e9920793199ab84e298f5 GIT binary patch literal 1316 zcmV+<1>5?GP)G_|`hH`5R7G2#ExyG^7NYgBP*mEk3ZkOuN?o|H3n42J zQE(CHLRNkTCXoy1E!iBB5U8rE8r;y( zFa&98Y8r|(H#ZN968FCw&s?{NeB^sWHisl6bp2I%dHHbZM%2~Sjg)>A(%9Jeb+({q z3}czYT(^J-@_wYF$Yv77AjTn5QBg6bwzhU$eSQ6S=_ewUm6hLQiqkWOvCLsE7+`_v zhVjMCxH8tN#KSg7vip+G8_+J0b$P{$^#~8-ioUR3c1*RkJO*+c6 z1~j6qtZXz!)SuMW)^@eCv$H0Q`C~2^V1WrXHu90qs`0tr%_PgM!xQF}$ue|3Oy~y| znDX)jY($XG_Hr2MT|$AR0Kk#ub}9^J$~$#Q5e5rPu(9DhjcqtYcsZ9aDY+)1IaLDv>KEfZoYh`Gx+V4o7>gwvbx?YkrVKBkQ1__DH2ruU+ zY<02AyWA$STVQjP=|4)=B~2Jiu(4s4WTNvjTp|f)hl7hs@bJ%I zV*^{*w7eM}5f&d4&I|{87))X1x?U`@KgkojQ;6YR!rp)l$!u)$fPn*Cq6mkXgefa7 z90WFvq!7SLysP#=3L$a8uvcIUn=UMD3os}zVHdwvUMT7_)GiRnT7mu|Ii56OFu}$K zwy?=l6b_#v{2}37{8}kn#4S^QuiBy%2p1Xl25gzlt~icJyj;Sz1M4bhx=phvI|A4w z`CW1*g&00#*qgA0O>D!#xO|$h?Z76J1kx=flZiEf{*i)*&w(x3f-P)fyGMj6BaX1E z5CU9AQb-Po@P!mSd>(AGu?(B8Qn=EVO*rU|umG0>ruJ}3gfD9=#cH4F`i0t;i1oSc#p*v%`+zyp{bkkRxMB8mw-$Ksho$>XfTtuEC4cJr zhV=K1%wveL0K`Z>=09EEV=Qx+tNuyp_k-!N9}c|VI0U%evihWzq$}p_f7HJz{T<0& zlRN16k1;m(ob)GHI9Q%<9D(mU-BN+C$B?e~sXaoL8}UoJzO4RLi_dG;zii2MR_$r# zP!-f}1IzQBF7SS9wz|Al#x|?J6XKGCx;}>IAZ3dvGJ@!iGKR6tVXpdX49n-OIq*K0 zkgib17V_MOxMZVc`407eC5a?^Om>@YhsFO!o5TKOAy}U05`p*059ee&jVwfdu&2`s zwX4nZ#N>J>=twF^GL|{a1p_S4lb?8JYgT$V;485GMj^MBOsDwULXZXMER+guYyopE z%zV$*`sVbKxrv-!_Pg`p-k!imoxZ1j0^cvcaisYbsXLNse**jbzSH&VFQGm7mK;~S ae*Xj9mr-3;MRO$p0000 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-navi/src/main/res/values/styles.xml b/modules/mogo-module-navi/src/main/res/values/styles.xml new file mode 100644 index 0000000000..624c3162ae --- /dev/null +++ b/modules/mogo-module-navi/src/main/res/values/styles.xml @@ -0,0 +1,19 @@ + + + + + + + + +