add window manager dialog

This commit is contained in:
wangcongtao
2020-05-15 17:00:47 +08:00
parent 696491509c
commit 8d7e09f81d
30 changed files with 455 additions and 1985 deletions

View File

@@ -22,7 +22,9 @@ public class AppLauncher extends BaseAppLauncher {
@Override
public void launch( Context context, AppInfo appInfo ) {
try {
AppServiceHandler.getApis().getAdasControllerApi().closeADAS();
if ( LaunchUtils.getLaunchIntentForPackage( context, appInfo.getPackageName() ) != null ) {
AppServiceHandler.getApis().getAdasControllerApi().closeADAS();
}
LaunchUtils.launchByPkg( context, appInfo.getPackageName() );
} catch ( Exception e ) {
Logger.e( TAG, e, "error." );

View File

@@ -20,9 +20,13 @@ public class LaunchUtils {
* @param context
* @param pkg 包名
*/
public static void launchByPkg( Context context, String pkg ) throws Exception{
Intent intent = context.getPackageManager().getLaunchIntentForPackage( pkg );
public static void launchByPkg( Context context, String pkg ) throws Exception {
Intent intent = getLaunchIntentForPackage( context, pkg );
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
context.startActivity( intent );
}
public static Intent getLaunchIntentForPackage( Context context, String pkg ) {
return context.getPackageManager().getLaunchIntentForPackage( pkg );
}
}

View File

@@ -31,7 +31,7 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.androidxrecyclerview
implementation rootProject.ext.dependencies.androidxconstraintlayout
if (Boolean.valueOf(RELEASE)) {
api rootProject.ext.dependencies.mogomap
api rootProject.ext.dependencies.mogomapapi

View File

@@ -0,0 +1,198 @@
package com.mogo.module.common.dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.PixelFormat;
import android.os.Build;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import androidx.annotation.StringRes;
import com.mogo.module.common.R;
import com.mogo.module.common.utils.CarSeries;
import com.mogo.utils.WindowUtils;
/**
* @author congtaowang
* @since 2020-04-24
* <p>
* 显示在最上层的对话框
*/
public class WMDialog implements DialogInterface {
private WMDialogParams mParams;
private WindowManager mWindowManager;
private boolean mIsShowing = false;
private View mContentView;
private WindowManager.LayoutParams mLayoutParams;
private WMDialog( WMDialogParams params ) {
this.mParams = params;
}
public void show() {
if ( mIsShowing ) {
return;
}
mIsShowing = true;
if ( mWindowManager == null ) {
mWindowManager = ( WindowManager ) mParams.mContext.getApplicationContext().getSystemService( Context.WINDOW_SERVICE );
}
if ( mContentView == null ) {
mLayoutParams = new WindowManager.LayoutParams();
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ) {
mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
mLayoutParams.format = PixelFormat.TRANSLUCENT;
mLayoutParams.gravity = Gravity.CENTER;
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
if ( CarSeries.getSeries() == CarSeries.CAR_SERIES_F80X ) {
mLayoutParams.width = 1920;
mLayoutParams.height = 1080;
} else {
mLayoutParams.width = WindowUtils.getScreenWidth( mParams.mContext );
mLayoutParams.height = WindowUtils.getScreenHeight( mParams.mContext );
}
mLayoutParams.dimAmount = 0.5f;
mLayoutParams.x = 0;
mLayoutParams.y = 0;
mContentView = initViews();
}
mWindowManager.addView( mContentView, mLayoutParams );
}
private View initViews() {
View contentView = LayoutInflater.from( mParams.mContext ).inflate( R.layout.module_commons_layout_wm_dialog, null );
TextView ok = contentView.findViewById( R.id.module_commons_wm_dialog_button_ok );
TextView cancel = contentView.findViewById( R.id.module_commons_wm_dialog_button_cancel );
TextView content = contentView.findViewById( R.id.module_commons_wm_dialog_content );
ok.setText( mParams.mOkButtonText );
if ( mParams.mOnOkButtonClickListener != null ) {
ok.setOnClickListener( view -> {
if ( mParams.mOnOkButtonClickListener != null ) {
mParams.mOnOkButtonClickListener.onClick( WMDialog.this, DialogInterface.BUTTON_POSITIVE );
}
} );
}
cancel.setText( mParams.mCancelButtonText );
if ( mParams.mOnCancelButtonClickListener != null ) {
cancel.setOnClickListener( view -> {
if ( mParams.mOnCancelButtonClickListener != null ) {
mParams.mOnCancelButtonClickListener.onClick( WMDialog.this, DialogInterface.BUTTON_NEGATIVE );
}
} );
}
content.setText( mParams.mContent );
return contentView;
}
@Override
public void cancel() {
dismiss();
}
@Override
public void dismiss() {
if ( !mIsShowing ) {
return;
}
if ( mContentView != null ) {
mWindowManager.removeViewImmediate( mContentView );
}
if ( mParams.mOnDialogDismissListener != null ) {
mParams.mOnDialogDismissListener.onDismiss( this );
}
mIsShowing = false;
}
public boolean isShowing() {
return mIsShowing;
}
public static class Builder {
private Context mContext;
private WMDialogParams mParams;
public Builder( Context context ) {
this.mContext = context;
mParams = new WMDialogParams();
mParams.mContext = context;
}
// public Builder setTitle( CharSequence title ) {
// mParams.mTitle = title;
// return this;
// }
//
// public Builder setTitle( @StringRes int title ) {
// mParams.mTitle = mContext.getString( title );
// return this;
// }
public Builder setContent( CharSequence content ) {
mParams.mContent = content;
return this;
}
public Builder setContent( @StringRes int content ) {
mParams.mContent = mContext.getString( content );
return this;
}
public Builder setOkButton( CharSequence buttonText, OnClickListener listener ) {
mParams.mOkButtonText = buttonText;
mParams.mOnOkButtonClickListener = listener;
return this;
}
public Builder setOkButton( @StringRes int buttonText, OnClickListener listener ) {
mParams.mOkButtonText = mContext.getText( buttonText );
mParams.mOnOkButtonClickListener = listener;
return this;
}
public Builder setCancelButton( CharSequence buttonText, OnClickListener listener ) {
mParams.mCancelButtonText = buttonText;
mParams.mOnCancelButtonClickListener = listener;
return this;
}
public Builder setCancelButton( @StringRes int buttonText, OnClickListener listener ) {
mParams.mCancelButtonText = mContext.getText( buttonText );
mParams.mOnCancelButtonClickListener = listener;
return this;
}
public Builder setOnDialogDismissListener( OnDismissListener onDialogDismissListener ) {
mParams.mOnDialogDismissListener = onDialogDismissListener;
return this;
}
public WMDialog build() {
WMDialog dialog = new WMDialog( mParams );
return dialog;
}
}
public static class WMDialogParams {
// public CharSequence mTitle;
public CharSequence mOkButtonText;
public CharSequence mCancelButtonText;
public CharSequence mContent;
public OnClickListener mOnOkButtonClickListener;
public OnClickListener mOnCancelButtonClickListener;
public OnDismissListener mOnDialogDismissListener;
public Context mContext;
}
}

View File

@@ -1,220 +0,0 @@
package com.yarolegovich.discretescrollview;
import android.graphics.Point;
import android.view.View;
/**
* Created by yarolegovich on 16.03.2017.
*/
public enum DSVOrientation {
HORIZONTAL {
@Override
Helper createHelper() {
return new HorizontalHelper();
}
},
VERTICAL {
@Override
Helper createHelper() {
return new VerticalHelper();
}
};
//Package private
abstract Helper createHelper();
interface Helper {
int getViewEnd(int recyclerWidth, int recyclerHeight);
int getDistanceToChangeCurrent(int childWidth, int childHeight);
void setCurrentViewCenter(Point recyclerCenter, int scrolled, Point outPoint);
void shiftViewCenter(Direction direction, int shiftAmount, Point outCenter);
int getFlingVelocity(int velocityX, int velocityY);
int getPendingDx(int pendingScroll);
int getPendingDy(int pendingScroll);
void offsetChildren(int amount, RecyclerViewProxy lm);
float getDistanceFromCenter(Point center, int viewCenterX, int viewCenterY);
boolean isViewVisible(Point center, int halfWidth, int halfHeight, int endBound,
int extraSpace);
boolean hasNewBecomeVisible(DiscreteScrollLayoutManager lm);
boolean canScrollVertically();
boolean canScrollHorizontally();
}
protected static class HorizontalHelper implements Helper {
@Override
public int getViewEnd(int recyclerWidth, int recyclerHeight) {
return recyclerWidth;
}
@Override
public int getDistanceToChangeCurrent(int childWidth, int childHeight) {
return childWidth;
}
@Override
public void setCurrentViewCenter(Point recyclerCenter, int scrolled, Point outPoint) {
int newX = recyclerCenter.x - scrolled;
outPoint.set(newX, recyclerCenter.y);
}
@Override
public void shiftViewCenter(Direction direction, int shiftAmount, Point outCenter) {
int newX = outCenter.x + direction.applyTo(shiftAmount);
outCenter.set(newX, outCenter.y);
}
@Override
public boolean isViewVisible(
Point viewCenter, int halfWidth, int halfHeight, int endBound,
int extraSpace) {
int viewLeft = viewCenter.x - halfWidth;
int viewRight = viewCenter.x + halfWidth;
return viewLeft < (endBound + extraSpace) && viewRight > -extraSpace;
}
@Override
public boolean hasNewBecomeVisible(DiscreteScrollLayoutManager lm) {
View firstChild = lm.getFirstChild(), lastChild = lm.getLastChild();
int leftBound = -lm.getExtraLayoutSpace();
int rightBound = lm.getWidth() + lm.getExtraLayoutSpace();
boolean isNewVisibleFromLeft = lm.getDecoratedLeft(firstChild) > leftBound
&& lm.getPosition(firstChild) > 0;
boolean isNewVisibleFromRight = lm.getDecoratedRight(lastChild) < rightBound
&& lm.getPosition(lastChild) < lm.getItemCount() - 1;
return isNewVisibleFromLeft || isNewVisibleFromRight;
}
@Override
public void offsetChildren(int amount, RecyclerViewProxy helper) {
helper.offsetChildrenHorizontal(amount);
}
@Override
public float getDistanceFromCenter(Point center, int viewCenterX, int viewCenterY) {
return viewCenterX - center.x;
}
@Override
public int getFlingVelocity(int velocityX, int velocityY) {
return velocityX;
}
@Override
public boolean canScrollHorizontally() {
return true;
}
@Override
public boolean canScrollVertically() {
return false;
}
@Override
public int getPendingDx(int pendingScroll) {
return pendingScroll;
}
@Override
public int getPendingDy(int pendingScroll) {
return 0;
}
}
protected static class VerticalHelper implements Helper {
@Override
public int getViewEnd(int recyclerWidth, int recyclerHeight) {
return recyclerHeight;
}
@Override
public int getDistanceToChangeCurrent(int childWidth, int childHeight) {
return childHeight;
}
@Override
public void setCurrentViewCenter(Point recyclerCenter, int scrolled, Point outPoint) {
int newY = recyclerCenter.y - scrolled;
outPoint.set(recyclerCenter.x, newY);
}
@Override
public void shiftViewCenter(Direction direction, int shiftAmount, Point outCenter) {
int newY = outCenter.y + direction.applyTo(shiftAmount);
outCenter.set(outCenter.x, newY);
}
@Override
public void offsetChildren(int amount, RecyclerViewProxy helper) {
helper.offsetChildrenVertical(amount);
}
@Override
public float getDistanceFromCenter(Point center, int viewCenterX, int viewCenterY) {
return viewCenterY - center.y;
}
@Override
public boolean isViewVisible(
Point viewCenter, int halfWidth, int halfHeight, int endBound,
int extraSpace) {
int viewTop = viewCenter.y - halfHeight;
int viewBottom = viewCenter.y + halfHeight;
return viewTop < (endBound + extraSpace) && viewBottom > -extraSpace;
}
@Override
public boolean hasNewBecomeVisible(DiscreteScrollLayoutManager lm) {
View firstChild = lm.getFirstChild(), lastChild = lm.getLastChild();
int topBound = -lm.getExtraLayoutSpace();
int bottomBound = lm.getHeight() + lm.getExtraLayoutSpace();
boolean isNewVisibleFromTop = lm.getDecoratedTop(firstChild) > topBound
&& lm.getPosition(firstChild) > 0;
boolean isNewVisibleFromBottom = lm.getDecoratedBottom(lastChild) < bottomBound
&& lm.getPosition(lastChild) < lm.getItemCount() - 1;
return isNewVisibleFromTop || isNewVisibleFromBottom;
}
@Override
public int getFlingVelocity(int velocityX, int velocityY) {
return velocityY;
}
@Override
public boolean canScrollHorizontally() {
return false;
}
@Override
public boolean canScrollVertically() {
return true;
}
@Override
public int getPendingDx(int pendingScroll) {
return 0;
}
@Override
public int getPendingDy(int pendingScroll) {
return pendingScroll;
}
}
}

View File

@@ -1,38 +0,0 @@
package com.yarolegovich.discretescrollview;
/**
* Created by yarolegovich on 16.03.2017.
*/
enum Direction {
START {
@Override
public int applyTo(int delta) {
return delta * -1;
}
@Override
public boolean sameAs(int direction) {
return direction < 0;
}
},
END {
@Override
public int applyTo(int delta) {
return delta;
}
@Override
public boolean sameAs(int direction) {
return direction > 0;
}
};
public abstract int applyTo(int delta);
public abstract boolean sameAs(int direction);
public static Direction fromDelta(int delta) {
return delta > 0 ? END : START;
}
}

View File

@@ -1,836 +0,0 @@
package com.yarolegovich.discretescrollview;
import android.content.Context;
import android.graphics.Point;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.accessibility.AccessibilityEventCompat;
import androidx.core.view.accessibility.AccessibilityRecordCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.idst.nls.internal.utils.L;
import com.mogo.utils.logger.Logger;
import com.yarolegovich.discretescrollview.transform.DiscreteScrollItemTransformer;
import java.util.Locale;
/**
* Created by yarolegovich on 17.02.2017.
*/
public class DiscreteScrollLayoutManager extends LinearLayoutManager {
static final int NO_POSITION = -1;
private static final String EXTRA_POSITION = "extra_position";
private static final int DEFAULT_TIME_FOR_ITEM_SETTLE = 300;
private static final int DEFAULT_FLING_THRESHOLD = 2100; //Decrease to increase sensitivity.
private static final int DEFAULT_TRANSFORM_CLAMP_ITEM_COUNT = 1;
protected static final float SCROLL_TO_SNAP_TO_ANOTHER_ITEM = 0.6f;
//This field will take value of all visible view's center points during the fill phase
protected Point viewCenterIterator;
protected Point recyclerCenter;
protected Point currentViewCenter;
protected int childHalfWidth, childHalfHeight;
protected int extraLayoutSpace;
//Max possible distance a view can travel during one scroll phase
protected int scrollToChangeCurrent;
protected int currentScrollState;
protected int scrolled;
protected int pendingScroll;
protected int currentPosition;
protected int pendingPosition;
protected SparseArray<View> detachedCache;
private DSVOrientation.Helper orientationHelper;
protected boolean isFirstOrEmptyLayout;
private Context context;
private int timeForItemSettle;
private int offscreenItems;
private int transformClampItemCount;
private boolean dataSetChangeShiftedPosition;
private int flingThreshold;
private boolean shouldSlideOnFling;
private int viewWidth, viewHeight;
private float ratio=0.5F;
private static final String TAG = "DiscreteScrollLayoutMan";
@NonNull
private final ScrollStateListener scrollStateListener;
private DiscreteScrollItemTransformer itemTransformer;
private RecyclerViewProxy recyclerViewProxy;
public DiscreteScrollLayoutManager(
@NonNull Context c,
@NonNull ScrollStateListener scrollStateListener,
@NonNull DSVOrientation orientation) {
super(c);
this.context = c;
this.timeForItemSettle = DEFAULT_TIME_FOR_ITEM_SETTLE;
this.pendingPosition = NO_POSITION;
this.currentPosition = NO_POSITION;
this.flingThreshold = DEFAULT_FLING_THRESHOLD;
this.shouldSlideOnFling = false;
this.recyclerCenter = new Point();
this.currentViewCenter = new Point();
this.viewCenterIterator = new Point();
this.detachedCache = new SparseArray<>();
this.scrollStateListener = scrollStateListener;
this.orientationHelper = orientation.createHelper();
this.recyclerViewProxy = new RecyclerViewProxy(this);
this.transformClampItemCount = DEFAULT_TRANSFORM_CLAMP_ITEM_COUNT;
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (state.getItemCount() == 0) {
recyclerViewProxy.removeAndRecycleAllViews(recycler);
currentPosition = pendingPosition = NO_POSITION;
scrolled = pendingScroll = 0;
return;
}
ensureValidPosition(state);
updateRecyclerDimensions(state);
//onLayoutChildren may be called multiple times and this check is required so that the flag
//won't be cleared until onLayoutCompleted
if (!isFirstOrEmptyLayout) {
isFirstOrEmptyLayout = recyclerViewProxy.getChildCount() == 0;
if (isFirstOrEmptyLayout) {
initChildDimensions(recycler);
}
}
recyclerViewProxy.detachAndScrapAttachedViews(recycler);
fill(recycler);
applyItemTransformToChildren();
}
private void ensureValidPosition(RecyclerView.State state) {
if (currentPosition == NO_POSITION || currentPosition >= state.getItemCount()) {
//currentPosition might have been assigned in onRestoreInstanceState()
//which can lead to a crash (position out of bounds) when data set
//is not persisted across rotations
currentPosition = 0;
}
}
public void setRatio(float ratio) {
this.ratio = ratio;
}
@Override
public void onLayoutCompleted(RecyclerView.State state) {
if (isFirstOrEmptyLayout) {
scrollStateListener.onCurrentViewFirstLayout();
isFirstOrEmptyLayout = false;
} else if (dataSetChangeShiftedPosition) {
scrollStateListener.onDataSetChangeChangedPosition();
dataSetChangeShiftedPosition = false;
}
}
protected void initChildDimensions(RecyclerView.Recycler recycler) {
View viewToMeasure = recyclerViewProxy.getMeasuredChildForAdapterPosition(0, recycler);
int childViewWidth = recyclerViewProxy.getMeasuredWidthWithMargin(viewToMeasure);
int childViewHeight = recyclerViewProxy.getMeasuredHeightWithMargin(viewToMeasure);
childHalfWidth = childViewWidth / 2;
childHalfHeight = childViewHeight / 2;
scrollToChangeCurrent = orientationHelper.getDistanceToChangeCurrent(
childViewWidth,
childViewHeight);
extraLayoutSpace = scrollToChangeCurrent * offscreenItems;
recyclerViewProxy.detachAndScrapView(viewToMeasure, recycler);
}
protected void updateRecyclerDimensions(RecyclerView.State state) {
boolean dimensionsChanged = !state.isMeasuring()
&& (recyclerViewProxy.getWidth() != viewWidth
|| recyclerViewProxy.getHeight() != viewHeight);
if (dimensionsChanged) {
viewWidth = recyclerViewProxy.getWidth();
viewHeight = recyclerViewProxy.getHeight();
recyclerViewProxy.removeAllViews();
}
recyclerCenter.set(
(int) (recyclerViewProxy.getWidth() * ratio),
recyclerViewProxy.getHeight() / 2);
}
protected void fill(RecyclerView.Recycler recycler) {
cacheAndDetachAttachedViews();
orientationHelper.setCurrentViewCenter(recyclerCenter, scrolled, currentViewCenter);
final int endBound = orientationHelper.getViewEnd(
recyclerViewProxy.getWidth(),
recyclerViewProxy.getHeight());
//Layout current
if (isViewVisible(currentViewCenter, endBound)) {
layoutView(recycler, currentPosition, currentViewCenter);
}
//Layout items before the current item
layoutViews(recycler, Direction.START, endBound);
//Layout items after the current item
layoutViews(recycler, Direction.END, endBound);
recycleDetachedViewsAndClearCache(recycler);
}
private void layoutViews(RecyclerView.Recycler recycler, Direction direction, int endBound) {
final int positionStep = direction.applyTo(1);
//Predictive layout is required when we are doing smooth fast scroll towards pendingPosition
boolean noPredictiveLayoutRequired = pendingPosition == NO_POSITION
|| !direction.sameAs(pendingPosition - currentPosition);
viewCenterIterator.set(currentViewCenter.x, currentViewCenter.y);
for (int pos = currentPosition + positionStep; isInBounds(pos); pos += positionStep) {
if (pos == pendingPosition) {
noPredictiveLayoutRequired = true;
}
orientationHelper.shiftViewCenter(direction, scrollToChangeCurrent, viewCenterIterator);
if (isViewVisible(viewCenterIterator, endBound)) {
layoutView(recycler, pos, viewCenterIterator);
} else if (noPredictiveLayoutRequired) {
break;
}
}
}
protected void layoutView(RecyclerView.Recycler recycler, int position, Point viewCenter) {
if (position < 0) return;
View v = detachedCache.get(position);
if (v == null) {
v = recyclerViewProxy.getMeasuredChildForAdapterPosition(position, recycler);
recyclerViewProxy.layoutDecoratedWithMargins(v,
viewCenter.x - childHalfWidth, viewCenter.y - childHalfHeight,
viewCenter.x + childHalfWidth, viewCenter.y + childHalfHeight);
} else {
recyclerViewProxy.attachView(v);
detachedCache.remove(position);
}
}
protected void cacheAndDetachAttachedViews() {
detachedCache.clear();
for (int i = 0; i < recyclerViewProxy.getChildCount(); i++) {
View child = recyclerViewProxy.getChildAt(i);
detachedCache.put(recyclerViewProxy.getPosition(child), child);
}
for (int i = 0; i < detachedCache.size(); i++) {
recyclerViewProxy.detachView(detachedCache.valueAt(i));
}
}
protected void recycleDetachedViewsAndClearCache(RecyclerView.Recycler recycler) {
for (int i = 0; i < detachedCache.size(); i++) {
View viewToRemove = detachedCache.valueAt(i);
recyclerViewProxy.recycleView(viewToRemove, recycler);
}
detachedCache.clear();
}
@Override
public void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount) {
int newPosition = currentPosition;
if (currentPosition == NO_POSITION) {
newPosition = 0;
} else if (currentPosition >= positionStart) {
newPosition = Math.min(currentPosition + itemCount, recyclerViewProxy.getItemCount() - 1);
}
onNewPosition(newPosition);
}
@Override
public void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount) {
int newPosition = currentPosition;
if (recyclerViewProxy.getItemCount() == 0) {
newPosition = NO_POSITION;
} else if (currentPosition >= positionStart) {
if (currentPosition < positionStart + itemCount) {
//If currentPosition is in the removed items, then the new item became current
currentPosition = NO_POSITION;
}
newPosition = Math.max(0, currentPosition - itemCount);
}
onNewPosition(newPosition);
}
@Override
public void onItemsChanged(RecyclerView recyclerView) {
//notifyDataSetChanged() was called. We need to ensure that currentPosition is not out of bounds
currentPosition = Math.min(Math.max(0, currentPosition), recyclerViewProxy.getItemCount() - 1);
dataSetChangeShiftedPosition = true;
}
private void onNewPosition(int position) {
if (currentPosition != position) {
currentPosition = position;
dataSetChangeShiftedPosition = true;
}
}
@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
return scrollBy(dx, recycler);
}
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
return scrollBy(dy, recycler);
}
protected int scrollBy(int amount, RecyclerView.Recycler recycler) {
if (recyclerViewProxy.getChildCount() == 0) {
return 0;
}
Direction direction = Direction.fromDelta(amount);
int leftToScroll = calculateAllowedScrollIn(direction);
if (leftToScroll <= 0) {
return 0;
}
int delta = direction.applyTo(Math.min(leftToScroll, Math.abs(amount)));
Logger.d(TAG,"leftToScroll--》"+leftToScroll+"---amount--》"+amount);
scrolled += delta;
if (pendingScroll != 0) {
pendingScroll -= delta;
}
orientationHelper.offsetChildren(-delta, recyclerViewProxy);
if (orientationHelper.hasNewBecomeVisible(this)) {
fill(recycler);
}
notifyScroll();
applyItemTransformToChildren();
return delta;
}
protected void applyItemTransformToChildren() {
if (itemTransformer != null) {
int clampAfterDistance = scrollToChangeCurrent * transformClampItemCount;
for (int i = 0; i < recyclerViewProxy.getChildCount(); i++) {
View child = recyclerViewProxy.getChildAt(i);
//RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(child);
float position = getCenterRelativePositionOf(child, clampAfterDistance);
itemTransformer.transformItem(child,null, position);
}
}
}
@Override
public void scrollToPosition(int position) {
if (currentPosition == position) {
return;
}
currentPosition = position;
recyclerViewProxy.requestLayout();
}
//@Override
//public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
// if (currentPosition == position || pendingPosition != NO_POSITION) {
// return;
// }
// checkTargetPosition(state, position);
// if (currentPosition == NO_POSITION) {
// //Layout not happened yet
// currentPosition = position;
// } else {
// startSmoothPendingScroll(position);
// }
//}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller smoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
// 返回滑过1px时经历的时间(ms)。
return 10f / displayMetrics.densityDpi;
}
@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
return boxStart - viewStart;
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
@Override
public boolean canScrollHorizontally() {
return orientationHelper.canScrollHorizontally();
}
@Override
public boolean canScrollVertically() {
return orientationHelper.canScrollVertically();
}
@Override
public void onScrollStateChanged(int state) {
if (currentScrollState == RecyclerView.SCROLL_STATE_IDLE && currentScrollState != state) {
scrollStateListener.onScrollStart();
}
if (state == RecyclerView.SCROLL_STATE_IDLE) {
//Scroll is not finished until current view is centered
boolean isScrollEnded = onScrollEnd();
if (isScrollEnded) {
scrollStateListener.onScrollEnd();
} else {
//Scroll continues and we don't want to set currentScrollState to STATE_IDLE,
//because this will then trigger .scrollStateListener.onScrollStart()
return;
}
} else if (state == RecyclerView.SCROLL_STATE_DRAGGING) {
onDragStart();
}
currentScrollState = state;
}
/**
* @return true if scroll is ended and we don't need to settle items
*/
private boolean onScrollEnd() {
if (pendingPosition != NO_POSITION) {
currentPosition = pendingPosition;
pendingPosition = NO_POSITION;
scrolled = 0;
}
Direction scrollDirection = Direction.fromDelta(scrolled);
if (Math.abs(scrolled) == scrollToChangeCurrent) {
currentPosition += scrollDirection.applyTo(1);
scrolled = 0;
}
if (isAnotherItemCloserThanCurrent()) {
pendingScroll = getHowMuchIsLeftToScroll(scrolled);
} else {
pendingScroll = -scrolled;
}
if (pendingScroll == 0) {
return true;
} else {
startSmoothPendingScroll();
return false;
}
}
private void onDragStart() {
//Here we need to:
//1. Stop any pending scroll
//2. Set currentPosition to position of the item that is closest to the center
boolean isScrollingThroughMultiplePositions = Math.abs(scrolled) > scrollToChangeCurrent;
if (isScrollingThroughMultiplePositions) {
int scrolledPositions = scrolled / scrollToChangeCurrent;
currentPosition += scrolledPositions;
scrolled -= scrolledPositions * scrollToChangeCurrent;
}
if (isAnotherItemCloserThanCurrent()) {
Direction direction = Direction.fromDelta(scrolled);
currentPosition += direction.applyTo(1);
scrolled = -getHowMuchIsLeftToScroll(scrolled);
}
pendingPosition = NO_POSITION;
pendingScroll = 0;
}
public void onFling(int velocityX, int velocityY) {
int velocity = orientationHelper.getFlingVelocity(velocityX, velocityY);
int throttleValue = shouldSlideOnFling ? Math.abs(velocity / flingThreshold) : 1;
int newPosition = currentPosition + Direction.fromDelta(velocity).applyTo(throttleValue);
newPosition = checkNewOnFlingPositionIsInBounds(newPosition);
boolean isInScrollDirection = velocity * scrolled >= 0;
boolean canFling = isInScrollDirection && isInBounds(newPosition);
if (canFling) {
startSmoothPendingScroll(newPosition);
} else {
returnToCurrentPosition();
}
Logger.d(TAG,"onFling"+newPosition);
}
public void returnToCurrentPosition() {
pendingScroll = -scrolled;
if (pendingScroll != 0) {
startSmoothPendingScroll();
}
}
protected int calculateAllowedScrollIn(Direction direction) {
if (pendingScroll != 0) {
return Math.abs(pendingScroll);
}
int allowedScroll;
boolean isBoundReached;
boolean isScrollDirectionAsBefore = direction.applyTo(scrolled) > 0;
if (direction == Direction.START && currentPosition == 0) {
//We can scroll to the left when currentPosition == 0 only if we scrolled to the right before
isBoundReached = scrolled == 0;
allowedScroll = isBoundReached ? 0 : Math.abs(scrolled);
} else if (direction == Direction.END && currentPosition == recyclerViewProxy.getItemCount() - 1) {
//We can scroll to the right when currentPosition == last only if we scrolled to the left before
isBoundReached = scrolled == 0;
allowedScroll = isBoundReached ? 0 : Math.abs(scrolled);
} else {
isBoundReached = false;
allowedScroll = isScrollDirectionAsBefore ?
scrollToChangeCurrent - Math.abs(scrolled) :
scrollToChangeCurrent + Math.abs(scrolled);
}
scrollStateListener.onIsBoundReachedFlagChange(isBoundReached);
return allowedScroll;
}
private void startSmoothPendingScroll() {
LinearSmoothScroller scroller = new DiscreteLinearSmoothScroller(context);
scroller.setTargetPosition(currentPosition);
recyclerViewProxy.startSmoothScroll(scroller);
}
public void startSmoothPendingScroll(int position) {
if (currentPosition == position) return;
pendingScroll = -scrolled;
Direction direction = Direction.fromDelta(position - currentPosition);
int distanceToScroll = Math.abs(position - currentPosition) * scrollToChangeCurrent;
pendingScroll += direction.applyTo(distanceToScroll);
pendingPosition = position;
startSmoothPendingScroll();
}
@Override
public boolean isAutoMeasureEnabled() {
return true;
}
@Override
public int computeVerticalScrollRange(RecyclerView.State state) {
return computeScrollRange(state);
}
@Override
public int computeVerticalScrollOffset(RecyclerView.State state) {
return computeScrollOffset(state);
}
@Override
public int computeVerticalScrollExtent(RecyclerView.State state) {
return computeScrollExtent(state);
}
@Override
public int computeHorizontalScrollRange(RecyclerView.State state) {
return computeScrollRange(state);
}
@Override
public int computeHorizontalScrollOffset(RecyclerView.State state) {
return computeScrollOffset(state);
}
@Override
public int computeHorizontalScrollExtent(RecyclerView.State state) {
return computeScrollExtent(state);
}
private int computeScrollOffset(RecyclerView.State state) {
int scrollbarSize = computeScrollExtent(state);
int offset = (int) ((scrolled / (float) scrollToChangeCurrent) * scrollbarSize);
return (currentPosition * scrollbarSize) + offset;
}
private int computeScrollExtent(RecyclerView.State state) {
if (getItemCount() == 0) {
return 0;
} else {
return (int) (computeScrollRange(state) / (float) getItemCount());
}
}
private int computeScrollRange(RecyclerView.State state) {
if (getItemCount() == 0) {
return 0;
} else {
return scrollToChangeCurrent * (getItemCount() - 1);
}
}
@Override
public void onAdapterChanged(RecyclerView.Adapter oldAdapter, RecyclerView.Adapter newAdapter) {
pendingPosition = NO_POSITION;
scrolled = pendingScroll = 0;
if (newAdapter instanceof InitialPositionProvider) {
currentPosition = ((InitialPositionProvider) newAdapter).getInitialPosition();
} else {
currentPosition = 0;
}
recyclerViewProxy.removeAllViews();
}
@Override
public Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
if (pendingPosition != NO_POSITION) {
currentPosition = pendingPosition;
}
bundle.putInt(EXTRA_POSITION, currentPosition);
return bundle;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
Bundle bundle = (Bundle) state;
currentPosition = bundle.getInt(EXTRA_POSITION);
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
public int getNextPosition() {
if (scrolled == 0) {
return currentPosition;
} else if (pendingPosition != NO_POSITION) {
return pendingPosition;
} else {
return currentPosition + Direction.fromDelta(scrolled).applyTo(1);
}
}
public void setItemTransformer(DiscreteScrollItemTransformer itemTransformer) {
this.itemTransformer = itemTransformer;
}
public void setTimeForItemSettle(int timeForItemSettle) {
this.timeForItemSettle = timeForItemSettle;
}
public void setOffscreenItems(int offscreenItems) {
this.offscreenItems = offscreenItems;
extraLayoutSpace = scrollToChangeCurrent * offscreenItems;
recyclerViewProxy.requestLayout();
}
public void setTransformClampItemCount(int transformClampItemCount) {
this.transformClampItemCount = transformClampItemCount;
applyItemTransformToChildren();
}
public void setOrientation(DSVOrientation orientation) {
orientationHelper = orientation.createHelper();
recyclerViewProxy.removeAllViews();
recyclerViewProxy.requestLayout();
}
public void setShouldSlideOnFling(boolean result) {
shouldSlideOnFling = result;
}
public void setSlideOnFlingThreshold(int threshold) {
flingThreshold = threshold;
}
public int getCurrentPosition() {
return currentPosition;
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
if (recyclerViewProxy.getChildCount() > 0) {
final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
record.setFromIndex(getPosition(getFirstChild()));
record.setToIndex(getPosition(getLastChild()));
}
}
private float getCenterRelativePositionOf(View v, int maxDistance) {
float distanceFromCenter = orientationHelper.getDistanceFromCenter(recyclerCenter,
getDecoratedLeft(v) + childHalfWidth,
getDecoratedTop(v) + childHalfHeight);
return Math.min(Math.max(-1f, distanceFromCenter / maxDistance), 1f);
}
private int checkNewOnFlingPositionIsInBounds(int position) {
final int itemCount = recyclerViewProxy.getItemCount();
//The check is required in case slide through multiple items is turned on
if (currentPosition != 0 && position < 0) {
//If currentPosition == 0 && position < 0 we forbid scroll to the left,
//but if currentPosition != 0 we can slide to the first item
return 0;
} else if (currentPosition != itemCount - 1 && position >= itemCount) {
return itemCount - 1;
}
return position;
}
private int getHowMuchIsLeftToScroll(int dx) {
return Direction.fromDelta(dx).applyTo(scrollToChangeCurrent - Math.abs(scrolled));
}
private boolean isAnotherItemCloserThanCurrent() {
return Math.abs(scrolled) >= scrollToChangeCurrent * SCROLL_TO_SNAP_TO_ANOTHER_ITEM;
}
public View getFirstChild() {
return recyclerViewProxy.getChildAt(0);
}
public View getLastChild() {
return recyclerViewProxy.getChildAt(recyclerViewProxy.getChildCount() - 1);
}
public int getExtraLayoutSpace() {
return extraLayoutSpace;
}
private void notifyScroll() {
float amountToScroll = pendingPosition != NO_POSITION ?
Math.abs(scrolled + pendingScroll) :
scrollToChangeCurrent;
float position = -Math.min(Math.max(-1f, scrolled / amountToScroll), 1f);
scrollStateListener.onScroll(position);
}
private boolean isInBounds(int itemPosition) {
return itemPosition >= 0 && itemPosition < recyclerViewProxy.getItemCount();
}
private boolean isViewVisible(Point viewCenter, int endBound) {
return orientationHelper.isViewVisible(
viewCenter, childHalfWidth, childHalfHeight,
endBound, extraLayoutSpace);
}
public void setPendingScroll(int pendingScroll){
this.pendingScroll=pendingScroll;
}
private void checkTargetPosition(RecyclerView.State state, int targetPosition) {
if (targetPosition < 0 || targetPosition >= state.getItemCount()) {
throw new IllegalArgumentException(String.format(Locale.US,
"target position out of bounds: position=%d, itemCount=%d",
targetPosition, state.getItemCount()));
}
}
protected void setRecyclerViewProxy(RecyclerViewProxy recyclerViewProxy) {
this.recyclerViewProxy = recyclerViewProxy;
}
protected void setOrientationHelper(DSVOrientation.Helper orientationHelper) {
this.orientationHelper = orientationHelper;
}
private class DiscreteLinearSmoothScroller extends LinearSmoothScroller {
public DiscreteLinearSmoothScroller(Context context) {
super(context);
}
@Override
public int calculateDxToMakeVisible(View view, int snapPreference) {
return orientationHelper.getPendingDx(-pendingScroll);
}
@Override
public int calculateDyToMakeVisible(View view, int snapPreference) {
return orientationHelper.getPendingDy(-pendingScroll);
}
@Override
protected int calculateTimeForScrolling(int dx) {
float dist = Math.min(Math.abs(dx), scrollToChangeCurrent);
return (int) (Math.max(0.01f, dist / scrollToChangeCurrent) * timeForItemSettle);
}
@Nullable
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return new PointF(
orientationHelper.getPendingDx(pendingScroll),
orientationHelper.getPendingDy(pendingScroll));
}
@Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return 10f / displayMetrics.densityDpi;
}
}
public interface ScrollStateListener {
void onIsBoundReachedFlagChange(boolean isBoundReached);
void onScrollStart();
void onScrollEnd();
void onScroll(float currentViewPosition);
void onCurrentViewFirstLayout();
void onDataSetChangeChangedPosition();
}
public interface InitialPositionProvider {
int getInitialPosition();
}
}

