From c3df548d0462ae4e73e7e8f7fa5db3407fd4bf3e Mon Sep 17 00:00:00 2001 From: zhangyuanzhen Date: Thu, 2 Jan 2020 16:56:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=BC=E8=88=AA=E6=A8=A1?= =?UTF-8?q?=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