opt
This commit is contained in:
@@ -2,6 +2,7 @@ package com.mogo.module.main;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -25,6 +26,7 @@ import com.mogo.module.main.cards.OrientedViewPager;
|
||||
import com.mogo.module.main.cards.VerticalStackTransformer;
|
||||
import com.mogo.module.main.fragmentmanager.FragmentStack;
|
||||
import com.mogo.module.main.fragmentmanager.FragmentStackTransactionListener;
|
||||
import com.mogo.module.main.windowview.WindowViewHandler;
|
||||
import com.mogo.module.map.VoiceConstants;
|
||||
import com.mogo.module.service.ServiceConst;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
@@ -58,6 +60,7 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
|
||||
private View mCards;
|
||||
private View mApps;
|
||||
private View mEntrance;
|
||||
private FrameLayout mFloatingLayout;
|
||||
|
||||
/**
|
||||
* 主模块管控定位,可以向各个模块发送统一定位信息
|
||||
@@ -103,6 +106,9 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
|
||||
mCards = findViewById( R.id.module_main_id_cards_container );
|
||||
mApps = findViewById( R.id.module_main_id_apps_fragment_container );
|
||||
mEntrance = findViewById( R.id.module_main_id_entrance_fragment_container );
|
||||
mFloatingLayout = findViewById( R.id.module_main_id_floating_view );
|
||||
|
||||
WindowViewHandler.init( mFloatingLayout );
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
@@ -110,6 +116,7 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
|
||||
mCards.setVisibility( View.GONE );
|
||||
mApps.setVisibility( View.GONE );
|
||||
mEntrance.setVisibility( View.GONE );
|
||||
mFloatingLayout.setVisibility( View.GONE );
|
||||
}
|
||||
|
||||
private void show() {
|
||||
@@ -117,6 +124,7 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
|
||||
mCards.setVisibility( View.VISIBLE );
|
||||
mApps.setVisibility( View.VISIBLE );
|
||||
mEntrance.setVisibility( View.VISIBLE );
|
||||
mFloatingLayout.setVisibility( View.VISIBLE );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -187,8 +195,8 @@ public class MainActivity extends MvpActivity< MainView, MainPresenter > impleme
|
||||
@Override
|
||||
public boolean onMarkerClicked( IMogoMarker marker ) {
|
||||
switch2( marker.getOwner() );
|
||||
if (mMogoModuleHandler != null) {
|
||||
mMogoModuleHandler.onMarkerReceive(marker);
|
||||
if ( mMogoModuleHandler != null ) {
|
||||
mMogoModuleHandler.onMarkerReceive( marker );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.mogo.module.main.windowview;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class DispatchTouchEventWrapper {
|
||||
|
||||
private IWindowViewHandler mWindowViewHandler;
|
||||
|
||||
int mActionDownX = -1;
|
||||
int mActionDownY = -1;
|
||||
|
||||
/**
|
||||
* Flag whether move after touch down.
|
||||
*/
|
||||
boolean mMoveFlag = false;
|
||||
|
||||
private static volatile DispatchTouchEventWrapper INST;
|
||||
|
||||
private DispatchTouchEventWrapper() {
|
||||
}
|
||||
|
||||
public static DispatchTouchEventWrapper getInstance() {
|
||||
if ( INST == null ) {
|
||||
synchronized ( DispatchTouchEventWrapper.class ) {
|
||||
if ( INST == null ) {
|
||||
INST = new DispatchTouchEventWrapper();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INST;
|
||||
}
|
||||
|
||||
public DispatchTouchEventWrapper attach( View windowView, WindowManager.LayoutParams params ) {
|
||||
if ( mWindowViewHandler == null || mWindowViewHandler.getWindowView() != windowView ) {
|
||||
mWindowViewHandler = new IWindowViewHandler.DefaultHandler( windowView, params );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean handle( MotionEvent event ) {
|
||||
switch ( event.getAction() & MotionEvent.ACTION_MASK ) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if ( onActionDown( event ) ) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if ( onActionMove( event ) ) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if ( onActionUp( event ) ) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean onActionDown( MotionEvent event ) {
|
||||
mActionDownX = ( ( int ) event.getRawX() );
|
||||
mActionDownY = ( ( int ) event.getRawY() );
|
||||
if ( mWindowViewHandler != null ) {
|
||||
mWindowViewHandler.recordNewPosition();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean onActionMove( MotionEvent event ) {
|
||||
|
||||
if ( Math.abs( event.getRawX() - mActionDownX ) >= 20
|
||||
|| Math.abs( event.getRawY() - mActionDownY ) >= 20 ) {
|
||||
mMoveFlag = false;
|
||||
}
|
||||
|
||||
if ( isLastDownValueLegal() ) {
|
||||
moveWindowView( event );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean onActionUp( MotionEvent event ) {
|
||||
if ( isClickEventLike() ) {
|
||||
if ( mWindowViewHandler != null ) {
|
||||
mWindowViewHandler.performClickLike();
|
||||
}
|
||||
} else {
|
||||
if ( mWindowViewHandler != null ) {
|
||||
mWindowViewHandler.moveToEdge();
|
||||
mWindowViewHandler.recordNewPosition();
|
||||
}
|
||||
}
|
||||
mMoveFlag = false;
|
||||
clearLastDownAxisValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void clearLastDownAxisValue() {
|
||||
mActionDownX = mActionDownY = -1;
|
||||
}
|
||||
|
||||
private boolean isLastDownValueLegal() {
|
||||
return mActionDownX != -1 && mActionDownY != -1;
|
||||
}
|
||||
|
||||
private void moveWindowView( MotionEvent event ) {
|
||||
if ( mWindowViewHandler != null ) {
|
||||
mWindowViewHandler.move( event, mActionDownX, mActionDownY );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate click event just like set {@link View.OnClickListener}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isClickEventLike() {
|
||||
System.out.println( mMoveFlag );
|
||||
return isLastDownValueLegal() && !mMoveFlag;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if ( mWindowViewHandler != null ) {
|
||||
mWindowViewHandler.release();
|
||||
}
|
||||
mWindowViewHandler = null;
|
||||
mActionDownX = -1;
|
||||
mActionDownY = -1;
|
||||
mMoveFlag = false;
|
||||
INST = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.mogo.module.main.windowview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.utils.WindowUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Created by congtaowang on 2017/6/20.
|
||||
*/
|
||||
|
||||
public interface IWindowViewHandler {
|
||||
|
||||
View getWindowView();
|
||||
|
||||
void recordNewPosition();
|
||||
|
||||
void move( MotionEvent event, int downX, int downY );
|
||||
|
||||
void release();
|
||||
|
||||
void moveToEdge();
|
||||
|
||||
void performClickLike();
|
||||
|
||||
class DefaultHandler implements IWindowViewHandler {
|
||||
|
||||
protected View mWindowView;
|
||||
|
||||
protected int mWindowViewLeft = -1;
|
||||
protected int mWindowViewTop = -1;
|
||||
|
||||
private WindowManager.LayoutParams mParams;
|
||||
|
||||
public DefaultHandler( View windowView, WindowManager.LayoutParams params ) {
|
||||
this.mWindowView = windowView;
|
||||
mParams = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getWindowView() {
|
||||
return mWindowView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordNewPosition() {
|
||||
mWindowViewLeft = mParams.x;
|
||||
mWindowViewTop = mParams.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move( MotionEvent event, int downX, int downY ) {
|
||||
move( ( ( int ) ( event.getRawX() - downX ) ),
|
||||
( ( int ) ( event.getRawY() - downY ) ) );
|
||||
}
|
||||
|
||||
private void move( int distanceX, int distanceY ) {
|
||||
if ( mWindowView == null ) {
|
||||
return;
|
||||
}
|
||||
mParams.x = mWindowViewLeft + distanceX;
|
||||
mParams.y = mWindowViewTop + distanceY;
|
||||
WindowManager wm = ( ( WindowManager ) mWindowView.getContext().getSystemService( Context.WINDOW_SERVICE ) );
|
||||
|
||||
if ( wm == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wm.updateViewLayout( mWindowView, alignLayoutParamsBoundary( mParams ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveToEdge() {
|
||||
if ( mWindowView == null ) {
|
||||
return;
|
||||
}
|
||||
WindowManager wm = ( ( WindowManager ) mWindowView.getContext().getSystemService( Context.WINDOW_SERVICE ) );
|
||||
|
||||
if ( mParams.x > WindowUtils.getScreenWidth( AbsMogoApplication.getApp() ) / 2 ) {
|
||||
mParams.x = WindowUtils.getScreenWidth( AbsMogoApplication.getApp() ) - mWindowView.getMeasuredWidth();
|
||||
} else {
|
||||
mParams.x = 0;
|
||||
}
|
||||
|
||||
wm.updateViewLayout( mWindowView, alignLayoutParamsBoundary( mParams ) );
|
||||
}
|
||||
|
||||
protected WindowManager.LayoutParams alignLayoutParamsBoundary( WindowManager.LayoutParams params ) {
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performClickLike() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
mWindowView = null;
|
||||
mWindowViewLeft = -1;
|
||||
mWindowViewTop = -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.mogo.module.main.windowview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
import com.mogo.service.windowview.IMogoWindowManager;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-06
|
||||
* <p>
|
||||
* 根据优先级控制显示 window view.
|
||||
*/
|
||||
@Route( path = MogoServicePaths.PATH_WINDOW_MANAGER )
|
||||
public class MogoWindowManager implements IMogoWindowManager {
|
||||
|
||||
@Override
|
||||
public void addView( int priority, View view, int x, int y, boolean movable ) {
|
||||
WindowViewHandler.addView( view, priority, x, y, movable );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeView( View view ) {
|
||||
WindowViewHandler.removeView( view );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init( Context context ) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.mogo.module.main.windowview;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-06
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class WindowViewHandler {
|
||||
|
||||
private static final String TAG = "WindowViewHandler";
|
||||
|
||||
/**
|
||||
* 上次显示的优先级
|
||||
*/
|
||||
private static int sPriority = Integer.MIN_VALUE;
|
||||
|
||||
/**
|
||||
* 上次添加的view
|
||||
*/
|
||||
private static View sView = null;
|
||||
|
||||
private static int sX, sY;
|
||||
|
||||
/**
|
||||
* 是否可手指拖动
|
||||
*/
|
||||
private static boolean sMovable = false;
|
||||
|
||||
public static FrameLayout sFloatingLayout = null;
|
||||
|
||||
public static void init( FrameLayout frameLayout ) {
|
||||
sFloatingLayout = frameLayout;
|
||||
}
|
||||
|
||||
public static void addView( View view, int priority, int x, int y, boolean movable ) {
|
||||
if ( view == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( sFloatingLayout == null ) {
|
||||
Logger.e( TAG, "no floating frame. " );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( sView == view ) {
|
||||
Logger.w( TAG, "改布局已添加且没有移除,不操作" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( sView == null ) {
|
||||
sView = view;
|
||||
sMovable = movable;
|
||||
sPriority = priority;
|
||||
sX = x;
|
||||
sY = y;
|
||||
addView();
|
||||
} else {
|
||||
if ( priority < sPriority ) {
|
||||
Logger.w( TAG, "过滤低优先级布局" );
|
||||
return;
|
||||
}
|
||||
sFloatingLayout.removeView( sView );
|
||||
sView = view;
|
||||
sX = x;
|
||||
sY = y;
|
||||
sPriority = priority;
|
||||
sMovable = movable;
|
||||
addView();
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeView( View view ) {
|
||||
if ( sFloatingLayout == null ) {
|
||||
return;
|
||||
}
|
||||
if ( sView != view ) {
|
||||
Logger.w( TAG, "view do not added." );
|
||||
return;
|
||||
}
|
||||
if ( view == null ) {
|
||||
return;
|
||||
}
|
||||
sFloatingLayout.removeView( view );
|
||||
sView = null;
|
||||
sPriority = Integer.MIN_VALUE;
|
||||
sMovable = false;
|
||||
DispatchTouchEventWrapper.getInstance().release();
|
||||
}
|
||||
|
||||
private static void addView() {
|
||||
if ( sView == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT );
|
||||
params.leftMargin = sX;
|
||||
params.topMargin = sY;
|
||||
sFloatingLayout.addView( sView, params );
|
||||
}
|
||||
|
||||
public static void attachMovementEvent( View view, WindowManager.LayoutParams params ) {
|
||||
if ( view == null ) {
|
||||
return;
|
||||
}
|
||||
view.setOnTouchListener( ( v, event ) -> {
|
||||
DispatchTouchEventWrapper.getInstance()
|
||||
.attach( view, params )
|
||||
.handle( event );
|
||||
return false;
|
||||
} );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user