添加上滑fling隐藏顶部view接口及实现
This commit is contained in:
@@ -41,6 +41,7 @@ import com.mogo.module.extensions.ExtensionsModuleConst;
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.module.extensions.navi.NaviInfoView;
|
||||
import com.mogo.module.extensions.utils.TopViewAnimHelper;
|
||||
import com.mogo.module.extensions.utils.TopViewManager;
|
||||
import com.mogo.module.share.ShareControl;
|
||||
import com.mogo.service.IMogoServiceApis;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
@@ -53,6 +54,7 @@ import com.mogo.service.module.IMogoRegisterCenter;
|
||||
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
|
||||
import com.mogo.service.statusmanager.IMogoStatusManager;
|
||||
import com.mogo.service.statusmanager.StatusDescriptor;
|
||||
import com.mogo.service.windowview.IMogoTopViewStatusListener;
|
||||
import com.mogo.utils.ResourcesHelper;
|
||||
import com.mogo.utils.UiThreadHandler;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
@@ -170,6 +172,8 @@ public class EntranceFragment extends MvpFragment< EntranceView, EntrancePresent
|
||||
|
||||
private Rect mDisplayOverviewBounds;
|
||||
|
||||
private boolean toggle = false;
|
||||
|
||||
private Runnable mLockCarRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -206,9 +210,19 @@ public class EntranceFragment extends MvpFragment< EntranceView, EntrancePresent
|
||||
// // todo 测试动画
|
||||
// View v = LayoutInflater.from(getContext()).inflate(R.layout.demo_top, null);
|
||||
// TextView tv = v.findViewById(R.id.tvIndex);
|
||||
// tv.setText(demoCache.size() + "");
|
||||
// tv.setText(demoCache.size() + ": " + v);
|
||||
// demoCache.add(v);
|
||||
// mApis.getTopViewManager().addView(v);
|
||||
// mApis.getTopViewManager().addView(v, new IMogoTopViewStatusListener() {
|
||||
// @Override
|
||||
// public void onViewAdded(View view) {
|
||||
// Logger.d(TAG, "onViewAdded: " + view);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onViewRemoved(View view) {
|
||||
// Logger.d(TAG, "onViewRemoved: " + view);
|
||||
// }
|
||||
// });
|
||||
// 原始逻辑
|
||||
isClickShare = true;
|
||||
if ( mIMogoAuthorizeModuleManager.needAuthorize( AUTHORIZE_TYPE_LAUNCHER_SHARE ) ) {
|
||||
@@ -237,6 +251,12 @@ public class EntranceFragment extends MvpFragment< EntranceView, EntrancePresent
|
||||
mMove2CurrentLocation = findViewById( R.id.module_entrance_id_move2_current_location );
|
||||
mMove2CurrentLocation.setOnClickListener( view -> {
|
||||
// // todo 测试动画
|
||||
// if(!toggle) {
|
||||
// TopViewAnimHelper.getInstance().showNaviView();
|
||||
// }else{
|
||||
// TopViewAnimHelper.getInstance().hideNaviView();
|
||||
// }
|
||||
// toggle = !toggle;
|
||||
// if(demoCache.size()>0) {
|
||||
// View v = demoCache.remove(demoCache.size() - 1);
|
||||
// boolean isViewAdded = mApis.getTopViewManager().isViewAdded(v);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.mogo.module.extensions.navi;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
/**
|
||||
* 顶部view封装,用于处理手指滑动
|
||||
*/
|
||||
public class TopView extends FrameLayout {
|
||||
public TopView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public TopView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public TopView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private OnTopViewSlideListener slideListener;
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
// 简单处理,只要手指抬起的位置在按下的位置上面(就是手指上划),就触发外面的动画
|
||||
if (event.getY() < originY) {
|
||||
if (slideListener != null) {
|
||||
slideListener.onSlideUp();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
private float originY;
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
originY = ev.getY();
|
||||
} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
// 垂直滑动,事件拦截
|
||||
return Math.abs(originY - ev.getY()) > ViewConfiguration.get(getContext()).getScaledTouchSlop();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setSlideListener(OnTopViewSlideListener slideListener) {
|
||||
this.slideListener = slideListener;
|
||||
}
|
||||
|
||||
public interface OnTopViewSlideListener{
|
||||
/**
|
||||
* 监听到view上滑
|
||||
*/
|
||||
void onSlideUp();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
package com.mogo.module.extensions.utils;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.transition.AutoTransition;
|
||||
import android.transition.Transition;
|
||||
import android.transition.TransitionManager;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -19,10 +18,13 @@ import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
import com.mogo.module.common.map.MapCenterPointStrategy;
|
||||
import com.mogo.module.common.map.Scene;
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.module.extensions.navi.TopView;
|
||||
import com.mogo.service.windowview.IMogoTopViewStatusListener;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
@@ -34,13 +36,15 @@ public class TopViewAnimHelper {
|
||||
private static final String TAG = "TopViewAnimHelper";
|
||||
|
||||
private ConstraintLayout topMotionLayout;
|
||||
private Group naviGroup, remainTimeGroup, remainDistanceGroup, arriveTimeGroup;
|
||||
private Group remainTimeGroup, remainDistanceGroup, arriveTimeGroup;
|
||||
private View naviBg;
|
||||
|
||||
private ImageView ivTurnIcon;
|
||||
private TextView tvNextDistance;
|
||||
private TextView tvNextRoad;
|
||||
private FrameLayout topContainer;
|
||||
private TextView tvNextDistanceUnit;
|
||||
private TextView tvTurnInfo;
|
||||
private TopView topContainer;
|
||||
|
||||
private ConstraintSet constraintSet = new ConstraintSet();
|
||||
private Transition transition = new AutoTransition();
|
||||
@@ -75,11 +79,14 @@ public class TopViewAnimHelper {
|
||||
public void init(ConstraintLayout rootView, OnTopViewAnimSimpleListener listener) {
|
||||
topMotionLayout = rootView;
|
||||
naviBg = rootView.findViewById(R.id.module_map_id_navi_bg);
|
||||
naviGroup = rootView.findViewById(R.id.naviGroup);
|
||||
remainTimeGroup = rootView.findViewById(R.id.remainTimeGroup);
|
||||
remainDistanceGroup = rootView.findViewById(R.id.remainDistanceGroup);
|
||||
arriveTimeGroup = rootView.findViewById(R.id.arriveTimeGroup);
|
||||
topContainer = rootView.findViewById(R.id.module_entrance_id_top_container);
|
||||
tvNextDistanceUnit = rootView.findViewById(R.id.module_map_id_navi_next_info_distance_unit);
|
||||
tvTurnInfo = rootView.findViewById(R.id.module_map_id_navi_next_info_turn_info);
|
||||
|
||||
topContainer.setSlideListener(this::startLatestTopOutAnim);
|
||||
|
||||
ivTurnIcon = rootView.findViewById(R.id.module_map_id_navi_next_info_road_turn_icon);
|
||||
tvNextDistance = rootView.findViewById(R.id.module_map_id_navi_next_info_distance);
|
||||
@@ -102,6 +109,16 @@ public class TopViewAnimHelper {
|
||||
if (listener != null) {
|
||||
listener.onAnimEnd();
|
||||
}
|
||||
Logger.d(TAG, "onTransitionEnd: " + currentAnimatingView);
|
||||
IMogoTopViewStatusListener listener;
|
||||
if (isTopViewOut) {
|
||||
listener = statusListenerMap.remove(currentAnimatingView);
|
||||
}else{
|
||||
listener = statusListenerMap.get(currentAnimatingView);
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onViewAdded(currentAnimatingView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,8 +142,11 @@ public class TopViewAnimHelper {
|
||||
|
||||
private boolean isTopViewOut = true;
|
||||
private List<View> viewCaches = new ArrayList<>();
|
||||
private Map<View, IMogoTopViewStatusListener> statusListenerMap = new ArrayMap<>();
|
||||
|
||||
public void startTopInAnim(View view, ViewGroup.LayoutParams params) {
|
||||
private View currentAnimatingView = null;
|
||||
|
||||
public void startTopInAnim(View view, ViewGroup.LayoutParams params, IMogoTopViewStatusListener statusListener) {
|
||||
Logger.d(TAG, "startTopInAnim====="+isTopViewOut);
|
||||
if (view == null) {
|
||||
throw new IllegalArgumentException("method addTopView params view is null");
|
||||
@@ -136,6 +156,7 @@ public class TopViewAnimHelper {
|
||||
}
|
||||
if (!viewCaches.contains(view)) {
|
||||
// 判断此view是否已经增加到了顶部view,如果增加过就不增加了
|
||||
statusListenerMap.put(view, statusListener);
|
||||
Logger.d(TAG, "开始执行");
|
||||
isTopViewOut = false;
|
||||
if (topContainer.getChildCount() > 0) {
|
||||
@@ -145,11 +166,42 @@ public class TopViewAnimHelper {
|
||||
topContainer.addView(view, params);
|
||||
Logger.d(TAG, "顶部view已经有布局了,增加新增view滑入动画: " + view.getTranslationY() + " height:" +
|
||||
" " + view.getHeight() + " paramsHeight: " + params.height);
|
||||
view.animate().translationY(0).setDuration(500).start();
|
||||
view.animate().translationY(0).setDuration(500).setListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
IMogoTopViewStatusListener listener = statusListenerMap.get(view);
|
||||
if (listener != null) {
|
||||
listener.onViewAdded(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
// 顶部view还没有内容,需要整体下移
|
||||
currentAnimatingView = view;
|
||||
viewCaches.add(view);
|
||||
topContainer.addView(view, params);
|
||||
|
||||
if (naviBg.getVisibility() == View.VISIBLE) {
|
||||
remainDistanceGroup.setVisibility(View.GONE);
|
||||
remainTimeGroup.setVisibility(View.GONE);
|
||||
arriveTimeGroup.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
constraintSet.clone(topMotionLayout);
|
||||
|
||||
constraintSet.clear(R.id.module_entrance_id_top_container,ConstraintSet.BOTTOM);
|
||||
@@ -157,7 +209,7 @@ public class TopViewAnimHelper {
|
||||
R.id.module_entrance_id_top_motion_layout, ConstraintSet.TOP);
|
||||
TransitionManager.beginDelayedTransition(topMotionLayout, transition);
|
||||
checkCameraModePosition(false);
|
||||
if (naviGroup.getVisibility() == View.VISIBLE) {
|
||||
if (naviBg.getVisibility() == View.VISIBLE) {
|
||||
// 约束设置需要在applyTo()方法之前执行,visiable设置需要在applyTo()
|
||||
// 方法之后执行才能生效,所以分开了两个判断,至于为什么这么做才能生效,不得而知
|
||||
constraintSet.connect(tvNextDistance.getId(), ConstraintSet.BOTTOM,
|
||||
@@ -170,11 +222,6 @@ public class TopViewAnimHelper {
|
||||
(int) topMotionLayout.getContext().getResources().getDimension(R.dimen.dp_46));
|
||||
}
|
||||
constraintSet.applyTo(topMotionLayout);
|
||||
if (naviGroup.getVisibility() == View.VISIBLE) {
|
||||
remainDistanceGroup.setVisibility(View.GONE);
|
||||
remainTimeGroup.setVisibility(View.GONE);
|
||||
arriveTimeGroup.setVisibility(View.GONE);
|
||||
}
|
||||
ivTurnIcon.getLayoutParams().height =
|
||||
(int) getDimen(R.dimen.module_ext_navi_info_panel_turn_icon_small_height);
|
||||
ivTurnIcon.getLayoutParams().width =
|
||||
@@ -182,7 +229,7 @@ public class TopViewAnimHelper {
|
||||
naviBg.getLayoutParams().height =
|
||||
(int) topMotionLayout.getContext().getResources().getDimension(R.dimen.module_ext_navi_info_panel_small_height);
|
||||
int scene = 0;
|
||||
if(naviGroup.getVisibility() == View.VISIBLE){
|
||||
if(naviBg.getVisibility() == View.VISIBLE){
|
||||
scene = Scene.NAVI_WITH_ROAD_EVENT;
|
||||
}else{
|
||||
scene = Scene.AIMLESS_WITH_ROAD_EVENT;
|
||||
@@ -193,6 +240,15 @@ public class TopViewAnimHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出最新的(也就是最上面的)view
|
||||
*/
|
||||
private void startLatestTopOutAnim(){
|
||||
if (topContainer.getChildCount() > 0) {
|
||||
startTopOutAnim(topContainer.getChildAt(topContainer.getChildCount() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
public void startTopOutAnim(View view) {
|
||||
Logger.d("TopViewAnimHelper", "startTopOutAnim=====");
|
||||
if (!isTopViewOut) {
|
||||
@@ -208,8 +264,15 @@ public class TopViewAnimHelper {
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
Logger.d(TAG,"onAnimationEnd: "+view);
|
||||
viewCaches.remove(view);
|
||||
topContainer.removeView(view);
|
||||
IMogoTopViewStatusListener listener = statusListenerMap.remove(view);
|
||||
if (listener != null) {
|
||||
listener.onViewRemoved(view);
|
||||
}else{
|
||||
Logger.d(TAG, "listener is null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -225,7 +288,13 @@ public class TopViewAnimHelper {
|
||||
}).start();
|
||||
}else {
|
||||
// 顶部view仅剩一个view,需要整体上移
|
||||
currentAnimatingView = view;
|
||||
isTopViewOut = true;
|
||||
if (naviBg.getVisibility() == View.VISIBLE) {
|
||||
remainDistanceGroup.setVisibility(View.VISIBLE);
|
||||
remainTimeGroup.setVisibility(View.VISIBLE);
|
||||
arriveTimeGroup.setVisibility(View.VISIBLE);
|
||||
}
|
||||
constraintSet.clone(topMotionLayout);
|
||||
|
||||
constraintSet.clear(R.id.module_entrance_id_top_container,ConstraintSet.TOP);
|
||||
@@ -234,7 +303,7 @@ public class TopViewAnimHelper {
|
||||
TransitionManager.beginDelayedTransition(topMotionLayout, transition);
|
||||
checkCameraModePosition(false);
|
||||
|
||||
if (naviGroup.getVisibility() == View.VISIBLE) {
|
||||
if (naviBg.getVisibility() == View.VISIBLE) {
|
||||
// 约束设置需要在applyTo()方法之前执行,visiable设置需要在applyTo()
|
||||
// 方法之后执行才能生效,所以分开了两个判断,至于为什么这么做才能生效,不得而知
|
||||
constraintSet.clear(tvNextDistance.getId(), ConstraintSet.BOTTOM);
|
||||
@@ -246,11 +315,7 @@ public class TopViewAnimHelper {
|
||||
0);
|
||||
}
|
||||
constraintSet.applyTo(topMotionLayout);
|
||||
if (naviGroup.getVisibility() == View.VISIBLE) {
|
||||
remainDistanceGroup.setVisibility(View.VISIBLE);
|
||||
remainTimeGroup.setVisibility(View.VISIBLE);
|
||||
arriveTimeGroup.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
ivTurnIcon.getLayoutParams().height =
|
||||
(int) getDimen(R.dimen.module_ext_navi_info_panel_turn_icon_height);
|
||||
ivTurnIcon.getLayoutParams().width =
|
||||
@@ -258,7 +323,7 @@ public class TopViewAnimHelper {
|
||||
naviBg.getLayoutParams().height =
|
||||
(int) topMotionLayout.getContext().getResources().getDimension(R.dimen.module_ext_navi_info_panel_height);
|
||||
int scene = 0;
|
||||
if(naviGroup.getVisibility() == View.VISIBLE){
|
||||
if(naviBg.getVisibility() == View.VISIBLE){
|
||||
scene = Scene.NAVI;
|
||||
}else{
|
||||
scene = Scene.AIMLESS;
|
||||
@@ -271,7 +336,7 @@ public class TopViewAnimHelper {
|
||||
|
||||
public void showNaviView() {
|
||||
Logger.d("TopViewAnimHelper", "showNaviView=====");
|
||||
naviGroup.setVisibility(View.VISIBLE);
|
||||
setNaviVisibility(View.VISIBLE);
|
||||
int scene = 0;
|
||||
if (isTopViewOut) {
|
||||
remainDistanceGroup.setVisibility(View.VISIBLE);
|
||||
@@ -326,7 +391,7 @@ public class TopViewAnimHelper {
|
||||
|
||||
public void hideNaviView() {
|
||||
Logger.d("TopViewAnimHelper", "hideNaviView=====");
|
||||
naviGroup.setVisibility(View.GONE);
|
||||
setNaviVisibility(View.GONE);
|
||||
remainDistanceGroup.setVisibility(View.GONE);
|
||||
remainTimeGroup.setVisibility(View.GONE);
|
||||
arriveTimeGroup.setVisibility(View.GONE);
|
||||
@@ -345,7 +410,7 @@ public class TopViewAnimHelper {
|
||||
if (isNeedClone) {
|
||||
constraintSet.clone(topMotionLayout);
|
||||
}
|
||||
if (naviGroup.getVisibility() == View.VISIBLE) {
|
||||
if (naviBg.getVisibility() == View.VISIBLE) {
|
||||
constraintSet.connect(cameraMode.getId(), ConstraintSet.TOP, naviBg.getId(),
|
||||
ConstraintSet.BOTTOM, (int) getDimen(R.dimen.dp_30));
|
||||
} else {
|
||||
@@ -378,4 +443,17 @@ public class TopViewAnimHelper {
|
||||
public boolean isViewAdded(View view) {
|
||||
return viewCaches.contains(view);
|
||||
}
|
||||
|
||||
private void setNaviVisibility(int visibility) {
|
||||
ivTurnIcon.setVisibility(visibility);
|
||||
tvNextRoad.setVisibility(visibility);
|
||||
tvNextDistance.setVisibility(visibility);
|
||||
remainTimeGroup.setVisibility(visibility);
|
||||
remainDistanceGroup.setVisibility(visibility);
|
||||
arriveTimeGroup.setVisibility(visibility);
|
||||
naviBg.setVisibility(visibility);
|
||||
tvNextDistanceUnit.setVisibility(visibility);
|
||||
tvTurnInfo.setVisibility(visibility);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
import com.mogo.service.windowview.IMogoTopViewManager;
|
||||
import com.mogo.service.windowview.IMogoTopViewStatusListener;
|
||||
|
||||
/**
|
||||
* 顶部1/2界面管理
|
||||
@@ -36,12 +37,24 @@ public class TopViewManager implements IMogoTopViewManager {
|
||||
@Override
|
||||
public void addView(View view) {
|
||||
addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
(int) context.getResources().getDimension(R.dimen.dp_350)));
|
||||
(int) context.getResources().getDimension(R.dimen.dp_350)),null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View view, IMogoTopViewStatusListener statusListener) {
|
||||
addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
(int) context.getResources().getDimension(R.dimen.dp_350)),statusListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View view, ViewGroup.LayoutParams params) {
|
||||
TopViewAnimHelper.getInstance().startTopInAnim(view, params);
|
||||
addView(view, params, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View view, ViewGroup.LayoutParams params,
|
||||
IMogoTopViewStatusListener statusListener) {
|
||||
TopViewAnimHelper.getInstance().startTopInAnim(view, params, statusListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user