View File

@@ -1,302 +0,0 @@
package com.yarolegovich.discretescrollview;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.module.common.R;
import com.yarolegovich.discretescrollview.transform.DiscreteScrollItemTransformer;
import com.yarolegovich.discretescrollview.util.ScrollListenerAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yarolegovich on 18.02.2017.
*/
@SuppressWarnings("unchecked")
public class DiscreteScrollView extends RecyclerView {
public static final int NO_POSITION = DiscreteScrollLayoutManager.NO_POSITION;
private static final int DEFAULT_ORIENTATION = DSVOrientation.HORIZONTAL.ordinal();
private DiscreteScrollLayoutManager layoutManager;
private List<ScrollStateChangeListener> scrollStateChangeListeners;
private List<OnItemChangedListener> onItemChangedListeners;
private boolean isOverScrollEnabled;
public DiscreteScrollView(Context context) {
super(context);
init(null);
}
public DiscreteScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public DiscreteScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs) {
scrollStateChangeListeners = new ArrayList<>();
onItemChangedListeners = new ArrayList<>();
int orientation = DEFAULT_ORIENTATION;
if (attrs != null) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.DiscreteScrollView);
orientation = ta.getInt(R.styleable.DiscreteScrollView_dsv_orientation, DEFAULT_ORIENTATION);
ta.recycle();
}
isOverScrollEnabled = getOverScrollMode() != OVER_SCROLL_NEVER;
layoutManager = new DiscreteScrollLayoutManager(
getContext(), new ScrollStateListener(),
DSVOrientation.values()[orientation]);
setLayoutManager(layoutManager);
}
public void setRatio(float ratio){
layoutManager.setRatio(ratio);
}
@Override
public void setLayoutManager(LayoutManager layout) {
if (layout instanceof DiscreteScrollLayoutManager) {
super.setLayoutManager(layout);
} else {
throw new IllegalArgumentException(getContext().getString(R.string.dsv_ex_msg_dont_set_lm));
}
}
@Override
public boolean fling(int velocityX, int velocityY) {
boolean isFling = super.fling(velocityX, velocityY);
if (isFling) {
layoutManager.onFling(velocityX, velocityY);
} else {
layoutManager.returnToCurrentPosition();
}
return isFling;
}
@Nullable
public ViewHolder getViewHolder(int position) {
View view = layoutManager.findViewByPosition(position);
return view != null ? getChildViewHolder(view) : null;
}
/**
* @return adapter position of the current item or -1 if nothing is selected
*/
public int getCurrentItem() {
return layoutManager.getCurrentPosition();
}
public void setItemTransformer(DiscreteScrollItemTransformer transformer) {
layoutManager.setItemTransformer(transformer);
}
public void setItemTransitionTimeMillis(@IntRange(from = 10) int millis) {
layoutManager.setTimeForItemSettle(millis);
}
public void setSlideOnFling(boolean result){
layoutManager.setShouldSlideOnFling(result);
}
public void setSlideOnFlingThreshold(int threshold){
layoutManager.setSlideOnFlingThreshold(threshold);
}
public void setOrientation(DSVOrientation orientation) {
layoutManager.setOrientation(orientation);
}
public void setOffscreenItems(int items) {
layoutManager.setOffscreenItems(items);
}
public void setClampTransformProgressAfter(@IntRange(from = 1) int itemCount) {
if (itemCount <= 1) {
throw new IllegalArgumentException("must be >= 1");
}
layoutManager.setTransformClampItemCount(itemCount);
}
public void setOverScrollEnabled(boolean overScrollEnabled) {
isOverScrollEnabled = overScrollEnabled;
setOverScrollMode(OVER_SCROLL_NEVER);
}
public void addScrollStateChangeListener(@NonNull ScrollStateChangeListener<?> scrollStateChangeListener) {
scrollStateChangeListeners.add(scrollStateChangeListener);
}
public void addScrollListener(@NonNull ScrollListener<?> scrollListener) {
addScrollStateChangeListener(new ScrollListenerAdapter(scrollListener));
}
public void addOnItemChangedListener(@NonNull OnItemChangedListener<?> onItemChangedListener) {
onItemChangedListeners.add(onItemChangedListener);
}
public void removeScrollStateChangeListener(@NonNull ScrollStateChangeListener<?> scrollStateChangeListener) {
scrollStateChangeListeners.remove(scrollStateChangeListener);
}
public void removeScrollListener(@NonNull ScrollListener<?> scrollListener) {
removeScrollStateChangeListener(new ScrollListenerAdapter<>(scrollListener));
}
public void removeItemChangedListener(@NonNull OnItemChangedListener<?> onItemChangedListener) {
onItemChangedListeners.remove(onItemChangedListener);
}
private void notifyScrollStart(ViewHolder holder, int current) {
for (ScrollStateChangeListener listener : scrollStateChangeListeners) {
listener.onScrollStart(holder, current);
}
}
private void notifyScrollEnd(ViewHolder holder, int current) {
for (ScrollStateChangeListener listener : scrollStateChangeListeners) {
listener.onScrollEnd(holder, current);
}
}
private void notifyScroll(float position,
int currentIndex, int newIndex,
ViewHolder currentHolder, ViewHolder newHolder) {
for (ScrollStateChangeListener listener : scrollStateChangeListeners) {
listener.onScroll(position, currentIndex, newIndex,
currentHolder,
newHolder);
}
}
private void notifyCurrentItemChanged(ViewHolder holder, int current) {
for (OnItemChangedListener listener : onItemChangedListeners) {
listener.onCurrentItemChanged(holder, current);
}
}
private void notifyCurrentItemChanged() {
if (onItemChangedListeners.isEmpty()) {
return;
}
int current = layoutManager.getCurrentPosition();
ViewHolder currentHolder = getViewHolder(current);
notifyCurrentItemChanged(currentHolder, current);
}
public void setPendingScroll(int PendingScroll ) {
layoutManager.setPendingScroll(PendingScroll);
}
private class ScrollStateListener implements DiscreteScrollLayoutManager.ScrollStateListener {
@Override
public void onIsBoundReachedFlagChange(boolean isBoundReached) {
if (isOverScrollEnabled) {
setOverScrollMode(isBoundReached ? OVER_SCROLL_ALWAYS : OVER_SCROLL_NEVER);
}
}
@Override
public void onScrollStart() {
if (scrollStateChangeListeners.isEmpty()) {
return;
}
int current = layoutManager.getCurrentPosition();
ViewHolder holder = getViewHolder(current);
if (holder != null) {
notifyScrollStart(holder, current);
}
}
@Override
public void onScrollEnd() {
if (onItemChangedListeners.isEmpty() && scrollStateChangeListeners.isEmpty()) {
return;
}
int current = layoutManager.getCurrentPosition();
ViewHolder holder = getViewHolder(current);
if (holder != null) {
notifyScrollEnd(holder, current);
notifyCurrentItemChanged(holder, current);
}
}
@Override
public void onScroll(float currentViewPosition) {
if (scrollStateChangeListeners.isEmpty()) {
return;
}
int currentIndex = getCurrentItem();
int newIndex = layoutManager.getNextPosition();
if (currentIndex != newIndex) {
notifyScroll(currentViewPosition,
currentIndex, newIndex,
getViewHolder(currentIndex),
getViewHolder(newIndex));
}
}
@Override
public void onCurrentViewFirstLayout() {
post(new Runnable() {
@Override
public void run() {
notifyCurrentItemChanged();
}
});
}
@Override
public void onDataSetChangeChangedPosition() {
notifyCurrentItemChanged();
}
}
public interface ScrollStateChangeListener<T extends ViewHolder> {
void onScrollStart(@NonNull T currentItemHolder, int adapterPosition);
void onScrollEnd(@NonNull T currentItemHolder, int adapterPosition);
void onScroll(float scrollPosition,
int currentPosition,
int newPosition,
@Nullable T currentHolder,
@Nullable T newCurrent);
}
public interface ScrollListener<T extends ViewHolder> {
void onScroll(float scrollPosition,
int currentPosition, int newPosition,
@Nullable T currentHolder,
@Nullable T newCurrent);
}
public interface OnItemChangedListener<T extends ViewHolder> {
/*
* This method will be also triggered when view appears on the screen for the first time.
* If data set is empty, viewHolder will be null and adapterPosition will be NO_POSITION
*/
void onCurrentItemChanged(@Nullable T viewHolder, int adapterPosition);
}
}

