This commit is contained in:
wangcongtao
2020-01-12 17:06:40 +08:00
parent d9834271be
commit 612be92dae
12 changed files with 81 additions and 53 deletions

View File

@@ -3,6 +3,7 @@ package com.mogo.module.extensions.anim;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@@ -91,7 +92,7 @@ public class JSurfaceView extends SurfaceView implements Runnable, SurfaceHolder
return;
}
//绘制透明色
mCanvas.drawColor( Color.parseColor( "#0C0C0C" ) );
mCanvas.drawColor( Color.parseColor( "#EE0C0C0C" ) );
Bitmap mBitmap = BitmapFactory.decodeResource( getResources(), mFrames[mCurrentPos % mFrames.length] );
Paint paint = new Paint();

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_120"
android:background="#0C0C0C "
android:background="#EE0C0C0C"
android:orientation="vertical"
android:paddingLeft="@dimen/dp_70"
android:paddingRight="@dimen/dp_70">

View File

@@ -26,6 +26,11 @@ android {
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {

View File

@@ -12,6 +12,7 @@
android:resumeWhilePausing="true"
android:screenOrientation="landscape"
android:stateNotNeeded="true"
android:theme="@style/Main"
android:taskAffinity=""
android:windowSoftInputMode="adjustPan">
<intent-filter>

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 ) {
}
}

View File

@@ -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;
} );
}
}

View File

@@ -40,9 +40,9 @@
android:id="@+id/module_main_id_cards_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:layout_marginBottom="@dimen/dp_211"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingBottom="@dimen/dp_20" />
<!-- 应用入口-->
<FrameLayout
@@ -64,6 +64,12 @@
</LinearLayout>
<!-- 浮层-->
<FrameLayout
android:id="@+id/module_main_id_floating_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/module_main_id_search_fragment"
android:layout_width="match_parent"

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Main" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">false</item>
<item name="android:statusBarColor" tools:ignore="NewApi">@null</item>
<item name="android:windowEnterAnimation">@null</item>
<item name="android:windowExitAnimation">@null</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">#EE0C0C0C</item>
<item name="android:windowTranslucentNavigation">false</item>
<item name="android:windowAnimationStyle">@style/MainAnimation</item>
</style>
<style name="MainAnimation">
<item name="android:activityOpenEnterAnimation">@null</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@null</item>
<item name="android:taskOpenEnterAnimation">@null</item>
<item name="android:taskOpenExitAnimation">@null</item>
<item name="android:taskCloseEnterAnimation">@null</item>
<item name="android:taskCloseExitAnimation">@null</item>
<item name="android:taskToFrontEnterAnimation">@null</item>
<item name="android:taskToFrontExitAnimation">@null</item>
<item name="android:taskToBackEnterAnimation">@null</item>
<item name="android:taskToBackExitAnimation">@null</item>
</style>
</resources>