View File

@@ -1,179 +0,0 @@
package com.yarolegovich.discretescrollview;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.module.common.R;
import java.util.Locale;
/**
* Created by yarolegovich on 28-Apr-17.
*/
public class InfiniteScrollAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T>
implements DiscreteScrollLayoutManager.InitialPositionProvider {
private static final int CENTER = Integer.MAX_VALUE / 2;
private static final int RESET_BOUND = 100;
public static <T extends RecyclerView.ViewHolder> InfiniteScrollAdapter<T> wrap(
@NonNull RecyclerView.Adapter<T> adapter) {
return new InfiniteScrollAdapter<>(adapter);
}
private RecyclerView.Adapter<T> wrapped;
private DiscreteScrollLayoutManager layoutManager;
public InfiniteScrollAdapter(@NonNull RecyclerView.Adapter<T> wrapped) {
this.wrapped = wrapped;
this.wrapped.registerAdapterDataObserver(new DataSetChangeDelegate());
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
wrapped.onAttachedToRecyclerView(recyclerView);
if (recyclerView instanceof DiscreteScrollView) {
layoutManager = (DiscreteScrollLayoutManager) recyclerView.getLayoutManager();
} else {
String msg = recyclerView.getContext().getString(R.string.dsv_ex_msg_adapter_wrong_recycler);
throw new RuntimeException(msg);
}
}
@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
wrapped.onDetachedFromRecyclerView(recyclerView);
layoutManager = null;
}
@Override
public @NonNull T onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return wrapped.onCreateViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(@NonNull T holder, int position) {
if (isResetRequired(position)) {
int resetPosition = CENTER + mapPositionToReal(layoutManager.getCurrentPosition());
setPosition(resetPosition);
return;
}
wrapped.onBindViewHolder(holder, mapPositionToReal(position));
}
@Override
public int getItemViewType(int position) {
return wrapped.getItemViewType(mapPositionToReal(position));
}
@Override
public int getItemCount() {
return isInfinite() ? Integer.MAX_VALUE : wrapped.getItemCount();
}
public int getRealItemCount() {
return wrapped.getItemCount();
}
public int getRealCurrentPosition() {
return getRealPosition(layoutManager.getCurrentPosition());
}
public int getRealPosition(int position) {
return mapPositionToReal(position);
}
public int getClosestPosition(int position) {
ensureValidPosition(position);
int adapterCurrent = layoutManager.getCurrentPosition();
int current = mapPositionToReal(adapterCurrent);
if (position == current) {
return adapterCurrent;
}
int delta = position - current;
int target = adapterCurrent + delta;
int wraparoundTarget = adapterCurrent + (position > current ?
delta - wrapped.getItemCount() :
wrapped.getItemCount() + delta);
int distance = Math.abs(adapterCurrent - target);
int wraparoundDistance = Math.abs(adapterCurrent - wraparoundTarget);
if (distance == wraparoundDistance) {
//Scroll to the right feels more natural, so prefer it
return target > adapterCurrent ? target : wraparoundTarget;
} else {
return distance < wraparoundDistance ? target : wraparoundTarget;
}
}
private int mapPositionToReal(int position) {
if (position < CENTER) {
int rem = (CENTER - position) % wrapped.getItemCount();
return rem == 0 ? 0 : wrapped.getItemCount() - rem;
} else {
return (position - CENTER) % wrapped.getItemCount();
}
}
private boolean isResetRequired(int requestedPosition) {
return isInfinite()
&& (requestedPosition <= RESET_BOUND
|| requestedPosition >= (Integer.MAX_VALUE - RESET_BOUND));
}
private void ensureValidPosition(int position) {
if (position >= wrapped.getItemCount()) {
throw new IndexOutOfBoundsException(String.format(Locale.US,
"requested position is outside adapter's bounds: position=%d, size=%d",
position, wrapped.getItemCount()));
}
}
private boolean isInfinite() {
return wrapped.getItemCount() > 1;
}
@Override
public int getInitialPosition() {
return isInfinite() ? CENTER : 0;
}
private void setPosition(int position) {
layoutManager.scrollToPosition(position);
}
//TODO: handle proper data set change notifications
private class DataSetChangeDelegate extends RecyclerView.AdapterDataObserver {
@Override
public void onChanged() {
setPosition(getInitialPosition());
notifyDataSetChanged();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
onChanged();
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
onChanged();
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
onChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
notifyItemRangeChanged(0, getItemCount());
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
notifyItemRangeChanged(0, getItemCount(), payload);
}
}
}

View File

@@ -1,107 +0,0 @@
package com.yarolegovich.discretescrollview;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created by yarolegovich on 10/25/17.
*/
public class RecyclerViewProxy {
private RecyclerView.LayoutManager layoutManager;
public RecyclerViewProxy(@NonNull RecyclerView.LayoutManager layoutManager) {
this.layoutManager = layoutManager;
}
public void attachView(View view) {
layoutManager.attachView(view);
}
public void detachView(View view) {
layoutManager.detachView(view);
}
public void detachAndScrapView(View view, RecyclerView.Recycler recycler) {
layoutManager.detachAndScrapView(view, recycler);
}
public void detachAndScrapAttachedViews(RecyclerView.Recycler recycler) {
layoutManager.detachAndScrapAttachedViews(recycler);
}
public void recycleView(View view, RecyclerView.Recycler recycler) {
recycler.recycleView(view);
}
public void removeAndRecycleAllViews(RecyclerView.Recycler recycler) {
layoutManager.removeAndRecycleAllViews(recycler);
}
public int getChildCount() {
return layoutManager.getChildCount();
}
public int getItemCount() {
return layoutManager.getItemCount();
}
public View getMeasuredChildForAdapterPosition(int position, RecyclerView.Recycler recycler) {
View view = recycler.getViewForPosition(position);
layoutManager.addView(view);
layoutManager.measureChildWithMargins(view, 0, 0);
return view;
}
public void layoutDecoratedWithMargins(View v, int left, int top, int right, int bottom) {
layoutManager.layoutDecoratedWithMargins(v, left, top, right, bottom);
}
public View getChildAt(int index) {
return layoutManager.getChildAt(index);
}
public int getPosition(View view) {
return layoutManager.getPosition(view);
}
public int getMeasuredWidthWithMargin(View child) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) child.getLayoutParams();
return layoutManager.getDecoratedMeasuredWidth(child) + lp.leftMargin + lp.rightMargin;
}
public int getMeasuredHeightWithMargin(View child) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) child.getLayoutParams();
return layoutManager.getDecoratedMeasuredHeight(child) + lp.topMargin + lp.bottomMargin;
}
public int getWidth() {
return layoutManager.getWidth();
}
public int getHeight() {
return layoutManager.getHeight();
}
public void offsetChildrenHorizontal(int amount) {
layoutManager.offsetChildrenHorizontal(amount);
}
public void offsetChildrenVertical(int amount) {
layoutManager.offsetChildrenVertical(amount);
}
public void requestLayout() {
layoutManager.requestLayout();
}
public void startSmoothScroll(RecyclerView.SmoothScroller smoothScroller) {
layoutManager.startSmoothScroll(smoothScroller);
}
public void removeAllViews() {
layoutManager.removeAllViews();
}
}

View File

@@ -1,12 +0,0 @@
package com.yarolegovich.discretescrollview.transform;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created by yarolegovich on 02.03.2017.
*/
public interface DiscreteScrollItemTransformer {
void transformItem(View item, RecyclerView.ViewHolder childViewHolder,float position);
}

View File

@@ -1,116 +0,0 @@
package com.yarolegovich.discretescrollview.transform;
import android.view.View;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Created by yarolegovich on 03.03.2017.
*/
public class Pivot {
public static final int AXIS_X = 0;
public static final int AXIS_Y = 1;
private static final int PIVOT_CENTER = -1;
private static final int PIVOT_MAX = -2;
private int axis;
private int pivotPoint;
public Pivot(@Axis int axis, int pivotPoint) {
this.axis = axis;
this.pivotPoint = pivotPoint;
}
public void setOn(View view) {
if (axis == AXIS_X) {
switch (pivotPoint) {
case PIVOT_CENTER:
view.setPivotX(view.getWidth() * 0.5f);
break;
case PIVOT_MAX:
view.setPivotX(view.getWidth());
break;
default:
view.setPivotX(pivotPoint);
break;
}
return;
}
if (axis == AXIS_Y) {
switch (pivotPoint) {
case PIVOT_CENTER:
view.setPivotY(view.getHeight() * 0.5f);
break;
case PIVOT_MAX:
view.setPivotY(view.getHeight());
break;
default:
view.setPivotY(pivotPoint);
break;
}
}
}
@Axis
public int getAxis() {
return axis;
}
public enum X {
LEFT {
@Override
public Pivot create() {
return new Pivot(AXIS_X, 0);
}
},
CENTER {
@Override
public Pivot create() {
return new Pivot(AXIS_X, PIVOT_CENTER);
}
},
RIGHT {
@Override
public Pivot create() {
return new Pivot(AXIS_X, PIVOT_MAX);
}
};
public abstract Pivot create();
}
public enum Y {
TOP {
@Override
public Pivot create() {
return new Pivot(AXIS_Y, 0);
}
},
CENTER {
@Override
public Pivot create() {
return new Pivot(AXIS_Y, PIVOT_CENTER);
}
},
BOTTOM {
@Override
public Pivot create() {
return new Pivot(AXIS_Y, PIVOT_MAX);
}
};
public abstract Pivot create();
}
@IntDef({AXIS_X, AXIS_Y})
@Retention(RetentionPolicy.SOURCE)
public @interface Axis{
}
}

View File

@@ -1,85 +0,0 @@
package com.yarolegovich.discretescrollview.transform;
import android.view.View;
import androidx.annotation.FloatRange;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created by yarolegovich on 03.03.2017.
*/
public class ScaleTransformer implements DiscreteScrollItemTransformer {
private Pivot pivotX;
private Pivot pivotY;
private float minScale;
private float maxMinDiff;
public ScaleTransformer() {
pivotX = Pivot.X.CENTER.create();
pivotY = Pivot.Y.CENTER.create();
minScale = 0.8f;
maxMinDiff = 0.2f;
}
@Override
public void transformItem(View item, RecyclerView.ViewHolder childViewHolder, float position) {
pivotX.setOn(item);
pivotY.setOn(item);
float closenessToCenter = 1f - Math.abs(position);
float scale = minScale + maxMinDiff * closenessToCenter;
item.setScaleX(scale);
item.setScaleY(scale);
}
public static class Builder {
private ScaleTransformer transformer;
private float maxScale;
public Builder() {
transformer = new ScaleTransformer();
maxScale = 1f;
}
public Builder setMinScale(@FloatRange(from = 0.01) float scale) {
transformer.minScale = scale;
return this;
}
public Builder setMaxScale(@FloatRange(from = 0.01) float scale) {
maxScale = scale;
return this;
}
public Builder setPivotX(Pivot.X pivotX) {
return setPivotX(pivotX.create());
}
public Builder setPivotX(Pivot pivot) {
assertAxis(pivot, Pivot.AXIS_X);
transformer.pivotX = pivot;
return this;
}
public Builder setPivotY(Pivot.Y pivotY) {
return setPivotY(pivotY.create());
}
public Builder setPivotY(Pivot pivot) {
assertAxis(pivot, Pivot.AXIS_Y);
transformer.pivotY = pivot;
return this;
}
public ScaleTransformer build() {
transformer.maxMinDiff = maxScale - transformer.minScale;
return transformer;
}
private void assertAxis(Pivot pivot, @Pivot.Axis int axis) {
if (pivot.getAxis() != axis) {
throw new IllegalArgumentException("You passed a Pivot for wrong axis.");
}
}
}
}

View File

@@ -1,45 +0,0 @@
package com.yarolegovich.discretescrollview.util;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.yarolegovich.discretescrollview.DiscreteScrollView;
/**
* Created by yarolegovich on 16.03.2017.
*/
public class ScrollListenerAdapter<T extends RecyclerView.ViewHolder> implements DiscreteScrollView.ScrollStateChangeListener<T> {
private DiscreteScrollView.ScrollListener<T> adaptee;
public ScrollListenerAdapter(@NonNull DiscreteScrollView.ScrollListener<T> adaptee) {
this.adaptee = adaptee;
}
@Override
public void onScrollStart(@NonNull T currentItemHolder, int adapterPosition) {
}
@Override
public void onScrollEnd(@NonNull T currentItemHolder, int adapterPosition) {
}
@Override
public void onScroll(float scrollPosition,
int currentIndex, int newIndex,
@Nullable T currentHolder, @Nullable T newCurrentHolder) {
adaptee.onScroll(scrollPosition, currentIndex, newIndex, currentHolder, newCurrentHolder);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ScrollListenerAdapter) {
return adaptee.equals(((ScrollListenerAdapter) obj).adaptee);
} else {
return super.equals(obj);
}
}
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"
>
<gradient
android:angle="180"
android:endColor="#3E7FFC"
android:startColor="#5CC1FF" />
<corners
android:bottomLeftRadius="@dimen/dp_20"
/>
</shape>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:angle="180"
android:endColor="#50526E"
android:startColor="#333F4057" />
<corners android:bottomRightRadius="@dimen/dp_20"/>
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_20" />
<solid android:color="#3F4057" />
</shape>

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/dp_790"
android:layout_height="@dimen/dp_440"
android:layout_gravity="center"
android:background="@drawable/module_commons_shape_round_gray">
<TextView
android:id="@+id/module_commons_wm_dialog_content"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_56"
android:layout_marginTop="@dimen/dp_134"
android:maxLines="1"
android:textColor="@android:color/white"
android:textSize="@dimen/sp_40"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="是否退出导航导航导航导航导航导航导航导航导航导航导航导航导航导航导航导航?" />
<TextView
android:id="@+id/module_commons_wm_dialog_button_ok"
android:layout_width="@dimen/dp_395"
android:layout_height="@dimen/dp_128"
android:background="@drawable/moddule_commons_shape_react_blue_grident"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_40"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
tools:text="确认" />
<TextView
android:id="@+id/module_commons_wm_dialog_button_cancel"
android:layout_width="@dimen/dp_395"
android:layout_height="@dimen/dp_128"
android:background="@drawable/module_commons_shape_react_gray_grident"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_40"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:text="取消" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@@ -1,5 +1,6 @@
<resources>
<string name="app_name">mogo-module-common</string>
<string name="dsv_ex_msg_dont_set_lm">You should not set LayoutManager on DiscreteScrollView.class instance. Library uses a special one. Just don\'t call the method.</string>
<string name="dsv_ex_msg_adapter_wrong_recycler">InfiniteScrollAdapter is supposed to work only with DiscreteScrollView</string>
<string name="module_commons_button_ok">确认</string>
<string name="module_commons_button_cancel">取消</string>
<string name="module_commons_exit_navi_content">是否退出导航?</string>
</resources>

View File

@@ -34,6 +34,7 @@ import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.module.authorize.authprovider.invoke.AuthorizeConstant;
import com.mogo.module.authorize.authprovider.module.IMogoAcquireAuthorizeListener;
import com.mogo.module.authorize.authprovider.module.IMogoAuthorizeModuleManager;
import com.mogo.module.common.dialog.WMDialog;
import com.mogo.module.common.map.MapCenterPointStrategy;
import com.mogo.module.common.map.Scene;
import com.mogo.module.extensions.ExtensionsModuleConst;
@@ -97,7 +98,6 @@ public class EntranceFragment extends MvpFragment< EntranceView, EntrancePresent
private IMogoLocationClient mMogoLocationClient;
private IMogoNavi mMogoNavi;
private IMogoFragmentManager mMogoFragmentManager;
private IMogoAddressManager mMogoAddressManager;
private IMogoMarkerManager mMogoMarkerManager;
private IMogoRegisterCenter mMogoRegisterCenter;
@@ -178,7 +178,6 @@ public class EntranceFragment extends MvpFragment< EntranceView, EntrancePresent
mEntrancePresenter = new EntrancePresenter( getContext(), this, mIMogoAuthorizeModuleManager );
mMogoFragmentManager = mApis.getFragmentManagerApi();
mMogoAddressManager = mApis.getAddressManagerApi();
mStatusManager = mApis.getStatusManagerApi();
@@ -217,8 +216,16 @@ public class EntranceFragment extends MvpFragment< EntranceView, EntrancePresent
mExitNavi.setOnClickListener( view -> {
if ( mMogoNavi != null ) {
if ( mIsLock ) {
NaviNoticeDialog naviNoticeDialog = new NaviNoticeDialog( getContext() );
naviNoticeDialog.show();
new WMDialog.Builder( getContext() )
.setOkButton( R.string.module_commons_button_ok, ( dlg, which ) -> {
mMogoNavi.stopNavi();
} )
.setCancelButton( R.string.module_commons_button_cancel, ( dlg, which ) -> {
dlg.dismiss();
} )
.setContent( R.string.module_commons_exit_navi_content )
.build()
.show();
} else {
MapCenterPointStrategy.setMapCenterPointByScene( mMApUIController, Scene.NAVI );
mMApUIController.recoverLockMode();
@@ -466,10 +473,10 @@ public class EntranceFragment extends MvpFragment< EntranceView, EntrancePresent
if ( mCurrentUploadFrame == mUploadingFrameRes.length ) {
mCurrentUploadFrame = 12;
}
mUploading.setImageResource( mUploadingFrameRes[mCurrentUploadFrame++%mUploadingFrameRes.length] );
mUploading.setImageResource( mUploadingFrameRes[mCurrentUploadFrame++ % mUploadingFrameRes.length] );
}
mUploadFrameAnimHandler.sendEmptyMessageDelayed( MSG_FRAME_ANIM, TIME_FRAME_INTERVAL_TIME );
} else if( msg.what == MSG_STOP_ANIM ){
} else if ( msg.what == MSG_STOP_ANIM ) {
mStatusManager.setUploadingStatus( TAG, false );
}
}

View File

@@ -246,7 +246,7 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
protected void onResume() {
super.onResume();
mMogoStatusManager.setMainPageResumeStatus( TAG, true );
if ( mCoverUpLayout.getVisibility() == View.VISIBLE ) {
if ( mCoverUpLayout.getVisibility() != View.VISIBLE ) {
mServiceApis.getAdasControllerApi().showADAS();
}
}

View File

@@ -125,7 +125,7 @@ public class SchemeIntent implements IMogoStatusChangedListener {
if ( mApis.getMapServiceApi().getNavi( mContext ).isNaviing() ) {
mApis.getMapServiceApi().getNavi( mContext ).naviTo( new MogoLatLng( dlat, dlon ) );
} else {
mApis.getAddressManagerApi().calculatePath( new MogoLatLng( dlat, dlon ) );
mApis.getSearchManagerApi().calculatePath( new MogoLatLng( dlat, dlon ) );
}
} catch ( Exception e ) {
TipToast.shortTip( "目的地异常,不能导航" );

View File

@@ -28,7 +28,6 @@ import com.mogo.service.intent.IMogoIntentListener;
import com.mogo.service.intent.IMogoIntentManager;
import com.mogo.service.launcher.IMogoLauncher;
import com.mogo.service.map.IMogoMapService;
import com.mogo.service.module.IMogoAddressManager;
import com.mogo.service.module.IMogoRegisterCenter;
import com.mogo.service.module.IMogoSearchManager;
import com.mogo.service.statusmanager.IMogoStatusManager;
@@ -59,7 +58,7 @@ public class MapPresenter extends Presenter< MapView > implements
private IMogoStatusManager mStatusManager;
private IMogoRegisterCenter mRegisterCenter;
private IMogoLauncher mLauncher;
private IMogoAddressManager mMogoAddressManager;
private IMogoSearchManager mMogoSearchManager;
private Rect mDisplayOverviewBounds;
public MapPresenter( MapView view ) {
@@ -208,7 +207,7 @@ public class MapPresenter extends Presenter< MapView > implements
lon = intent.getDoubleExtra( "LON", 0.0 );
}
mMogoAddressManager.calculatePath( new MogoLatLng( lat, lon ) );
mMogoSearchManager.calculatePath( new MogoLatLng( lat, lon ) );
}
/**
@@ -287,7 +286,7 @@ public class MapPresenter extends Presenter< MapView > implements
private void onOpenNavi() {
mLauncher.backToLauncher( getContext() );
if ( !mMogoMapService.getNavi( getContext() ).isNaviing() && !mStatusManager.isSearchUIShow() ) {
mMogoAddressManager.goSearch();
mSearchManager.showSearch();
}
AIAssist.getInstance( getContext() ).speakTTSVoice( "已打开" );
}
@@ -305,7 +304,7 @@ public class MapPresenter extends Presenter< MapView > implements
mRegisterCenter = apis.getRegisterCenterApi();
mRegisterCenter.registerMogoNaviListener( TAG, this );
mLauncher = apis.getLauncherApi();
mMogoAddressManager = apis.getAddressManagerApi();
mMogoSearchManager = apis.getSearchManagerApi();
IMogoNavi mogoNavi = mMogoMapService.getNavi( getContext() );
mogoNavi.setCalculatePathDisplayBounds( new Rect(
@@ -418,7 +417,7 @@ public class MapPresenter extends Presenter< MapView > implements
break;
case VoiceConstants.CMD_MAP_STOP_NAVI_MODE_UN_WAKEUP:
case VoiceConstants.CMD_MAP_STOP_NAVI_MODE:
mSearchManager.showMain();
mLauncher.backToLauncher( getContext() );
break;
case VoiceConstants.CMD_MAP_NIGHT_MODE_UN_WAKEUP:
case VoiceConstants.CMD_MAP_NIGHT_MODE:

View File

@@ -4,51 +4,56 @@ import android.content.Context;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.map.MogoLatLng;
import com.mogo.module.navi.constants.SearchServiceHolder;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.module.IMogoAddressManager;
import com.mogo.service.module.IMogoSearchManager;
import com.mogo.utils.logger.Logger;
/**
* @author zyz
* 2020-01-12.
* <p>
* Deprecated, use {@link IMogoSearchManager} instead.
*/
@Deprecated
@Route( path = MogoServicePaths.PATH_ADDRESS_MANAGER )
public class MogoAddressManager implements IMogoAddressManager {
private static final String TAG = "MogoAddressManager";
@Override
public void goHome() {
AddressManager.INSTANCE.goHome();
Logger.w( TAG, "Deprecated, use IMogoSearchManager instead." );
}
@Override
public void goCompany() {
AddressManager.INSTANCE.goCompany();
Logger.w( TAG, "Deprecated, use IMogoSearchManager instead." );
}
@Override
public void goSearch() {
AddressManager.INSTANCE.goSearch();
Logger.w( TAG, "Deprecated, use IMogoSearchManager instead." );
}
@Override
public void calculatePath( MogoLatLng destination ) {
AddressManager.INSTANCE.calculatePath( destination );
Logger.w( TAG, "Deprecated, use IMogoSearchManager instead." );
}
@Override
public void categorySearch( String category ) {
AddressManager.INSTANCE.categorySearch( category );
Logger.w( TAG, "Deprecated, use IMogoSearchManager instead." );
}
@Override
public void goSettings() {
AddressManager.INSTANCE.goSettings();
Logger.w( TAG, "Deprecated, use IMogoSearchManager instead." );
}
@Override
public void init( Context context ) {
AddressManager.INSTANCE.init( context );
SearchServiceHolder.INSTANCE.init( context );
SettingManager.INSTANCE.init( context );
Logger.w( TAG, "Deprecated, use IMogoSearchManager instead." );
}
}

View File

@@ -1,8 +1,11 @@
package com.mogo.module.navi.manager;
import android.content.Context;
import androidx.fragment.app.Fragment;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.map.MogoLatLng;
import com.mogo.map.constants.BroadcastMode;
import com.mogo.module.common.MogoModulePaths;
import com.mogo.module.navi.constants.AMapConstants;
@@ -17,37 +20,57 @@ import com.mogo.service.module.IMogoSearchManager;
* @author zyz
* 2020-01-13.
*/
@Route(path = MogoServicePaths.PATH_SEARCH_MANAGER)
@Route( path = MogoServicePaths.PATH_SEARCH_MANAGER )
public class MogoSearchManager implements IMogoSearchManager {
@Override public void goHome() {
@Override
public void goHome() {
AddressManager.INSTANCE.goHome();
}
@Override public void goCompany() {
@Override
public void goCompany() {
AddressManager.INSTANCE.goCompany();
}
@Override public void showSearch() {
@Override
public void showSearch() {
AddressManager.INSTANCE.goSearch();
}
@Override public void showMain() {
@Override
public void showMain() {
SearchServiceHolder.INSTANCE.getFragmentManager().clearAll();
}
@Override public void speakDraft() {
SearchServiceHolder.INSTANCE.getNavi().setBroadcastMode(BroadcastMode.CONCISE);
@Override
public void speakDraft() {
SearchServiceHolder.INSTANCE.getNavi().setBroadcastMode( BroadcastMode.CONCISE );
}
@Override public void speakDetail() {
SearchServiceHolder.INSTANCE.getNavi().setBroadcastMode(BroadcastMode.DETAIL);
@Override
public void speakDetail() {
SearchServiceHolder.INSTANCE.getNavi().setBroadcastMode( BroadcastMode.DETAIL );
}
@Override public void showCategory(String keyword) {
@Override
public void categorySearch( String keyword ) {
AddressManager.INSTANCE.categorySearch( keyword );
}
@Override public void init(Context context) {
@Override
public void calculatePath( MogoLatLng destination ) {
AddressManager.INSTANCE.calculatePath( destination );
}
@Override
public void goSettings() {
AddressManager.INSTANCE.goSettings();
}
@Override
public void init( Context context ) {
AddressManager.INSTANCE.init( context );
SearchServiceHolder.INSTANCE.init( context );
SettingManager.INSTANCE.init( context );
}
}

View File

@@ -9,9 +9,20 @@ import android.view.View;
import android.widget.TextView;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.map.MogoLatLng;
import com.mogo.map.search.geo.IMogoGeoSearch;
import com.mogo.map.search.geo.IMogoGeoSearchListener;
import com.mogo.map.search.geo.MogoGeocodeResult;
import com.mogo.map.search.geo.MogoRegeocodeResult;
import com.mogo.map.search.geo.query.MogoRegeocodeQuery;
import com.mogo.module.common.dialog.WMDialog;
import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.MogoServiceProvider;
import com.mogo.module.service.R;
import com.mogo.service.entrance.ButtonIndex;
import com.mogo.utils.TipToast;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.utils.GsonUtil;
/**
* @author congtaowang
@@ -71,10 +82,10 @@ public class MockIntentHandler implements IntentHandler {
button11.setVisibility( View.VISIBLE );
button11.setBackgroundColor( Color.RED );
button11.setOnClickListener( view -> {
Intent intent1 = new Intent( );
Intent intent1 = new Intent();
intent1.setAction( Intent.ACTION_VIEW );
intent1.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
intent1.setData( Uri.parse("wechathelper://com.zhidao.wechathelper/main/transform?type=navi&lon=116.327007&lat=39.977639&from=os2.0") );
intent1.setData( Uri.parse( "wechathelper://com.zhidao.wechathelper/main/transform?type=navi&lon=116.327007&lat=39.977639&from=os2.0" ) );
try {
view.setOnClickListener( null );
view.getContext().startActivity( intent1 );
@@ -89,6 +100,37 @@ public class MockIntentHandler implements IntentHandler {
float bearing = intent.getFloatExtra( "bearing", 0 );
MarkerServiceHandler.getMapUIController().changeBearing( bearing );
break;
case 9:
new WMDialog.Builder( context )
.setOkButton( "确认", ( dlg, which ) -> {
dlg.dismiss();
} )
.setCancelButton( "取消", ( dlg, which ) -> {
dlg.dismiss();
} )
.setContent( "内容内容内容内容内容内容内容内容" )
.build()
.show();
break;
case 10:
IMogoGeoSearch geoSearch = MarkerServiceHandler.getMapService().getGeoSearch( context );
geoSearch.setGeoSearchListener( new IMogoGeoSearchListener() {
@Override
public void onRegeocodeSearched( MogoRegeocodeResult regeocodeResult ) {
Logger.d( TAG, GsonUtil.jsonFromObject( regeocodeResult ) );
}
@Override
public void onGeocodeSearched( MogoGeocodeResult geocodeResult ) {
}
} );
MogoRegeocodeQuery query = new MogoRegeocodeQuery();
query.setLatlngType( "autonavi" );
query.setPoint( new MogoLatLng( intent.getFloatExtra( "lat", 39.917366f ), intent.getFloatExtra( "lon", 116.39962f ) ) );
query.setRadius( 1000 );
geoSearch.getFromLocationAsyn( query );
break;
}
}
}

View File

@@ -160,9 +160,11 @@ public interface IMogoServiceApis extends IProvider {
/**
* 地址操作
* Deprecated, use {@link IMogoSearchManager} instead.
*
* @return
*/
@Deprecated
IMogoAddressManager getAddressManagerApi();
/**

View File

@@ -41,6 +41,7 @@ public interface IMogoMapService extends IProvider {
* @param context
* @return 定位实例
*/
@Deprecated
IMogoLocationClient getLocationClient( Context context );
/**

View File

@@ -6,22 +6,28 @@ import com.mogo.map.MogoLatLng;
/**
* @author zyz
* 2020-01-12.
* <p>
* Deprecated, use {@link IMogoSearchManager} instead."
*/
@Deprecated
public interface IMogoAddressManager extends IProvider {
/**
* 回家
*/
@Deprecated
void goHome();
/**
* 去公司
*/
@Deprecated
void goCompany();
/**
* 打开搜索
*/
@Deprecated
void goSearch();
/**
@@ -29,12 +35,15 @@ public interface IMogoAddressManager extends IProvider {
*
* @param destination 目的地
*/
@Deprecated
void calculatePath( MogoLatLng destination );
/**
* 分类搜索
*/
void categorySearch(String category);
@Deprecated
void categorySearch( String category );
@Deprecated
void goSettings();
}

View File

@@ -1,6 +1,7 @@
package com.mogo.service.module;
import com.alibaba.android.arouter.facade.template.IProvider;
import com.mogo.map.MogoLatLng;
/**
* @author zyz
@@ -8,11 +9,41 @@ import com.alibaba.android.arouter.facade.template.IProvider;
*/
public interface IMogoSearchManager extends IProvider {
/**
* 回家
*/
void goHome();
/**
* 去公司
*/
void goCompany();
/**
* 打开搜索
*/
void showSearch();
void showMain();
void speakDraft();
void speakDetail();
void showCategory(String keyword);
/**
* 规划路线
*
* @param destination 目的地
*/
void calculatePath( MogoLatLng destination );
/**
* 分类搜索
*/
void categorySearch( String keyword );
/**
* 打开导航设置
*/
void goSettings();
}