Merge branch 'dev/dev_eagle_architecture_upgrade' into dev/dev_eagle_wuhan_sikua_obu
This commit is contained in:
@@ -29,14 +29,13 @@ import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public
|
||||
/*
|
||||
* @author congtaowang
|
||||
* @since 2020/10/30
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
class BaseDrawer {
|
||||
/*
|
||||
* @author congtaowang
|
||||
* @since 2020/10/30
|
||||
* <p>
|
||||
* 描述
|
||||
*/
|
||||
public class BaseDrawer {
|
||||
|
||||
// 移除过期的 marker
|
||||
public static final int MSG_REMOVE_DIRTY_MARKERS = 9990;
|
||||
|
||||
@@ -5,13 +5,12 @@ import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.eagle.core.data.map.MogoLatLng
|
||||
import com.mogo.map.marker.IMogoMarker
|
||||
import com.mogo.map.marker.MogoMarkerOptions
|
||||
import com.mogo.module.common.MogoApisHandler
|
||||
import com.mogo.module.common.constants.DataTypes
|
||||
import com.mogo.module.common.drawer.bean.TrafficData
|
||||
import com.mogo.module.common.enums.TrafficTypeEnum
|
||||
import com.mogo.eagle.core.data.traffic.TrafficData
|
||||
import com.mogo.eagle.core.data.enums.TrafficTypeEnum
|
||||
import com.mogo.utils.WorkThreadHandler
|
||||
import com.mogo.utils.logger.Logger
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
package com.mogo.module.common.drawer.bean;
|
||||
|
||||
import com.mogo.module.common.enums.TrafficTypeEnum;
|
||||
|
||||
/**
|
||||
* @author xiaoyuzhou
|
||||
* @date 2021/8/17 8:41 下午
|
||||
* 交通元素数据,
|
||||
*/
|
||||
public class TrafficData {
|
||||
|
||||
/**
|
||||
* 交通元素类型, 车、人、摩托、大巴车、卡车、自行车
|
||||
*/
|
||||
public TrafficTypeEnum type;
|
||||
|
||||
/**
|
||||
* 识别物体唯一标识
|
||||
*/
|
||||
public String uuid;
|
||||
|
||||
/**
|
||||
* 识别物体的纬度
|
||||
*/
|
||||
public double lat;
|
||||
|
||||
/**
|
||||
* 识别物体的经度
|
||||
*/
|
||||
public double lon;
|
||||
|
||||
/**
|
||||
* 车头朝向
|
||||
*/
|
||||
public double heading;
|
||||
|
||||
/**
|
||||
* 系统时间
|
||||
*/
|
||||
public long systemTime;
|
||||
|
||||
/**
|
||||
* 定位卫星时间
|
||||
*/
|
||||
public long satelliteTime;
|
||||
|
||||
/**
|
||||
* 海拔
|
||||
*/
|
||||
public double alt;
|
||||
|
||||
/**
|
||||
* 速度
|
||||
*/
|
||||
public double speed;
|
||||
|
||||
/**
|
||||
* 莫顿码
|
||||
*/
|
||||
public long mortonCode;
|
||||
|
||||
/**
|
||||
* 实际距离
|
||||
* 使用distanceX和distanceY计算
|
||||
*/
|
||||
public double distance;
|
||||
|
||||
/**
|
||||
* 危险等级
|
||||
* range(0..3)
|
||||
* 0x00: 保留
|
||||
* 0x01: 模型原始颜色
|
||||
* 0x02: 通知 -- 黄
|
||||
* 0x03: 警告 -- 红
|
||||
*/
|
||||
public int threatLevel;
|
||||
}
|
||||
@@ -202,7 +202,7 @@ enum class EventTypeEnum(
|
||||
"限速预警",
|
||||
poiTypeSrcVr=R.drawable.icon_warning_v2x_over_speed,
|
||||
content="已超速",
|
||||
tts=""
|
||||
tts="已超速"
|
||||
),
|
||||
TYPE_USECASE_ID_LTA(
|
||||
ObuConstants.USE_CASE_ID.LTA.toString(),
|
||||
@@ -223,7 +223,7 @@ enum class EventTypeEnum(
|
||||
"车内标牌",
|
||||
poiTypeSrcVr=R.drawable.icon_warning_v2x_road_construction,
|
||||
content="前方施工",
|
||||
tts=""
|
||||
tts="前方施工"
|
||||
),
|
||||
TYPE_USECASE_ID_TJW(
|
||||
ObuConstants.USE_CASE_ID.TJW.toString(),
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
package com.mogo.module.common.enums
|
||||
|
||||
import com.mogo.module.common.R
|
||||
|
||||
/**
|
||||
* @author xiaoyuzhou
|
||||
* @date 2021/8/18 11:39 上午
|
||||
* 交通元素类型
|
||||
*/
|
||||
enum class TrafficTypeEnum(
|
||||
var type: Int,
|
||||
var desc: String,
|
||||
var traffic2DIconId: Int,
|
||||
var traffic3DIconId: Int
|
||||
) {
|
||||
|
||||
TYPE_TRAFFIC_ID_WEI_ZHI(
|
||||
0,
|
||||
"未知数据",
|
||||
R.raw.special_vehicle,
|
||||
R.raw.special_vehicle
|
||||
),
|
||||
TYPE_TRAFFIC_ID_PEOPLE(
|
||||
1,
|
||||
"人",
|
||||
R.raw.people,
|
||||
R.raw.people
|
||||
),
|
||||
TYPE_TRAFFIC_ID_BICYCLE(
|
||||
2,
|
||||
"自行车",
|
||||
R.raw.zixingche,
|
||||
R.raw.zixingche
|
||||
),
|
||||
TYPE_TRAFFIC_ID_TA_CHE(
|
||||
3,
|
||||
"他车",
|
||||
R.raw.special_vehicle,
|
||||
R.raw.special_vehicle
|
||||
),
|
||||
TYPE_TRAFFIC_ID_MOTO(
|
||||
4,
|
||||
"摩托",
|
||||
R.raw.motuoche,
|
||||
R.raw.motuoche
|
||||
),
|
||||
TYPE_TRAFFIC_ID_BUS(
|
||||
6,
|
||||
"大巴",
|
||||
R.raw.daba,
|
||||
R.raw.daba
|
||||
),
|
||||
TYPE_TRAFFIC_ID_TRUCK(
|
||||
8,
|
||||
"卡车",
|
||||
R.raw.daba,
|
||||
R.raw.daba
|
||||
),
|
||||
TYPE_TRAFFIC_ID_SPECIAL_VEHICLE(
|
||||
11,
|
||||
"特殊车辆",
|
||||
R.raw.special_vehicle,
|
||||
R.raw.special_vehicle
|
||||
),
|
||||
TYPE_TRAFFIC_ID_DAO_LU_SHI_GONG(
|
||||
12,
|
||||
"道路施工",
|
||||
R.raw.v2x_shigong_warning,
|
||||
R.raw.v2x_shigong_warning
|
||||
)
|
||||
|
||||
}
|
||||
@@ -1,337 +0,0 @@
|
||||
package com.mogo.module.common.widget;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.ColorRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
|
||||
import com.mogo.module.common.R;
|
||||
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
public class CustomCircleImageView extends ImageView {
|
||||
|
||||
private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
|
||||
|
||||
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
|
||||
private static final int COLORDRAWABLE_DIMENSION = 2;
|
||||
|
||||
private static final int DEFAULT_BORDER_WIDTH = 0;
|
||||
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
|
||||
private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
|
||||
private static final boolean DEFAULT_BORDER_OVERLAY = false;
|
||||
|
||||
private final RectF mDrawableRect = new RectF();
|
||||
private final RectF mBorderRect = new RectF();
|
||||
|
||||
private final Matrix mShaderMatrix = new Matrix();
|
||||
private final Paint mBitmapPaint = new Paint();
|
||||
private final Paint mBorderPaint = new Paint();
|
||||
private final Paint mFillPaint = new Paint();
|
||||
|
||||
private int mBorderColor = DEFAULT_BORDER_COLOR;
|
||||
private int mBorderWidth = DEFAULT_BORDER_WIDTH;
|
||||
private int mFillColor = DEFAULT_FILL_COLOR;
|
||||
|
||||
private Bitmap mBitmap;
|
||||
private BitmapShader mBitmapShader;
|
||||
private int mBitmapWidth;
|
||||
private int mBitmapHeight;
|
||||
|
||||
private float mDrawableRadius;
|
||||
private float mBorderRadius;
|
||||
|
||||
private ColorFilter mColorFilter;
|
||||
|
||||
private boolean mReady;
|
||||
private boolean mSetupPending;
|
||||
private boolean mBorderOverlay;
|
||||
|
||||
public CustomCircleImageView( Context context) {
|
||||
super(context);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
public CustomCircleImageView( Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CustomCircleImageView( Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomCircleImageView, defStyle, 0);
|
||||
|
||||
mBorderWidth = a.getDimensionPixelSize(R.styleable.CustomCircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
|
||||
mBorderColor = a.getColor(R.styleable.CustomCircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
|
||||
mBorderOverlay = a.getBoolean(R.styleable.CustomCircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
|
||||
mFillColor = a.getColor(R.styleable.CustomCircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);
|
||||
|
||||
a.recycle();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
super.setScaleType(SCALE_TYPE);
|
||||
mReady = true;
|
||||
|
||||
if (mSetupPending) {
|
||||
setup();
|
||||
mSetupPending = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleType getScaleType() {
|
||||
return SCALE_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleType(ScaleType scaleType) {
|
||||
if (scaleType != SCALE_TYPE) {
|
||||
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdjustViewBounds(boolean adjustViewBounds) {
|
||||
if (adjustViewBounds) {
|
||||
throw new IllegalArgumentException("adjustViewBounds not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mBitmap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFillColor != Color.TRANSPARENT) {
|
||||
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mFillPaint);
|
||||
}
|
||||
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mBitmapPaint);
|
||||
if (mBorderWidth != 0) {
|
||||
canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mBorderRadius, mBorderPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
setup();
|
||||
}
|
||||
|
||||
public int getBorderColor() {
|
||||
return mBorderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(@ColorInt int borderColor) {
|
||||
if (borderColor == mBorderColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBorderColor = borderColor;
|
||||
mBorderPaint.setColor(mBorderColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setBorderColorResource(@ColorRes int borderColorRes) {
|
||||
setBorderColor(getContext().getResources().getColor(borderColorRes));
|
||||
}
|
||||
|
||||
public int getFillColor() {
|
||||
return mFillColor;
|
||||
}
|
||||
|
||||
public void setFillColor(@ColorInt int fillColor) {
|
||||
if (fillColor == mFillColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFillColor = fillColor;
|
||||
mFillPaint.setColor(fillColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setFillColorResource(@ColorRes int fillColorRes) {
|
||||
setFillColor(getContext().getResources().getColor(fillColorRes));
|
||||
}
|
||||
|
||||
public int getBorderWidth() {
|
||||
return mBorderWidth;
|
||||
}
|
||||
|
||||
public void setBorderWidth(int borderWidth) {
|
||||
if (borderWidth == mBorderWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBorderWidth = borderWidth;
|
||||
setup();
|
||||
}
|
||||
|
||||
public boolean isBorderOverlay() {
|
||||
return mBorderOverlay;
|
||||
}
|
||||
|
||||
public void setBorderOverlay(boolean borderOverlay) {
|
||||
if (borderOverlay == mBorderOverlay) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBorderOverlay = borderOverlay;
|
||||
setup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageBitmap(Bitmap bm) {
|
||||
super.setImageBitmap(bm);
|
||||
mBitmap = bm;
|
||||
setup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageDrawable(Drawable drawable) {
|
||||
super.setImageDrawable(drawable);
|
||||
mBitmap = getBitmapFromDrawable(drawable);
|
||||
setup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageResource(@DrawableRes int resId) {
|
||||
super.setImageResource(resId);
|
||||
mBitmap = getBitmapFromDrawable(getDrawable());
|
||||
setup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageURI(Uri uri) {
|
||||
super.setImageURI(uri);
|
||||
mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null;
|
||||
setup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
if (cf == mColorFilter) {
|
||||
return;
|
||||
}
|
||||
|
||||
mColorFilter = cf;
|
||||
mBitmapPaint.setColorFilter(mColorFilter);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private Bitmap getBitmapFromDrawable(Drawable drawable) {
|
||||
if (drawable == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (drawable instanceof BitmapDrawable) {
|
||||
return ((BitmapDrawable) drawable).getBitmap();
|
||||
}
|
||||
|
||||
try {
|
||||
Bitmap bitmap;
|
||||
|
||||
if (drawable instanceof ColorDrawable) {
|
||||
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
|
||||
} else {
|
||||
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
|
||||
}
|
||||
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
if (!mReady) {
|
||||
mSetupPending = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (getWidth() == 0 && getHeight() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mBitmap == null) {
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
|
||||
mBitmapPaint.setAntiAlias(true);
|
||||
mBitmapPaint.setShader(mBitmapShader);
|
||||
|
||||
mBorderPaint.setStyle(Paint.Style.STROKE);
|
||||
mBorderPaint.setAntiAlias(true);
|
||||
mBorderPaint.setColor(mBorderColor);
|
||||
mBorderPaint.setStrokeWidth(mBorderWidth);
|
||||
|
||||
mFillPaint.setStyle(Paint.Style.FILL);
|
||||
mFillPaint.setAntiAlias(true);
|
||||
mFillPaint.setColor(mFillColor);
|
||||
|
||||
mBitmapHeight = mBitmap.getHeight();
|
||||
mBitmapWidth = mBitmap.getWidth();
|
||||
|
||||
mBorderRect.set(0, 0, getWidth(), getHeight());
|
||||
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
|
||||
|
||||
mDrawableRect.set(mBorderRect);
|
||||
if (!mBorderOverlay) {
|
||||
mDrawableRect.inset(mBorderWidth, mBorderWidth);
|
||||
}
|
||||
mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
|
||||
|
||||
updateShaderMatrix();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void updateShaderMatrix() {
|
||||
float scale;
|
||||
float dx = 0;
|
||||
float dy = 0;
|
||||
|
||||
mShaderMatrix.set(null);
|
||||
|
||||
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
|
||||
scale = mDrawableRect.height() / (float) mBitmapHeight;
|
||||
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
|
||||
} else {
|
||||
scale = mDrawableRect.width() / (float) mBitmapWidth;
|
||||
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
|
||||
}
|
||||
|
||||
mShaderMatrix.setScale(scale, scale);
|
||||
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
|
||||
|
||||
mBitmapShader.setLocalMatrix(mShaderMatrix);
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,12 +7,7 @@
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CustomCircleImageView">
|
||||
<attr name="civ_border_width" format="dimension" />
|
||||
<attr name="civ_border_color" format="color" />
|
||||
<attr name="civ_border_overlay" format="boolean" />
|
||||
<attr name="civ_fill_color" format="color" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CustomRatingBar">
|
||||
<!--宽-->
|
||||
<attr name="elenmentWidth" format="dimension" />
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
package com.mogo.module.extensions.entrance;
|
||||
|
||||
import static com.mogo.module.common.utils.SPConst.getSPGuideRecord;
|
||||
import static com.mogo.module.common.utils.SPConst.getSpGuide;
|
||||
import static com.mogo.module.extensions.ExtensionsModuleConst.TYPE_ENTRANCE;
|
||||
import static com.mogo.module.service.receiver.MogoReceiver.ACTION_V2X_REMOVE_TIP_WINDOW;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_CLICK_SHARE_BUTTON;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_CLICK_SHARE_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SERVER_SHOW_DAY_COUNT;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_INNER_GUIDE;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_INNER_GUIDE_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_OUTER_GUIDE;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_OUTER_GUIDE_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.ONE_DAY_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.SEVEN_DAY_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.VOICE_ALERT_COUNT;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.location.Location;
|
||||
@@ -14,7 +29,6 @@ import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckedTextView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
@@ -72,8 +86,6 @@ import com.mogo.module.extensions.utils.TopViewNoLinkageAnimHelper;
|
||||
import com.mogo.module.service.receiver.MogoReceiver;
|
||||
import com.mogo.module.share.manager.ServiceApisManager;
|
||||
import com.mogo.service.IMogoServiceApis;
|
||||
import com.mogo.service.adas.IMogoAdasOCHCallback;
|
||||
import com.mogo.service.adas.entity.AdasOCHData;
|
||||
import com.mogo.service.analytics.IMogoAnalytics;
|
||||
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
|
||||
import com.mogo.service.entrance.ButtonIndex;
|
||||
@@ -101,21 +113,6 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import static com.mogo.module.common.utils.SPConst.getSPGuideRecord;
|
||||
import static com.mogo.module.common.utils.SPConst.getSpGuide;
|
||||
import static com.mogo.module.extensions.ExtensionsModuleConst.TYPE_ENTRANCE;
|
||||
import static com.mogo.module.service.receiver.MogoReceiver.ACTION_V2X_REMOVE_TIP_WINDOW;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_CLICK_SHARE_BUTTON;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_CLICK_SHARE_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SERVER_SHOW_DAY_COUNT;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_INNER_GUIDE;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_INNER_GUIDE_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_OUTER_GUIDE;
|
||||
import static com.mogo.module.share.constant.ShareConstants.KEY_SHARE_OUTER_GUIDE_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.ONE_DAY_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.SEVEN_DAY_TIME;
|
||||
import static com.mogo.module.share.constant.ShareConstants.VOICE_ALERT_COUNT;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020-01-07
|
||||
@@ -129,9 +126,8 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
IMogoAimlessModeListener,
|
||||
IMogoStatusChangedListener,
|
||||
IMogoIntentListener,
|
||||
// IMogoLocationListener,
|
||||
IMogoCheckListener ,
|
||||
IMogoAdasOCHCallback,
|
||||
// IMogoLocationListener,
|
||||
IMogoCheckListener,
|
||||
IMogoCarLocationChangedListener2 {
|
||||
|
||||
private static final String TAG = "EntranceFragment";
|
||||
@@ -215,7 +211,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
private TextView tvRed;
|
||||
private TextView tvGreen;
|
||||
|
||||
private CheckedTextView ctvAutopilotStatus;
|
||||
// private CheckedTextView ctvAutopilotStatus;
|
||||
|
||||
/**
|
||||
* 内部变量标识是否在vrMode,用于方法执行过滤,避免重复或异常调用
|
||||
@@ -285,7 +281,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
mMove2CurrentLocation = findViewById(R.id.module_entrance_id_move2_current_location);
|
||||
mUserHeadImg = findViewById(R.id.ivUserHeadImg);
|
||||
groupFix = findViewById(R.id.groupFix);
|
||||
ctvAutopilotStatus = findViewById(R.id.module_mogo_autopilot_status);
|
||||
// ctvAutopilotStatus = findViewById(R.id.module_mogo_autopilot_status);
|
||||
|
||||
ConstraintLayout rootView = findViewById(R.id.module_entrance_id_top_motion_layout);
|
||||
if (rootView != null) {
|
||||
@@ -356,16 +352,14 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
});
|
||||
}
|
||||
|
||||
onAutopilotStatusChanged(
|
||||
MogoApisHandler.getInstance().getApis().getAdasControllerApi().getAutopilotStatus() == IMogoAdasOCHCallback.STATUS_AUTOPILOT_RUNNING);
|
||||
|
||||
ctvAutopilotStatus.setOnClickListener(new OnPreventFastClickListener() {
|
||||
@Override
|
||||
public void onClickImpl(View v) {
|
||||
// 如果能自动驾驶,就自动驾驶,不能就提示
|
||||
autopilotStatusClick();
|
||||
}
|
||||
});
|
||||
// ctvAutopilotStatus.setOnClickListener(new OnPreventFastClickListener() {
|
||||
// @Override
|
||||
// public void onClickImpl(View v) {
|
||||
// // 如果能自动驾驶,就自动驾驶,不能就提示
|
||||
// autopilotStatusClick();
|
||||
// }
|
||||
// });
|
||||
|
||||
dealWeatherContainer();
|
||||
|
||||
@@ -400,7 +394,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
enterVrMode();
|
||||
localIsVrMode = true;
|
||||
}
|
||||
// //检测入口
|
||||
// //检测入口
|
||||
jumpCheck = findViewById(R.id.module_ext_enter_check);
|
||||
tipImageView = findViewById(R.id.error_tip_image);
|
||||
jumpCheck.setOnClickListener(new View.OnClickListener() {
|
||||
@@ -414,21 +408,6 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动驾驶状态改变
|
||||
*
|
||||
* @param isInAutopilot true - 在自动驾驶中 false - 不在自动驾驶中
|
||||
*/
|
||||
public void onAutopilotStatusChanged(boolean isInAutopilot) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
ctvAutopilotStatus.setChecked(isInAutopilot);
|
||||
});
|
||||
}
|
||||
|
||||
private void autopilotStatusClick() {
|
||||
EntranceViewHolder.getInstance().entranceAutopilotStatusClick();
|
||||
}
|
||||
|
||||
private int debugPanelClickCount = 0;
|
||||
private long lastDebugPanelClickTime = 0;
|
||||
|
||||
@@ -443,8 +422,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
mMsgContainer.setVisibility(View.GONE);
|
||||
groupUserHead.setVisibility(View.GONE);
|
||||
groupUserHead.setVisibility(View.GONE);
|
||||
ctvAutopilotStatus.setVisibility(View.VISIBLE);
|
||||
// tvExitVrMode.setVisibility(View.VISIBLE);
|
||||
// tvExitVrMode.setVisibility(View.VISIBLE);
|
||||
TopViewAnimHelper.getInstance().enterVrMode();
|
||||
TopViewNoLinkageAnimHelper.getInstance().enterVrMode();
|
||||
mNaviInfo = vrModeNavInfoView;
|
||||
@@ -586,7 +564,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
if (intervalTime == 0) {
|
||||
SharedPrefsMgr.getInstance(getContext()).putLong(KEY_SHARE_OUTER_GUIDE_TIME, time);
|
||||
SharedPrefsMgr.getInstance(getContext()).putInt(KEY_SHARE_OUTER_GUIDE, ++shareItemSum);
|
||||
// AIAssist.getInstance(getContext()).speakTTSVoice(mOuterGuideVoiceStrings[random.nextInt(3)]);
|
||||
// AIAssist.getInstance(getContext()).speakTTSVoice(mOuterGuideVoiceStrings[random.nextInt(3)]);
|
||||
AIAssist.getInstance(getContext()).speakTTSVoice(mOuterGuideVoiceStrings[0]);
|
||||
} else {
|
||||
Logger.d(TAG, " playShareOuterGuideVoice else interval = " + (time - intervalTime));
|
||||
@@ -745,7 +723,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
|
||||
mMogoRegisterCenter.registerMogoNaviListener(TYPE_ENTRANCE, this);
|
||||
mMogoRegisterCenter.registerMogoMapListener(TYPE_ENTRANCE, this);
|
||||
//车辆监控
|
||||
//车辆监控
|
||||
CallerCheckManager.registerVehicleMonitoringListener(MogoReceiver.ACTION_CHECK_VEHICLE_MONITORING, this);
|
||||
|
||||
mMogoMarkerManager = mService.getMarkerManager(getContext());
|
||||
@@ -885,15 +863,15 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
} else {
|
||||
mExitNavi.setText(R.string.module_ext_str_continue_navi);
|
||||
}
|
||||
// if ( isLock ) {
|
||||
// if ( mMApUIController.getCurrentUiMode() == EnumMapUI.CarUp_2D ) {
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.icon_north_up );
|
||||
// } else {
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.icon_car_up );
|
||||
// }
|
||||
// } else {
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.module_map_ic_move2_current_location );
|
||||
// }
|
||||
// if ( isLock ) {
|
||||
// if ( mMApUIController.getCurrentUiMode() == EnumMapUI.CarUp_2D ) {
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.icon_north_up );
|
||||
// } else {
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.icon_car_up );
|
||||
// }
|
||||
// } else {
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.module_map_ic_move2_current_location );
|
||||
// }
|
||||
}
|
||||
|
||||
private void traceData(String from) {
|
||||
@@ -1008,14 +986,14 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
|
||||
private void debugTopView() {
|
||||
findViewById(R.id.btnDebugCtrlNaviView).setOnClickListener(view -> {
|
||||
// SharedPrefsMgr.getInstance(getContext()).putString("MY_LOCATION_CONFIG", "https" +
|
||||
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705236512" +
|
||||
// "&di=50620661ded7035fb84899a408f9f27e&imgtype=0&src=http%3A%2F%2Fb-ssl" +
|
||||
// ".duitang.com%2Fuploads%2Fitem%2F201409%2F11%2F20140911211243_3rT4u.jpeg");
|
||||
// MyLocationUtil.setMyLocationIconUrl(getContext(), "https" +
|
||||
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705236512" +
|
||||
// "&di=50620661ded7035fb84899a408f9f27e&imgtype=0&src=http%3A%2F%2Fb-ssl" +
|
||||
// ".duitang.com%2Fuploads%2Fitem%2F201409%2F11%2F20140911211243_3rT4u.jpeg");
|
||||
// SharedPrefsMgr.getInstance(getContext()).putString("MY_LOCATION_CONFIG", "https" +
|
||||
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705236512" +
|
||||
// "&di=50620661ded7035fb84899a408f9f27e&imgtype=0&src=http%3A%2F%2Fb-ssl" +
|
||||
// ".duitang.com%2Fuploads%2Fitem%2F201409%2F11%2F20140911211243_3rT4u.jpeg");
|
||||
// MyLocationUtil.setMyLocationIconUrl(getContext(), "https" +
|
||||
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705236512" +
|
||||
// "&di=50620661ded7035fb84899a408f9f27e&imgtype=0&src=http%3A%2F%2Fb-ssl" +
|
||||
// ".duitang.com%2Fuploads%2Fitem%2F201409%2F11%2F20140911211243_3rT4u.jpeg");
|
||||
if (!toggle) {
|
||||
TopViewAnimHelper.getInstance().showNaviView();
|
||||
} else {
|
||||
@@ -1025,7 +1003,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
});
|
||||
|
||||
findViewById(R.id.btnDebugCtrlSubView).setOnClickListener(view -> {
|
||||
// MyLocationUtil.emphasizeMyLocation();
|
||||
// MyLocationUtil.emphasizeMyLocation();
|
||||
View v = LayoutInflater.from(getContext()).inflate(R.layout.demo_top, null);
|
||||
TextView tv = v.findViewById(R.id.tvIndex);
|
||||
tv.setText("sub view height: " + currentHeight + ": " + v);
|
||||
@@ -1053,17 +1031,17 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
});
|
||||
|
||||
findViewById(R.id.btnDebugCtrlTopView).setOnClickListener(view -> {
|
||||
// SharedPrefsMgr.getInstance(getContext()).putString("MY_LOCATION_CONFIG", "https" +
|
||||
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705508574" +
|
||||
// "&di=339d3259ad21f5f48c8abcd1bafff324&imgtype=0&src=http%3A%2F%2Fc-ssl" +
|
||||
// ".duitang.com%2Fuploads%2Fitem%2F202004%2F23%2F20200423111550_4AJLr.thumb" +
|
||||
// ".1000_0.jpeg");
|
||||
// MyLocationUtil.setMyLocationIconUrl(getContext(),"https" +
|
||||
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705508574" +
|
||||
// "&di=339d3259ad21f5f48c8abcd1bafff324&imgtype=0&src=http%3A%2F%2Fc-ssl" +
|
||||
// ".duitang.com%2Fuploads%2Fitem%2F202004%2F23%2F20200423111550_4AJLr.thumb" +
|
||||
// ".1000_0.jpeg");
|
||||
// MyLocationUtil.emphasizeMyLocation();
|
||||
// SharedPrefsMgr.getInstance(getContext()).putString("MY_LOCATION_CONFIG", "https" +
|
||||
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705508574" +
|
||||
// "&di=339d3259ad21f5f48c8abcd1bafff324&imgtype=0&src=http%3A%2F%2Fc-ssl" +
|
||||
// ".duitang.com%2Fuploads%2Fitem%2F202004%2F23%2F20200423111550_4AJLr.thumb" +
|
||||
// ".1000_0.jpeg");
|
||||
// MyLocationUtil.setMyLocationIconUrl(getContext(),"https" +
|
||||
// "://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1605705508574" +
|
||||
// "&di=339d3259ad21f5f48c8abcd1bafff324&imgtype=0&src=http%3A%2F%2Fc-ssl" +
|
||||
// ".duitang.com%2Fuploads%2Fitem%2F202004%2F23%2F20200423111550_4AJLr.thumb" +
|
||||
// ".1000_0.jpeg");
|
||||
// MyLocationUtil.emphasizeMyLocation();
|
||||
View v = LayoutInflater.from(getContext()).inflate(R.layout.demo_top, null);
|
||||
TextView tv = v.findViewById(R.id.tvIndex);
|
||||
Random random = new Random();
|
||||
@@ -1071,7 +1049,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
tv.setText(" height: " + currentHeight + ": " + v);
|
||||
ViewGroup.LayoutParams params =
|
||||
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, currentHeight);
|
||||
// mApis.getEntranceButtonController().addLeftFeatureView(v);
|
||||
// mApis.getEntranceButtonController().addLeftFeatureView(v);
|
||||
|
||||
mApis.getTopViewManager().addView(v, params, new IMogoTopViewStatusListener() {
|
||||
@Override
|
||||
@@ -1114,12 +1092,12 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
mMsgContainer.setVisibility(View.GONE);
|
||||
|
||||
|
||||
// String enthusiasmIndex = "一般的字加粗的字一般的字";
|
||||
// SpannableString spannableStringUnSelectCountStr = new SpannableString(enthusiasmIndex);
|
||||
// ForegroundColorSpan foregroundColorSpanUnSelectCount = new ForegroundColorSpan(Color.RED);
|
||||
// spannableStringUnSelectCountStr.setSpan(foregroundColorSpanUnSelectCount, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
//
|
||||
// TipToast.tip(spannableStringUnSelectCountStr.toString());
|
||||
// String enthusiasmIndex = "一般的字加粗的字一般的字";
|
||||
// SpannableString spannableStringUnSelectCountStr = new SpannableString(enthusiasmIndex);
|
||||
// ForegroundColorSpan foregroundColorSpanUnSelectCount = new ForegroundColorSpan(Color.RED);
|
||||
// spannableStringUnSelectCountStr.setSpan(foregroundColorSpanUnSelectCount, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
//
|
||||
// TipToast.tip(spannableStringUnSelectCountStr.toString());
|
||||
TipDrawable drawable =
|
||||
new TipDrawable(getResources().getDrawable(R.drawable.model_ext_default_user_head));
|
||||
TipToast.tip("分享成功", drawable);
|
||||
@@ -1136,11 +1114,11 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
mCameraMode.setSelected(ui == EnumMapUI.NorthUP_2D);
|
||||
mCameraMode.setText(getString(ui == EnumMapUI.NorthUP_2D ? R.string.mode_car_up : R.string.mode_north_up));
|
||||
|
||||
// if ( ui == EnumMapUI.CarUp_2D ) {
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.icon_north_up );
|
||||
// } else if( ui == EnumMapUI.NorthUP_2D ){
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.icon_car_up );
|
||||
// }
|
||||
// if ( ui == EnumMapUI.CarUp_2D ) {
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.icon_north_up );
|
||||
// } else if( ui == EnumMapUI.NorthUP_2D ){
|
||||
// mMove2CurrentLocation.setImageResource( R.drawable.icon_car_up );
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -1424,20 +1402,13 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMonitoringStatus(boolean hasError){
|
||||
Log.d(TAG,"updateCheckStatus");
|
||||
if(hasError==true){
|
||||
tipImageView.setVisibility(View.VISIBLE);
|
||||
}else{
|
||||
tipImageView.setVisibility(View.INVISIBLE);
|
||||
public void updateMonitoringStatus(boolean hasError) {
|
||||
Log.d(TAG, "updateCheckStatus");
|
||||
if (hasError == true) {
|
||||
tipImageView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
tipImageView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
public void onArriveAt(AdasOCHData data) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int state, String reason) {
|
||||
ctvAutopilotStatus.setChecked(state == IMogoAdasOCHCallback.STATUS_AUTOPILOT_RUNNING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.module.extensions.utils.EntranceViewHolder;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
import com.mogo.service.entrance.ButtonIndex;
|
||||
import com.mogo.service.entrance.IMogoEntranceAutopilotStatusClickListener;
|
||||
import com.mogo.service.entrance.IMogoEntranceButtonController;
|
||||
import com.mogo.service.windowview.IMogoEntranceViewListener;
|
||||
|
||||
@@ -71,16 +70,6 @@ public class MogoEntranceButtonControllerImpl implements IMogoEntranceButtonCont
|
||||
EntranceViewHolder.getInstance().removeEntranceViewListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntranceAutopilotStatusClickListener(IMogoEntranceAutopilotStatusClickListener listener) {
|
||||
EntranceViewHolder.getInstance().addEntranceAutopilotStatusClickListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntranceAutopilotStatusClickListener(IMogoEntranceAutopilotStatusClickListener listener) {
|
||||
EntranceViewHolder.getInstance().removeEntranceAutopilotStatusClickListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init( Context context ) {
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import android.widget.TextView;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.mogo.eagle.core.view.LiveRoundLayout;
|
||||
import com.mogo.eagle.core.widget.LiveRoundLayout;
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
import com.tencent.rtmp.ITXLivePlayListener;
|
||||
|
||||
@@ -12,7 +12,6 @@ import android.widget.TextView;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.module.extensions.bean.BottomLayerViewWrapper;
|
||||
import com.mogo.service.entrance.IMogoEntranceAutopilotStatusClickListener;
|
||||
import com.mogo.service.windowview.IMogoEntranceViewListener;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
@@ -133,7 +132,7 @@ public class EntranceViewHolder {
|
||||
View v = wrapper.getView();
|
||||
v.setLayoutParams(params);
|
||||
rootViewGroup.addView(v, 0);
|
||||
// rootViewGroup.setBackgroundColor(Color.WHITE);
|
||||
// rootViewGroup.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
|
||||
public void removeBottomLayerView(View view) {
|
||||
@@ -270,7 +269,6 @@ public class EntranceViewHolder {
|
||||
}
|
||||
|
||||
private final List<IMogoEntranceViewListener> listeners = new ArrayList<>();
|
||||
private final List<IMogoEntranceAutopilotStatusClickListener> btnClickListeners = new ArrayList<>();
|
||||
|
||||
public void addEntranceViewListener(IMogoEntranceViewListener listener) {
|
||||
listeners.add(listener);
|
||||
@@ -280,20 +278,6 @@ public class EntranceViewHolder {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void addEntranceAutopilotStatusClickListener(IMogoEntranceAutopilotStatusClickListener listener) {
|
||||
btnClickListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeEntranceAutopilotStatusClickListener(IMogoEntranceAutopilotStatusClickListener listener) {
|
||||
btnClickListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void entranceAutopilotStatusClick() {
|
||||
for (IMogoEntranceAutopilotStatusClickListener listener : btnClickListeners) {
|
||||
listener.click();
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
rootViewGroup = null;
|
||||
featureViewGroup = null;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_checked="true">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:bottomLeftRadius="20px" android:bottomRightRadius="45px" android:topLeftRadius="45px" android:topRightRadius="20px" />
|
||||
<gradient android:angle="315" android:endColor="#2B6EFF" android:startColor="#2B6EFF" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:bottomLeftRadius="20px" android:bottomRightRadius="45px" android:topLeftRadius="45px" android:topRightRadius="20px" />
|
||||
<gradient android:angle="315" android:endColor="#3B4577" android:startColor="#3B4577" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mogo.eagle.core.view.LiveRoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.mogo.eagle.core.widget.LiveRoundLayout 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"
|
||||
@@ -65,4 +65,4 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/ivErrorIcon" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.mogo.eagle.core.view.LiveRoundLayout>
|
||||
</com.mogo.eagle.core.widget.LiveRoundLayout>
|
||||
|
||||
@@ -6,27 +6,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<CheckedTextView
|
||||
android:id="@+id/module_mogo_autopilot_status"
|
||||
android:layout_width="@dimen/module_mogo_autopilot_status_bg_width"
|
||||
android:layout_height="@dimen/module_mogo_autopilot_status_bg_height"
|
||||
android:layout_marginLeft="@dimen/module_mogo_autopilot_status_margin_left"
|
||||
android:layout_marginTop="@dimen/module_mogo_autopilot_status_margin_top"
|
||||
android:background="@drawable/module_mogo_autopilot_status_bg"
|
||||
android:drawableLeft="@drawable/module_ext_ic_autopilot"
|
||||
android:drawablePadding="@dimen/dp_30"
|
||||
android:elevation="@dimen/dp_10"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
android:paddingLeft="@dimen/module_mogo_autopilot_status_padding"
|
||||
android:text="自动驾驶"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="@dimen/module_mogo_autopilot_status_text_size"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
layout="@layout/module_ext_layout_extensions"
|
||||
android:layout_width="match_parent"
|
||||
@@ -359,6 +338,7 @@
|
||||
android:id="@+id/error_tip_image"
|
||||
android:layout_width="@dimen/dp_40"
|
||||
android:layout_height="@dimen/dp_40"
|
||||
android:visibility="invisible"
|
||||
android:src="@drawable/check_error_image"
|
||||
app:layout_constraintRight_toRightOf="@+id/module_ext_enter_check"
|
||||
app:layout_constraintTop_toTopOf="@+id/module_ext_enter_check" />
|
||||
|
||||
@@ -9,10 +9,5 @@
|
||||
<dimen name="module_switch_image">50px</dimen>
|
||||
<dimen name="module_switch_image_circle">60px</dimen>
|
||||
|
||||
<dimen name="module_mogo_autopilot_status_bg_width">460px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_bg_height">140px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_margin_left">20px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_margin_top">530px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_padding">92px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_text_size">44px</dimen>
|
||||
|
||||
</resources>
|
||||
@@ -251,11 +251,5 @@
|
||||
<dimen name="module_switch_image">35px</dimen>
|
||||
<dimen name="module_switch_image_circle">38px</dimen>
|
||||
|
||||
<dimen name="module_mogo_autopilot_status_bg_width">300px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_bg_height">100px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_margin_left">20px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_margin_top">345px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_padding">20px</dimen>
|
||||
<dimen name="module_mogo_autopilot_status_text_size">30px</dimen>
|
||||
|
||||
</resources>
|
||||
@@ -468,14 +468,7 @@ public class MainActivity extends MvpActivity<MainView, MainPresenter> implement
|
||||
Logger.d(TAG, "requestCode: " + requestCode + " resultCode: " + resultCode);
|
||||
if (requestCode == REQUEST_CODE_DIALOG) {
|
||||
//申请悬浮窗权限
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// 检查是否有悬浮窗权限
|
||||
if (Settings.canDrawOverlays(this)) {
|
||||
startVoicePad();
|
||||
}
|
||||
} else {
|
||||
startVoicePad();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,11 +79,6 @@ public class PushModuleProvider implements IMogoModuleProvider {
|
||||
|
||||
@Override
|
||||
public void init(final Context context) {
|
||||
HandlerUtils.INSTANCE.getMBgHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PushRepository.Companion.init(context);
|
||||
}
|
||||
});
|
||||
HandlerUtils.INSTANCE.getMBgHandler().post(() -> PushRepository.Companion.init(context));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,9 @@ class PushRepository(mContext: Context) {
|
||||
} else {
|
||||
return
|
||||
}
|
||||
iterateNext()
|
||||
mHandler.post {
|
||||
iterateNext()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
package com.mogo.module.push.view
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.ObjectAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.PixelFormat
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.*
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.Scroller
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.view.isVisible
|
||||
import com.elegant.analytics.utils.Logger
|
||||
import com.mogo.commons.context.ContextHolderUtil
|
||||
import com.mogo.commons.voice.AIAssist
|
||||
import com.mogo.module.push.Config
|
||||
import com.mogo.module.push.R
|
||||
@@ -27,14 +20,15 @@ import com.mogo.module.push.view.roundimage.RoundedImageView
|
||||
import com.mogo.module.push.viewmodel.PushViewModel
|
||||
import com.mogo.service.windowview.IMogoTopViewManager
|
||||
import com.mogo.service.windowview.IMogoTopViewStatusListener
|
||||
import com.mogo.utils.ResourcesHelper
|
||||
import com.mogo.utils.ThreadPoolService
|
||||
import com.mogo.utils.UiThreadHandler
|
||||
import com.mogo.utils.glide.GlideApp
|
||||
import com.mogo.utils.logger.Logger
|
||||
import kotlin.math.log
|
||||
|
||||
class FloatView constructor(
|
||||
private val pushViewModel: PushViewModel,
|
||||
private val context: Context
|
||||
private val pushViewModel: PushViewModel,
|
||||
private val context: Context
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -46,44 +40,37 @@ class FloatView constructor(
|
||||
interface PushViewController {
|
||||
fun show(bean: PushBean?)
|
||||
fun hide()
|
||||
fun timer(time: Int)
|
||||
fun inflateView(@LayoutRes layoutId: Int)
|
||||
}
|
||||
|
||||
abstract inner class PushView(context: Context) : FrameLayout(context),
|
||||
PushViewController {
|
||||
private lateinit var appIcon: ImageView
|
||||
PushViewController {
|
||||
private lateinit var titleIconContainer: View
|
||||
private lateinit var pushTitle: TextView
|
||||
private lateinit var pushImage: RoundedImageView
|
||||
private lateinit var pushContent: TextView
|
||||
private lateinit var pushTimer: TextView
|
||||
private lateinit var pushButtonLeft: TextView
|
||||
private lateinit var pushButtonRight: TextView
|
||||
lateinit var pushButton: View
|
||||
private lateinit var pushCheck: TextView
|
||||
|
||||
private var pushData: PushBean? = null
|
||||
|
||||
override fun inflateView(layoutId: Int) {
|
||||
LayoutInflater.from(context).inflate(layoutId, this, true)
|
||||
appIcon = findViewById(R.id.module_push_app_icon)
|
||||
pushTitle = findViewById(R.id.module_push_title)
|
||||
pushCheck = findViewById(R.id.module_push_check)
|
||||
pushImage = findViewById(R.id.module_push_image)
|
||||
pushContent = findViewById(R.id.module_push_content)
|
||||
pushButtonLeft = findViewById(R.id.module_push_button_left)
|
||||
pushButtonRight = findViewById(R.id.module_push_button_right)
|
||||
pushTimer = findViewById(R.id.module_push_timer)
|
||||
titleIconContainer = findViewById(R.id.module_push_app_icon_title)
|
||||
pushButton = findViewById(R.id.module_push_buttons)
|
||||
setOnClickListener {
|
||||
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_MAIN, "1")
|
||||
turnNextMessage()
|
||||
}
|
||||
pushButtonLeft.setOnClickListener {
|
||||
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_LEFT, "1")
|
||||
turnNextMessage()
|
||||
}
|
||||
pushButtonRight.setOnClickListener {
|
||||
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_RIGHT, "1")
|
||||
turnNextMessage()
|
||||
pushCheck.setOnClickListener {
|
||||
pushData?.let {
|
||||
if (pushCheckDialog == null) {
|
||||
pushCheckDialog = PushCheckDialog(ContextHolderUtil.getContext())
|
||||
}
|
||||
pushCheckDialog!!.showCheckDialog(it.title, it.content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,35 +81,11 @@ class FloatView constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun hasButtons(bean: PushBean?): Boolean {
|
||||
bean?.buttons?.forEach {
|
||||
if (it.text.isNotEmpty()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun hasTextContent(bean: PushBean?): Boolean =
|
||||
bean?.content?.isEmpty()?.not() ?: false
|
||||
|
||||
fun hasImgContent(bean: PushBean?): Boolean = bean?.QRCode?.isEmpty()?.not() ?: false
|
||||
|
||||
open fun setBean(bean: PushBean) {
|
||||
// app icon
|
||||
if (bean.appIcon.isNotEmpty()) {
|
||||
appIcon.visible()
|
||||
GlideApp.with(this).load(bean.appIcon).into(appIcon)
|
||||
} else {
|
||||
appIcon.gone()
|
||||
}
|
||||
|
||||
pushData = bean
|
||||
// title
|
||||
pushTitle.text = bean.title
|
||||
|
||||
// decrease timer
|
||||
pushTimer.text = if (bean.showTimeout > 99) "" else "${bean.showTimeout}s"
|
||||
|
||||
// image
|
||||
if (bean.imageUrl.isEmpty() && bean.QRCode.isEmpty()) {
|
||||
pushImage.gone()
|
||||
@@ -140,9 +103,9 @@ class FloatView constructor(
|
||||
pushImage.layoutParams = params
|
||||
ThreadPoolService.execute {
|
||||
val bmp = stringConverterBitmap(
|
||||
bean.QRCode,
|
||||
getQrImgWidth(),
|
||||
getQrImgHeight()
|
||||
bean.QRCode,
|
||||
getQrImgWidth(),
|
||||
getQrImgHeight()
|
||||
)
|
||||
UiThreadHandler.post {
|
||||
pushImage.setImageBitmap(bmp)
|
||||
@@ -151,22 +114,6 @@ class FloatView constructor(
|
||||
}
|
||||
}
|
||||
|
||||
// button
|
||||
pushButton.gone()
|
||||
pushButtonLeft.gone()
|
||||
pushButtonRight.gone()
|
||||
if (!bean.buttons.isNullOrEmpty()) {
|
||||
if (bean.buttons[0].text.isNotEmpty()) {
|
||||
pushButton.visible()
|
||||
pushButtonLeft.text = bean.buttons[0].text
|
||||
pushButtonLeft.visible()
|
||||
}
|
||||
if (bean.buttons.size > 1 && bean.buttons[1].text.isNotEmpty()) {
|
||||
pushButtonRight.text = bean.buttons[1].text
|
||||
pushButtonRight.visible()
|
||||
}
|
||||
}
|
||||
|
||||
// content
|
||||
if (bean.content.isEmpty()) {
|
||||
pushContent.gone()
|
||||
@@ -175,10 +122,10 @@ class FloatView constructor(
|
||||
pushContent.visible()
|
||||
}
|
||||
|
||||
// tts
|
||||
if (bean.tts.isNotEmpty()) {
|
||||
AIAssist.getInstance(context).speakTTSVoice(bean.tts)
|
||||
}
|
||||
// 产品侧需要重新梳理,tts暂时不播报
|
||||
// if (bean.tts.isNotEmpty()) {
|
||||
// AIAssist.getInstance(context).speakTTSVoice(bean.tts)
|
||||
// }
|
||||
}
|
||||
|
||||
abstract fun getImgWidth(): Int
|
||||
@@ -186,12 +133,6 @@ class FloatView constructor(
|
||||
abstract fun getQrImgWidth(): Int
|
||||
abstract fun getQrImgHeight(): Int
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun timer(time: Int) {
|
||||
Logger.d(TAG, "time = $time")
|
||||
pushTimer.text = "${time}s"
|
||||
}
|
||||
|
||||
override fun show(bean: PushBean?) {
|
||||
isAddWindow = true
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
@@ -252,184 +193,175 @@ class FloatView constructor(
|
||||
}
|
||||
|
||||
override fun getImgWidth(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width)
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width)
|
||||
|
||||
override fun getImgHeight(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
|
||||
override fun getQrImgWidth(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
|
||||
override fun getQrImgHeight(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
}
|
||||
|
||||
inner class PushViewInWindowView(context: Context) : PushView(context), View.OnTouchListener {
|
||||
|
||||
private val mContentContainer: View
|
||||
private val mWindowManager =
|
||||
context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
|
||||
private val params = WindowManager.LayoutParams()
|
||||
|
||||
init {
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
|
||||
params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
|
||||
or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE
|
||||
or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
|
||||
or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
|
||||
params.width = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
params.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
params.gravity = Gravity.START or Gravity.BOTTOM
|
||||
params.format = PixelFormat.TRANSLUCENT
|
||||
params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
|
||||
params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
|
||||
if (Build.VERSION.SDK_INT > 25) {
|
||||
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
|
||||
}
|
||||
|
||||
inflateView(R.layout.module_push_item_vertical)
|
||||
mContentContainer = findViewById(R.id.module_push_content_container)
|
||||
setOnTouchListener(this)
|
||||
}
|
||||
|
||||
override fun show(bean: PushBean?) {
|
||||
super.show(bean)
|
||||
mLastVisibleType = TYPE_WINDOW_MANAGER
|
||||
setBean(bean!!)
|
||||
|
||||
try {
|
||||
mWindowManager.addView(this, params)
|
||||
} catch (e: Exception) {
|
||||
mWindowManager.updateViewLayout(this, params)
|
||||
}
|
||||
translationXAnimation(
|
||||
-ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical),
|
||||
0f
|
||||
) {
|
||||
if (pushViewModel.pushBean != null) {
|
||||
startClosePush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translationXAnimation(
|
||||
from: Float,
|
||||
to: Float,
|
||||
doOnEnd: (animator: Animator) -> Unit
|
||||
) {
|
||||
val transitionXAnimator: ObjectAnimator =
|
||||
ObjectAnimator.ofFloat(
|
||||
this,
|
||||
View.TRANSLATION_X,
|
||||
from,
|
||||
to
|
||||
)
|
||||
transitionXAnimator.duration = 200
|
||||
transitionXAnimator.doOnEnd(doOnEnd)
|
||||
transitionXAnimator.start()
|
||||
}
|
||||
|
||||
override fun setBean(bean: PushBean) {
|
||||
super.setBean(bean)
|
||||
var paddingBottom = 0
|
||||
if (pushButton.isVisible) {
|
||||
paddingBottom =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_content_paddingBottom_vertical)
|
||||
}
|
||||
mContentContainer.setPadding(0, 0, 0, paddingBottom)
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
super.hide()
|
||||
translationXAnimation(
|
||||
this.x,
|
||||
-ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical)
|
||||
) {
|
||||
Logger.d(TAG, "here")
|
||||
this.x = 0f
|
||||
mWindowManager.removeViewImmediate(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouch(v: View?, ev: MotionEvent?): Boolean {
|
||||
|
||||
if (mLastVisibleType != TYPE_WINDOW_MANAGER) {
|
||||
return false
|
||||
}
|
||||
when (ev?.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
needInterceptClick = false
|
||||
startX = ev.x
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
moveX = startX - ev.x
|
||||
scrollBy(moveX.toInt(), 0)
|
||||
startX = ev.x
|
||||
if (scrollX < 0) {
|
||||
scrollTo(0, 0)
|
||||
}
|
||||
if (!needInterceptClick && scrollX > 20) {
|
||||
needInterceptClick = true
|
||||
}
|
||||
invalidate()
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
if (scrollX > 0) {
|
||||
mScroller.startScroll(scrollX, 0, width - scrollX, 0)
|
||||
invalidate()
|
||||
return true
|
||||
}
|
||||
if (needInterceptClick) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
startX = 0f
|
||||
moveX = 0f
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun computeScroll() {
|
||||
if (mScroller.computeScrollOffset()) {
|
||||
scrollTo(mScroller.currX, mScroller.currY)
|
||||
invalidate()
|
||||
} else {
|
||||
if (mScroller.currX == 0) {
|
||||
return
|
||||
}
|
||||
mScroller.finalX = 0
|
||||
removeCallbacks(delayClosePush)
|
||||
if (isAddWindow) {
|
||||
if (currentBean != null) {
|
||||
AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1")
|
||||
}
|
||||
mWindowManager.removeView(this)
|
||||
isAddWindow = false
|
||||
}
|
||||
pushViewModel.pushBean?.showTimeout = 0
|
||||
updateTimer()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getImgWidth(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical)
|
||||
|
||||
override fun getImgHeight(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical)
|
||||
|
||||
override fun getQrImgWidth(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
|
||||
|
||||
override fun getQrImgHeight(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
|
||||
}
|
||||
// inner class PushViewInWindowView(context: Context) : PushView(context), View.OnTouchListener {
|
||||
//
|
||||
// private val mContentContainer: View
|
||||
// private val mWindowManager =
|
||||
// context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
//
|
||||
// private val params = WindowManager.LayoutParams()
|
||||
//
|
||||
// init {
|
||||
//
|
||||
// @Suppress("DEPRECATION")
|
||||
// params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
|
||||
// params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
// or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
|
||||
// or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE
|
||||
// or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
|
||||
// or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
|
||||
// params.width = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
// params.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
// params.gravity = Gravity.START or Gravity.BOTTOM
|
||||
// params.format = PixelFormat.TRANSLUCENT
|
||||
// params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
|
||||
// params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
|
||||
// if (Build.VERSION.SDK_INT > 25) {
|
||||
// params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
|
||||
// }
|
||||
//
|
||||
// inflateView(R.layout.module_push_item_vertical)
|
||||
// mContentContainer = findViewById(R.id.module_push_content_container)
|
||||
// setOnTouchListener(this)
|
||||
// }
|
||||
//
|
||||
// override fun show(bean: PushBean?) {
|
||||
// super.show(bean)
|
||||
// mLastVisibleType = TYPE_WINDOW_MANAGER
|
||||
// setBean(bean!!)
|
||||
//
|
||||
// try {
|
||||
// mWindowManager.addView(this, params)
|
||||
// } catch (e: Exception) {
|
||||
// mWindowManager.updateViewLayout(this, params)
|
||||
// }
|
||||
// translationXAnimation(
|
||||
// -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical),
|
||||
// 0f
|
||||
// ) {
|
||||
// if (pushViewModel.pushBean != null) {
|
||||
// startClosePush()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun translationXAnimation(
|
||||
// from: Float,
|
||||
// to: Float,
|
||||
// doOnEnd: (animator: Animator) -> Unit
|
||||
// ) {
|
||||
// val transitionXAnimator: ObjectAnimator =
|
||||
// ObjectAnimator.ofFloat(
|
||||
// this,
|
||||
// View.TRANSLATION_X,
|
||||
// from,
|
||||
// to
|
||||
// )
|
||||
// transitionXAnimator.duration = 200
|
||||
// transitionXAnimator.doOnEnd(doOnEnd)
|
||||
// transitionXAnimator.start()
|
||||
// }
|
||||
//
|
||||
// override fun hide() {
|
||||
// super.hide()
|
||||
// translationXAnimation(
|
||||
// this.x,
|
||||
// -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical)
|
||||
// ) {
|
||||
// Logger.d(TAG, "here")
|
||||
// this.x = 0f
|
||||
// mWindowManager.removeViewImmediate(this)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onTouch(v: View?, ev: MotionEvent?): Boolean {
|
||||
//
|
||||
// if (mLastVisibleType != TYPE_WINDOW_MANAGER) {
|
||||
// return false
|
||||
// }
|
||||
// when (ev?.action) {
|
||||
// MotionEvent.ACTION_DOWN -> {
|
||||
// needInterceptClick = false
|
||||
// startX = ev.x
|
||||
// }
|
||||
// MotionEvent.ACTION_MOVE -> {
|
||||
// moveX = startX - ev.x
|
||||
// scrollBy(moveX.toInt(), 0)
|
||||
// startX = ev.x
|
||||
// if (scrollX < 0) {
|
||||
// scrollTo(0, 0)
|
||||
// }
|
||||
// if (!needInterceptClick && scrollX > 20) {
|
||||
// needInterceptClick = true
|
||||
// }
|
||||
// invalidate()
|
||||
// }
|
||||
// MotionEvent.ACTION_UP -> {
|
||||
// if (scrollX > 0) {
|
||||
// mScroller.startScroll(scrollX, 0, width - scrollX, 0)
|
||||
// invalidate()
|
||||
// return true
|
||||
// }
|
||||
// if (needInterceptClick) {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// else -> {
|
||||
// startX = 0f
|
||||
// moveX = 0f
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
//
|
||||
// override fun computeScroll() {
|
||||
// if (mScroller.computeScrollOffset()) {
|
||||
// scrollTo(mScroller.currX, mScroller.currY)
|
||||
// invalidate()
|
||||
// } else {
|
||||
// if (mScroller.currX == 0) {
|
||||
// return
|
||||
// }
|
||||
// mScroller.finalX = 0
|
||||
// removeCallbacks(delayClosePush)
|
||||
// if (isAddWindow) {
|
||||
// if (currentBean != null) {
|
||||
// AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1")
|
||||
// }
|
||||
// mWindowManager.removeView(this)
|
||||
// isAddWindow = false
|
||||
// }
|
||||
// pushViewModel.pushBean?.showTimeout = 0
|
||||
// updateTimer()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun getImgWidth(): Int =
|
||||
// context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical)
|
||||
//
|
||||
// override fun getImgHeight(): Int =
|
||||
// context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical)
|
||||
//
|
||||
// override fun getQrImgWidth(): Int =
|
||||
// context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
|
||||
//
|
||||
// override fun getQrImgHeight(): Int =
|
||||
// context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
|
||||
// }
|
||||
|
||||
private var pushCheckDialog: PushCheckDialog? = null
|
||||
private val delayClosePush: Runnable
|
||||
private var isAddWindow = false
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
@@ -473,10 +405,8 @@ class FloatView constructor(
|
||||
val time = pushViewModel.pushBean?.showTimeout ?: 0
|
||||
if (time > 0) {
|
||||
pushViewModel.pushBean!!.showTimeout--
|
||||
pushViewController?.timer(time)
|
||||
uiHandler.postDelayed(delayClosePush, 1000)
|
||||
} else {
|
||||
pushViewController?.timer(0)
|
||||
pushViewModel.pushMessageFinish(true)
|
||||
}
|
||||
}
|
||||
@@ -520,17 +450,17 @@ class FloatView constructor(
|
||||
}
|
||||
|
||||
private fun showByWindowManager(bean: PushBean?) {
|
||||
if (pushViewController !is PushViewInWindowView) {
|
||||
pushViewController = PushViewInWindowView(context)
|
||||
}
|
||||
pushViewController?.show(bean)
|
||||
// if (pushViewController !is PushViewInWindowView) {
|
||||
// pushViewController = PushViewInWindowView(context)
|
||||
// }
|
||||
// pushViewController?.show(bean)
|
||||
}
|
||||
|
||||
private fun startClosePush() {
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
uiHandler.postDelayed(
|
||||
delayClosePush,
|
||||
1000L
|
||||
delayClosePush,
|
||||
1000L
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,568 @@
|
||||
package com.mogo.module.push.view
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.ObjectAnimator
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.PixelFormat
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.*
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.Scroller
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.core.view.isVisible
|
||||
import com.elegant.analytics.utils.Logger
|
||||
import com.mogo.commons.voice.AIAssist
|
||||
import com.mogo.module.push.Config
|
||||
import com.mogo.module.push.R
|
||||
import com.mogo.module.push.model.PushBean
|
||||
import com.mogo.module.push.utils.AnalyticsUtils
|
||||
import com.mogo.module.push.utils.stringConverterBitmap
|
||||
import com.mogo.module.push.view.roundimage.RoundedImageView
|
||||
import com.mogo.module.push.viewmodel.PushViewModel
|
||||
import com.mogo.service.windowview.IMogoTopViewManager
|
||||
import com.mogo.service.windowview.IMogoTopViewStatusListener
|
||||
import com.mogo.utils.ResourcesHelper
|
||||
import com.mogo.utils.ThreadPoolService
|
||||
import com.mogo.utils.UiThreadHandler
|
||||
import com.mogo.utils.glide.GlideApp
|
||||
|
||||
class FloatViewOrigin constructor(
|
||||
private val pushViewModel: PushViewModel,
|
||||
private val context: Context
|
||||
) {
|
||||
|
||||
companion object {
|
||||
const val TYPE_TOP_VIEW = 1
|
||||
const val TYPE_WINDOW_MANAGER = 2
|
||||
const val TAG: String = "FloatViewOrigin.kt"
|
||||
}
|
||||
|
||||
interface PushViewController {
|
||||
fun show(bean: PushBean?)
|
||||
fun hide()
|
||||
fun timer(time: Int)
|
||||
fun inflateView(@LayoutRes layoutId: Int)
|
||||
}
|
||||
|
||||
abstract inner class PushViewOrigin(context: Context) : FrameLayout(context),
|
||||
PushViewController {
|
||||
private lateinit var appIcon: ImageView
|
||||
private lateinit var titleIconContainer: View
|
||||
private lateinit var pushTitle: TextView
|
||||
private lateinit var pushImage: RoundedImageView
|
||||
private lateinit var pushContent: TextView
|
||||
private lateinit var pushTimer: TextView
|
||||
private lateinit var pushButtonLeft: TextView
|
||||
private lateinit var pushButtonRight: TextView
|
||||
lateinit var pushButton: View
|
||||
|
||||
override fun inflateView(layoutId: Int) {
|
||||
LayoutInflater.from(context).inflate(layoutId, this, true)
|
||||
appIcon = findViewById(R.id.module_push_app_icon)
|
||||
pushTitle = findViewById(R.id.module_push_title)
|
||||
pushImage = findViewById(R.id.module_push_image)
|
||||
pushContent = findViewById(R.id.module_push_content)
|
||||
pushButtonLeft = findViewById(R.id.module_push_button_left)
|
||||
pushButtonRight = findViewById(R.id.module_push_button_right)
|
||||
pushTimer = findViewById(R.id.module_push_timer)
|
||||
titleIconContainer = findViewById(R.id.module_push_app_icon_title)
|
||||
pushButton = findViewById(R.id.module_push_buttons)
|
||||
setOnClickListener {
|
||||
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_MAIN, "1")
|
||||
turnNextMessage()
|
||||
}
|
||||
pushButtonLeft.setOnClickListener {
|
||||
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_LEFT, "1")
|
||||
turnNextMessage()
|
||||
}
|
||||
pushButtonRight.setOnClickListener {
|
||||
pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_RIGHT, "1")
|
||||
turnNextMessage()
|
||||
}
|
||||
}
|
||||
|
||||
private fun turnNextMessage() {
|
||||
pushViewModel.pushBean?.apply {
|
||||
showTimeout = 0
|
||||
updateTimer()
|
||||
}
|
||||
}
|
||||
|
||||
fun hasButtons(bean: PushBean?): Boolean {
|
||||
bean?.buttons?.forEach {
|
||||
if (it.text.isNotEmpty()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun hasTextContent(bean: PushBean?): Boolean =
|
||||
bean?.content?.isEmpty()?.not() ?: false
|
||||
|
||||
fun hasImgContent(bean: PushBean?): Boolean = bean?.QRCode?.isEmpty()?.not() ?: false
|
||||
|
||||
open fun setBean(bean: PushBean) {
|
||||
// app icon
|
||||
if (bean.appIcon.isNotEmpty()) {
|
||||
appIcon.visible()
|
||||
GlideApp.with(this).load(bean.appIcon).into(appIcon)
|
||||
} else {
|
||||
appIcon.gone()
|
||||
}
|
||||
|
||||
// title
|
||||
pushTitle.text = bean.title
|
||||
|
||||
// decrease timer
|
||||
pushTimer.text = if (bean.showTimeout > 99) "" else "${bean.showTimeout}s"
|
||||
|
||||
// image
|
||||
if (bean.imageUrl.isEmpty() && bean.QRCode.isEmpty()) {
|
||||
pushImage.gone()
|
||||
} else if (bean.imageUrl.isNotEmpty()) {
|
||||
val params = pushImage.layoutParams
|
||||
params.width = getImgWidth()
|
||||
params.height = getImgHeight()
|
||||
pushImage.layoutParams = params
|
||||
pushImage.visible()
|
||||
GlideApp.with(this).load(bean.imageUrl).into(pushImage)
|
||||
} else if (bean.QRCode.isNotEmpty()) {
|
||||
val params = pushImage.layoutParams
|
||||
params.width = getQrImgWidth()
|
||||
params.height = getQrImgHeight()
|
||||
pushImage.layoutParams = params
|
||||
ThreadPoolService.execute {
|
||||
val bmp = stringConverterBitmap(
|
||||
bean.QRCode,
|
||||
getQrImgWidth(),
|
||||
getQrImgHeight()
|
||||
)
|
||||
UiThreadHandler.post {
|
||||
pushImage.setImageBitmap(bmp)
|
||||
pushImage.visible()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// button
|
||||
pushButton.gone()
|
||||
pushButtonLeft.gone()
|
||||
pushButtonRight.gone()
|
||||
if (!bean.buttons.isNullOrEmpty()) {
|
||||
if (bean.buttons[0].text.isNotEmpty()) {
|
||||
pushButton.visible()
|
||||
pushButtonLeft.text = bean.buttons[0].text
|
||||
pushButtonLeft.visible()
|
||||
}
|
||||
if (bean.buttons.size > 1 && bean.buttons[1].text.isNotEmpty()) {
|
||||
pushButtonRight.text = bean.buttons[1].text
|
||||
pushButtonRight.visible()
|
||||
}
|
||||
}
|
||||
|
||||
// content
|
||||
if (bean.content.isEmpty()) {
|
||||
pushContent.gone()
|
||||
} else {
|
||||
pushContent.text = bean.content
|
||||
pushContent.visible()
|
||||
}
|
||||
|
||||
// tts
|
||||
if (bean.tts.isNotEmpty()) {
|
||||
AIAssist.getInstance(context).speakTTSVoice(bean.tts)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun getImgWidth(): Int
|
||||
abstract fun getImgHeight(): Int
|
||||
abstract fun getQrImgWidth(): Int
|
||||
abstract fun getQrImgHeight(): Int
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun timer(time: Int) {
|
||||
Logger.d(TAG, "time = $time")
|
||||
pushTimer.text = "${time}s"
|
||||
}
|
||||
|
||||
override fun show(bean: PushBean?) {
|
||||
isAddWindow = true
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
isAddWindow = false
|
||||
}
|
||||
}
|
||||
|
||||
open inner class PushViewInTopView(context: Context) : PushViewOrigin(context) {
|
||||
|
||||
private val mTopViewManager: IMogoTopViewManager = getApis(context).topViewManager
|
||||
|
||||
init {
|
||||
inflateView(R.layout.module_push_item_origin)
|
||||
}
|
||||
|
||||
private var topViewStatusListener = object : IMogoTopViewStatusListener {
|
||||
override fun onViewRemoved(view: View?) {
|
||||
isAddWindow = false
|
||||
if (pushViewModel.pushBean?.showTimeout ?: 0 > 0) {
|
||||
if (getApis(context).statusManagerApi.isV2XShow) {
|
||||
// 被中断的消息,需要再次被显示一次
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
pushViewModel.push()
|
||||
pushViewModel.pushMessageFinish()
|
||||
return
|
||||
}
|
||||
}
|
||||
pushViewModel.pushBean?.showTimeout = 0
|
||||
updateTimer()
|
||||
}
|
||||
|
||||
override fun onViewAdded(view: View?) {
|
||||
if (pushViewModel.pushBean != null) {
|
||||
startClosePush()
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeViewRemoveAnim(view: View?) {
|
||||
}
|
||||
|
||||
override fun beforeViewAddAnim(view: View?) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun show(bean: PushBean?) {
|
||||
super.show(bean)
|
||||
mLastVisibleType = TYPE_TOP_VIEW
|
||||
mTopViewManager.addView(this, topViewStatusListener)
|
||||
setBean(bean!!)
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
super.hide()
|
||||
mTopViewManager.removeView(this)
|
||||
}
|
||||
|
||||
override fun getImgWidth(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width)
|
||||
|
||||
override fun getImgHeight(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
|
||||
override fun getQrImgWidth(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
|
||||
override fun getQrImgHeight(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height)
|
||||
}
|
||||
|
||||
inner class PushViewInWindowView(context: Context) : PushViewOrigin(context), View.OnTouchListener {
|
||||
|
||||
private val mContentContainer: View
|
||||
private val mWindowManager =
|
||||
context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
|
||||
private val params = WindowManager.LayoutParams()
|
||||
|
||||
init {
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
|
||||
params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
|
||||
or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE
|
||||
or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
|
||||
or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
|
||||
params.width = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
params.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
params.gravity = Gravity.START or Gravity.BOTTOM
|
||||
params.format = PixelFormat.TRANSLUCENT
|
||||
params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
|
||||
params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x)
|
||||
if (Build.VERSION.SDK_INT > 25) {
|
||||
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
|
||||
}
|
||||
|
||||
inflateView(R.layout.module_push_item_vertical)
|
||||
mContentContainer = findViewById(R.id.module_push_content_container)
|
||||
setOnTouchListener(this)
|
||||
}
|
||||
|
||||
override fun show(bean: PushBean?) {
|
||||
super.show(bean)
|
||||
mLastVisibleType = TYPE_WINDOW_MANAGER
|
||||
setBean(bean!!)
|
||||
|
||||
try {
|
||||
mWindowManager.addView(this, params)
|
||||
} catch (e: Exception) {
|
||||
mWindowManager.updateViewLayout(this, params)
|
||||
}
|
||||
translationXAnimation(
|
||||
-ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical),
|
||||
0f
|
||||
) {
|
||||
if (pushViewModel.pushBean != null) {
|
||||
startClosePush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translationXAnimation(
|
||||
from: Float,
|
||||
to: Float,
|
||||
doOnEnd: (animator: Animator) -> Unit
|
||||
) {
|
||||
val transitionXAnimator: ObjectAnimator =
|
||||
ObjectAnimator.ofFloat(
|
||||
this,
|
||||
View.TRANSLATION_X,
|
||||
from,
|
||||
to
|
||||
)
|
||||
transitionXAnimator.duration = 200
|
||||
transitionXAnimator.doOnEnd(doOnEnd)
|
||||
transitionXAnimator.start()
|
||||
}
|
||||
|
||||
override fun setBean(bean: PushBean) {
|
||||
super.setBean(bean)
|
||||
var paddingBottom = 0
|
||||
if (pushButton.isVisible) {
|
||||
paddingBottom =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_content_paddingBottom_vertical)
|
||||
}
|
||||
mContentContainer.setPadding(0, 0, 0, paddingBottom)
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
super.hide()
|
||||
translationXAnimation(
|
||||
this.x,
|
||||
-ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical)
|
||||
) {
|
||||
Logger.d(TAG, "here")
|
||||
this.x = 0f
|
||||
mWindowManager.removeViewImmediate(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouch(v: View?, ev: MotionEvent?): Boolean {
|
||||
|
||||
if (mLastVisibleType != TYPE_WINDOW_MANAGER) {
|
||||
return false
|
||||
}
|
||||
when (ev?.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
needInterceptClick = false
|
||||
startX = ev.x
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
moveX = startX - ev.x
|
||||
scrollBy(moveX.toInt(), 0)
|
||||
startX = ev.x
|
||||
if (scrollX < 0) {
|
||||
scrollTo(0, 0)
|
||||
}
|
||||
if (!needInterceptClick && scrollX > 20) {
|
||||
needInterceptClick = true
|
||||
}
|
||||
invalidate()
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
if (scrollX > 0) {
|
||||
mScroller.startScroll(scrollX, 0, width - scrollX, 0)
|
||||
invalidate()
|
||||
return true
|
||||
}
|
||||
if (needInterceptClick) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
startX = 0f
|
||||
moveX = 0f
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun computeScroll() {
|
||||
if (mScroller.computeScrollOffset()) {
|
||||
scrollTo(mScroller.currX, mScroller.currY)
|
||||
invalidate()
|
||||
} else {
|
||||
if (mScroller.currX == 0) {
|
||||
return
|
||||
}
|
||||
mScroller.finalX = 0
|
||||
removeCallbacks(delayClosePush)
|
||||
if (isAddWindow) {
|
||||
if (currentBean != null) {
|
||||
AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1")
|
||||
}
|
||||
mWindowManager.removeView(this)
|
||||
isAddWindow = false
|
||||
}
|
||||
pushViewModel.pushBean?.showTimeout = 0
|
||||
updateTimer()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getImgWidth(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical)
|
||||
|
||||
override fun getImgHeight(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical)
|
||||
|
||||
override fun getQrImgWidth(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
|
||||
|
||||
override fun getQrImgHeight(): Int =
|
||||
context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical)
|
||||
}
|
||||
|
||||
private val delayClosePush: Runnable
|
||||
private var isAddWindow = false
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
private var startX = 0f
|
||||
private var moveX = 0f
|
||||
private val mScroller: Scroller = Scroller(context)
|
||||
private var needInterceptClick = false
|
||||
private var pause = false
|
||||
|
||||
private var currentBean: PushBean? = null
|
||||
|
||||
|
||||
private var mLastVisibleType = -1
|
||||
private var pushViewController: PushViewController? = null
|
||||
|
||||
init {
|
||||
delayClosePush = Runnable {
|
||||
updateTimer()
|
||||
}
|
||||
}
|
||||
|
||||
fun pushBeanChanged(bean: PushBean?) {
|
||||
uiHandler.post {
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
if (bean == null) {
|
||||
if (currentBean != null) {
|
||||
AnalyticsUtils.track(Config.NEWS_CARD_DISAPPEAR, "title", currentBean!!.title)
|
||||
}
|
||||
hide()
|
||||
} else {
|
||||
show(bean)
|
||||
AnalyticsUtils.track(Config.NEWS_CARD_SHOW, "title", bean.title)
|
||||
}
|
||||
currentBean = bean
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTimer() {
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
val time = pushViewModel.pushBean?.showTimeout ?: 0
|
||||
if (time > 0) {
|
||||
pushViewModel.pushBean!!.showTimeout--
|
||||
pushViewController?.timer(time)
|
||||
uiHandler.postDelayed(delayClosePush, 1000)
|
||||
} else {
|
||||
pushViewController?.timer(0)
|
||||
pushViewModel.pushMessageFinish(true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun show(bean: PushBean) {
|
||||
if (isAddWindow) {
|
||||
if (getApis(context).statusManagerApi.isMainPageOnResume) {
|
||||
if (mLastVisibleType != TYPE_TOP_VIEW) {
|
||||
hide()
|
||||
(pushViewController as View).postDelayed({
|
||||
show(bean)
|
||||
}, 750L)
|
||||
} else {
|
||||
showByTopView(bean)
|
||||
}
|
||||
} else {
|
||||
if (mLastVisibleType != TYPE_WINDOW_MANAGER) {
|
||||
hide()
|
||||
(pushViewController as View).postDelayed({
|
||||
show(bean)
|
||||
}, 750L)
|
||||
} else {
|
||||
showByWindowManager(bean)
|
||||
}
|
||||
}
|
||||
startClosePush()
|
||||
} else {
|
||||
if (getApis(context).statusManagerApi.isMainPageOnResume) {
|
||||
showByTopView(bean)
|
||||
} else {
|
||||
showByWindowManager(bean)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showByTopView(bean: PushBean) {
|
||||
if (pushViewController !is PushViewInTopView) {
|
||||
pushViewController = PushViewInTopView(context)
|
||||
}
|
||||
pushViewController?.show(bean)
|
||||
}
|
||||
|
||||
private fun showByWindowManager(bean: PushBean?) {
|
||||
if (pushViewController !is PushViewInWindowView) {
|
||||
pushViewController = PushViewInWindowView(context)
|
||||
}
|
||||
pushViewController?.show(bean)
|
||||
}
|
||||
|
||||
private fun startClosePush() {
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
uiHandler.postDelayed(
|
||||
delayClosePush,
|
||||
1000L
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun hide() {
|
||||
if (!isAddWindow) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
pushViewController?.hide()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun pauseTimer(on: Boolean) {
|
||||
if (on) {
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
} else {
|
||||
updateTimer()
|
||||
uiHandler.post {
|
||||
if (on) {
|
||||
pause = true
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
} else if (pause) {
|
||||
pause = false
|
||||
updateTimer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isAddWindow(): Boolean = isAddWindow
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.mogo.module.push.view
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.mogo.module.common.dialog.BaseFloatDialog
|
||||
import com.mogo.module.push.R
|
||||
|
||||
class PushCheckDialog(context: Context) : BaseFloatDialog(context) {
|
||||
|
||||
private var pushCheckClose: ImageView? = null
|
||||
private var pushCheckTitle: TextView? = null
|
||||
private var pushCheckContent: TextView? = null
|
||||
|
||||
init {
|
||||
setContentView(R.layout.module_push_dialog_check)
|
||||
setCanceledOnTouchOutside(true)
|
||||
pushCheckClose = findViewById(R.id.module_push_dialog_close)
|
||||
pushCheckTitle = findViewById(R.id.module_push_dialog_title)
|
||||
pushCheckContent = findViewById(R.id.module_push_dialog_content)
|
||||
pushCheckClose?.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun showCheckDialog(title: String, content: String) {
|
||||
if (isShowing) {
|
||||
return
|
||||
}
|
||||
if (title.isBlank() || content.isBlank()) {
|
||||
return
|
||||
}
|
||||
pushCheckTitle?.text = title
|
||||
pushCheckContent?.text = content
|
||||
show()
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/module_push_check_dialog_bg_color" />
|
||||
<corners android:radius="@dimen/module_push_dialog_check_bg_corner" />
|
||||
</shape>
|
||||
@@ -1,7 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?><!--<selector xmlns:android="http://schemas.android.com/apk/res/android">-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<gradient
|
||||
android:angle="135"
|
||||
android:endColor="#33000000"
|
||||
android:startColor="#33000000"
|
||||
android:type="linear" />
|
||||
<corners android:radius="@dimen/module_push_ui_bkg_corner" />
|
||||
<solid android:color="#F23F4057" />
|
||||
</shape>
|
||||
|
||||
|
||||
@@ -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/module_push_ui_bkg_corner" />
|
||||
<solid android:color="#F23F4057" />
|
||||
</shape>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="@dimen/module_push_dialog_check_width"
|
||||
android:layout_height="@dimen/module_push_dialog_check_height"
|
||||
android:background="@drawable/module_push_dialog_check_background">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/module_push_dialog_close"
|
||||
android:layout_width="@dimen/module_push_dialog_close_width"
|
||||
android:layout_height="@dimen/module_push_dialog_close_height"
|
||||
android:layout_marginLeft="@dimen/module_push_dialog_close_margin"
|
||||
android:layout_marginTop="@dimen/module_push_dialog_close_margin"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/module_push_dialog_close"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_dialog_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/module_push_dialog_title_margin"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/module_push_dialog_title_size"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_dialog_content"
|
||||
android:layout_width="@dimen/module_push_dialog_content_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/module_push_dialog_content_margin_top"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/module_push_dialog_content_size"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/module_push_dialog_title" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -4,18 +4,19 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/module_push_ui_height"
|
||||
android:background="@drawable/module_push_item_background_p">
|
||||
android:layout_marginTop="@dimen/module_push_ui_margin_top"
|
||||
android:background="@drawable/module_push_item_background">
|
||||
|
||||
<com.mogo.module.push.view.roundimage.RoundedImageView
|
||||
android:id="@+id/module_push_image"
|
||||
android:layout_width="@dimen/module_push_ui_image_width"
|
||||
android:layout_height="@dimen/module_push_ui_image_height"
|
||||
android:layout_marginLeft="@dimen/module_push_ui_image_marLeft"
|
||||
android:scaleType="fitXY"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:riv_corner_radius="@dimen/module_push_ui_image_corner" />
|
||||
app:riv_corner_radius_bottom_left="@dimen/module_push_ui_image_corner"
|
||||
app:riv_corner_radius_top_left="@dimen/module_push_ui_image_corner" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/module_push_app_icon_title"
|
||||
@@ -24,19 +25,10 @@
|
||||
android:layout_marginLeft="@dimen/module_push_ui_app_icon_leftMargin"
|
||||
android:layout_marginTop="@dimen/module_push_ui_app_icon_topMargin"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/module_push_ui_app_icon_size"
|
||||
app:layout_constraintRight_toLeftOf="@+id/module_push_progress_bar_frame"
|
||||
app:layout_constraintLeft_toRightOf="@+id/module_push_image"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_goneMarginTop="@dimen/module_push_ui_app_icon_goneTopMargin">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/module_push_app_icon"
|
||||
android:layout_width="@dimen/module_push_ui_app_icon_size"
|
||||
android:layout_height="@dimen/module_push_ui_app_icon_size"
|
||||
android:layout_marginRight="@dimen/module_push_title_margin_start"
|
||||
android:background="@drawable/module_push_ui_ic_message2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_title"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -44,102 +36,59 @@
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical|left"
|
||||
android:maxWidth="@dimen/module_push_title_mix_width"
|
||||
android:singleLine="true"
|
||||
android:maxLength="25"
|
||||
tools:text="标题标题标题标题标题标题标题"
|
||||
android:singleLine="true"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/module_push_ui_title_textSize"
|
||||
app:layout_constrainedWidth="true" />
|
||||
app:layout_constrainedWidth="true"
|
||||
tools:text="官方公告" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:id="@+id/module_push_rl_content"
|
||||
android:layout_width="@dimen/module_push_ui_content_width"
|
||||
android:layout_height="@dimen/module_push_ui_content_height"
|
||||
android:layout_marginTop="@dimen/module_push_ui_content_marginTop"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginBottom="@dimen/module_push_ui_content_marginBottom"
|
||||
app:layout_constraintLeft_toLeftOf="@id/module_push_app_icon_title"
|
||||
app:layout_constraintRight_toRightOf="@id/module_push_progress_bar_frame"
|
||||
app:layout_constraintTop_toBottomOf="@id/module_push_app_icon_title">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:maxLines="3"
|
||||
android:layout_above="@+id/module_push_buttons"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="3"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/module_push_ui_title_text_size"
|
||||
tools:text="文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内" />
|
||||
android:textSize="@dimen/module_push_ui_title_text_size" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/module_push_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/module_push_button_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginTop="@dimen/module_push_button_margin_top"
|
||||
android:layout_marginBottom="@dimen/module_push_button_margin_bottom"
|
||||
android:gravity="center"
|
||||
android:weightSum="2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_button_left"
|
||||
android:layout_width="@dimen/module_push_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/module_push_left_button"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:enabled="true"
|
||||
android:lines="1"
|
||||
android:maxWidth="@dimen/module_push_button_maxWidth"
|
||||
android:maxLength="6"
|
||||
android:text="查看"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="@dimen/module_push_title_text_size"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_button_right"
|
||||
android:layout_width="@dimen/module_push_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/module_push_button_right_marLeft"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/module_push_right_button"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:maxWidth="@dimen/module_push_button_maxWidth"
|
||||
android:maxLength="6"
|
||||
android:text="忽略"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="@dimen/module_push_title_text_size"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/module_push_progress_bar_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/module_push_progress_bar_frame_marginTop"
|
||||
android:layout_marginEnd="@dimen/module_push_progress_bar_frame_marginEnd"
|
||||
android:background="@drawable/module_push_decrease_timer_bkg"
|
||||
android:paddingLeft="@dimen/module_push_progress_bar_frame_padding"
|
||||
android:paddingRight="@dimen/module_push_progress_bar_frame_padding"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
<View
|
||||
android:id="@+id/module_push_line"
|
||||
android:layout_width="@dimen/module_push_line_width"
|
||||
android:layout_height="@dimen/module_push_line_height"
|
||||
android:layout_marginLeft="@dimen/module_push_line_margin_left"
|
||||
android:background="@color/module_push_item_line_color"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/module_push_rl_content"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_timer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:textColor="#80FFFFFF"
|
||||
android:textSize="@dimen/module_push_ui_timer_textSize"
|
||||
tools:text="11s" />
|
||||
</FrameLayout>
|
||||
<TextView
|
||||
android:id="@+id/module_push_check"
|
||||
android:layout_width="@dimen/module_push_check_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/module_push_check_margin"
|
||||
android:layout_marginBottom="@dimen/module_push_check_margin"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/module_push_check"
|
||||
android:textColor="@color/module_push_check_color"
|
||||
android:textSize="@dimen/module_push_check_text_size"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/module_push_line"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="@dimen/module_push_ui_height"
|
||||
android:background="@drawable/module_push_item_background_p">
|
||||
|
||||
<com.mogo.module.push.view.roundimage.RoundedImageView
|
||||
android:id="@+id/module_push_image"
|
||||
android:layout_width="@dimen/module_push_ui_image_width"
|
||||
android:layout_height="@dimen/module_push_ui_image_height"
|
||||
android:layout_marginLeft="@dimen/module_push_ui_image_marLeft"
|
||||
android:scaleType="fitXY"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:riv_corner_radius="@dimen/module_push_ui_image_corner" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/module_push_app_icon_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/module_push_ui_app_icon_leftMargin"
|
||||
android:layout_marginTop="@dimen/module_push_ui_app_icon_topMargin"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/module_push_ui_app_icon_size"
|
||||
app:layout_constraintRight_toLeftOf="@+id/module_push_progress_bar_frame"
|
||||
app:layout_constraintLeft_toRightOf="@+id/module_push_image"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_goneMarginTop="@dimen/module_push_ui_app_icon_goneTopMargin">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/module_push_app_icon"
|
||||
android:layout_width="@dimen/module_push_ui_app_icon_size"
|
||||
android:layout_height="@dimen/module_push_ui_app_icon_size"
|
||||
android:layout_marginRight="@dimen/module_push_title_margin_start"
|
||||
android:background="@drawable/module_push_ui_ic_message2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical|left"
|
||||
android:maxWidth="@dimen/module_push_title_mix_width"
|
||||
android:singleLine="true"
|
||||
android:maxLength="25"
|
||||
tools:text="标题标题标题标题标题标题标题"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/module_push_ui_title_textSize"
|
||||
app:layout_constrainedWidth="true" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="@dimen/module_push_ui_content_marginTop"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="@id/module_push_app_icon_title"
|
||||
app:layout_constraintRight_toRightOf="@id/module_push_progress_bar_frame"
|
||||
app:layout_constraintTop_toBottomOf="@id/module_push_app_icon_title">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:maxLines="3"
|
||||
android:layout_above="@+id/module_push_buttons"
|
||||
android:ellipsize="end"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/module_push_ui_title_text_size"
|
||||
tools:text="文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内文本内容文本内容文本内" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/module_push_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/module_push_button_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginTop="@dimen/module_push_button_margin_top"
|
||||
android:layout_marginBottom="@dimen/module_push_button_margin_bottom"
|
||||
android:gravity="center"
|
||||
android:weightSum="2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_button_left"
|
||||
android:layout_width="@dimen/module_push_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/module_push_left_button"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:enabled="true"
|
||||
android:lines="1"
|
||||
android:maxWidth="@dimen/module_push_button_maxWidth"
|
||||
android:maxLength="6"
|
||||
android:text="查看"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="@dimen/module_push_title_text_size"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_button_right"
|
||||
android:layout_width="@dimen/module_push_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/module_push_button_right_marLeft"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/module_push_right_button"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:maxWidth="@dimen/module_push_button_maxWidth"
|
||||
android:maxLength="6"
|
||||
android:text="忽略"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="@dimen/module_push_title_text_size"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/module_push_progress_bar_frame"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/module_push_progress_bar_frame_marginTop"
|
||||
android:layout_marginEnd="@dimen/module_push_progress_bar_frame_marginEnd"
|
||||
android:background="@drawable/module_push_decrease_timer_bkg"
|
||||
android:paddingLeft="@dimen/module_push_progress_bar_frame_padding"
|
||||
android:paddingRight="@dimen/module_push_progress_bar_frame_padding"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_timer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:textColor="#80FFFFFF"
|
||||
android:textSize="@dimen/module_push_ui_timer_textSize"
|
||||
tools:text="11s" />
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="@dimen/module_push_ui_width_vertical"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/module_push_item_background"
|
||||
android:background="@drawable/module_push_item_background_origin"
|
||||
android:maxHeight="@dimen/module_push_item_maxHeight_vertical"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="@dimen/module_push_ui_app_icon_leftMargin_vertical"
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
|
||||
<dimen name="module_push_ui_height">230px</dimen>
|
||||
<dimen name="module_push_ui_image_width">230px</dimen>
|
||||
<dimen name="module_push_ui_image_height">230px</dimen>
|
||||
<dimen name="module_push_ui_image_corner">30px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin">21px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin">34px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_goneTopMargin">33px</dimen>
|
||||
<dimen name="module_push_line_width">2px</dimen>
|
||||
<dimen name="module_push_line_height">120px</dimen>
|
||||
<dimen name="module_push_line_margin_left">30px</dimen>
|
||||
<dimen name="module_push_check_margin">55px</dimen>
|
||||
<dimen name="module_push_check_text_size">42px</dimen>
|
||||
<dimen name="module_push_check_width">208px</dimen>
|
||||
<dimen name="module_push_title_mix_width">394px</dimen>
|
||||
<dimen name="module_push_ui_title_textSize">42px</dimen>
|
||||
<dimen name="module_push_ui_content_width">567px</dimen>
|
||||
<dimen name="module_push_ui_content_height">100px</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop">20px</dimen>
|
||||
<dimen name="module_push_ui_content_marginBottom">34px</dimen>
|
||||
<dimen name="module_push_ui_title_text_size">34px</dimen>
|
||||
|
||||
|
||||
<dimen name="module_push_dialog_check_width">1200px</dimen>
|
||||
<dimen name="module_push_dialog_check_height">763px</dimen>
|
||||
<dimen name="module_push_dialog_check_bg_corner">32px</dimen>
|
||||
<dimen name="module_push_dialog_close_width">107px</dimen>
|
||||
<dimen name="module_push_dialog_close_height">107px</dimen>
|
||||
<dimen name="module_push_dialog_close_margin">40px</dimen>
|
||||
<dimen name="module_push_dialog_title_margin">54px</dimen>
|
||||
<dimen name="module_push_dialog_title_size">56px</dimen>
|
||||
<dimen name="module_push_dialog_content_width">1000px</dimen>
|
||||
<dimen name="module_push_dialog_content_margin_top">33px</dimen>
|
||||
<dimen name="module_push_dialog_content_size">43px</dimen>
|
||||
<dimen name="module_push_ui_margin_top">20px</dimen>
|
||||
|
||||
</resources>
|
||||
@@ -4,4 +4,7 @@
|
||||
<color name="module_push_item_title_textColor">#FFFFFF</color>
|
||||
<color name="module_push_item_content_textColor">#B2FFFFFF</color>
|
||||
<color name="module_push_item_time_textColor">#999999</color>
|
||||
<color name="module_push_item_line_color">#B3FFFFFF</color>
|
||||
<color name="module_push_check_color">#5A8EFD</color>
|
||||
<color name="module_push_check_dialog_bg_color">#E63B4577</color>
|
||||
</resources>
|
||||
@@ -98,4 +98,29 @@
|
||||
<dimen name="module_push_item_image_width">118px</dimen>
|
||||
<dimen name="module_push_item_image_height">86px</dimen>
|
||||
<dimen name="module_push_panel_bkg_padding">8px</dimen>
|
||||
|
||||
|
||||
<dimen name="module_push_ui_content_marginBottom">34px</dimen>
|
||||
<dimen name="module_push_ui_content_width">567px</dimen>
|
||||
<dimen name="module_push_ui_content_height">100px</dimen>
|
||||
|
||||
<dimen name="module_push_line_width">2px</dimen>
|
||||
<dimen name="module_push_line_height">120px</dimen>
|
||||
<dimen name="module_push_line_margin_left">30px</dimen>
|
||||
<dimen name="module_push_check_margin">55px</dimen>
|
||||
<dimen name="module_push_check_text_size">42px</dimen>
|
||||
<dimen name="module_push_check_width">208px</dimen>
|
||||
|
||||
<dimen name="module_push_dialog_check_width">1200px</dimen>
|
||||
<dimen name="module_push_dialog_check_height">763px</dimen>
|
||||
<dimen name="module_push_dialog_check_bg_corner">32px</dimen>
|
||||
<dimen name="module_push_dialog_close_width">107px</dimen>
|
||||
<dimen name="module_push_dialog_close_height">107px</dimen>
|
||||
<dimen name="module_push_dialog_close_margin">40px</dimen>
|
||||
<dimen name="module_push_dialog_title_margin">54px</dimen>
|
||||
<dimen name="module_push_dialog_title_size">56px</dimen>
|
||||
<dimen name="module_push_dialog_content_width">1000px</dimen>
|
||||
<dimen name="module_push_dialog_content_margin_top">33px</dimen>
|
||||
<dimen name="module_push_dialog_content_size">43px</dimen>
|
||||
<dimen name="module_push_ui_margin_top">20px</dimen>
|
||||
</resources>
|
||||
@@ -3,4 +3,5 @@
|
||||
<string name="module_push_str_delete">清除</string>
|
||||
<string name="module_push_str_clear">清空历史消息</string>
|
||||
<string name="module_push_str_not_data">暂无消息</string>
|
||||
<string name="module_push_check">查看</string>
|
||||
</resources>
|
||||
|
||||
@@ -60,6 +60,8 @@ dependencies {
|
||||
implementation project(':modules:mogo-module-common')
|
||||
|
||||
implementation project(':core:mogo-core-data')
|
||||
implementation project(':core:mogo-core-res')
|
||||
implementation project(':core:mogo-core-function-call')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.mogo.map.navi.IMogoNaviListener;
|
||||
import com.mogo.module.common.utils.CarSeries;
|
||||
import com.mogo.module.service.dispatch.DispatchAutoPilotManager;
|
||||
import com.mogo.module.service.location.MogoRTKLocation;
|
||||
import com.mogo.module.service.routeoverlay.MogoRouteOverlayManager;
|
||||
import com.mogo.service.module.IMogoModuleLifecycle;
|
||||
import com.mogo.service.module.IMogoModuleProvider;
|
||||
import com.mogo.service.module.ModuleType;
|
||||
@@ -106,6 +107,7 @@ public class MogoServiceProvider implements IMogoModuleProvider {
|
||||
MogoServices.getInstance().preInit( context );
|
||||
MogoServices.getInstance().init( AbsMogoApplication.getApp() );
|
||||
DispatchAutoPilotManager.getInstance().initSocket(context);
|
||||
MogoRouteOverlayManager.getInstance(context).init();
|
||||
UiThreadHandler.postDelayed( () -> {
|
||||
}, 5_000L );
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.mogo.module.service.autopilot;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
|
||||
import com.mogo.eagle.core.data.autopilot.RemoteControlAutoPilotParameters;
|
||||
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
|
||||
import com.mogo.service.cloud.socket.IMogoSocketManager;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
@@ -10,7 +10,11 @@ import android.os.Handler;
|
||||
import android.os.Message;
|
||||
|
||||
import com.mogo.cloud.commons.utils.CoordinateUtils;
|
||||
import com.mogo.eagle.core.data.autopilot.AdasOCHData;
|
||||
import com.mogo.eagle.core.data.autopilot.RemoteControlAutoPilotParameters;
|
||||
import com.mogo.eagle.core.data.map.MogoLatLng;
|
||||
import com.mogo.eagle.core.function.api.hmi.autopilot.IMoGoCheckAutoPilotBtnListener;
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiListenerManager;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
@@ -19,10 +23,7 @@ import com.mogo.module.service.dispatch.model.DispatchServiceModel;
|
||||
import com.mogo.module.service.dispatch.model.IDispatch;
|
||||
import com.mogo.service.IMogoServiceApis;
|
||||
import com.mogo.service.adas.IMogoAdasOCHCallback;
|
||||
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
|
||||
import com.mogo.service.adas.entity.AdasOCHData;
|
||||
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
|
||||
import com.mogo.service.entrance.IMogoEntranceAutopilotStatusClickListener;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -31,7 +32,7 @@ import java.util.List;
|
||||
//负责监听自动驾驶状态并进行状态上报,自动驾驶路线上报,接收调度指令展示指令弹窗
|
||||
public class DispatchAutoPilotManager implements IMogoOnMessageListener<DispatchAdasAutoPilotLocReceiverBean>
|
||||
, IDispatchRemindClickListener
|
||||
, IMogoCarLocationChangedListener2, IMogoAdasOCHCallback, IMogoEntranceAutopilotStatusClickListener {
|
||||
, IMogoCarLocationChangedListener2, IMogoAdasOCHCallback, IMoGoCheckAutoPilotBtnListener {
|
||||
|
||||
private static final String TAG = "DispatchAutoPilotManager";
|
||||
private static volatile DispatchAutoPilotManager instance;
|
||||
@@ -95,7 +96,7 @@ public class DispatchAutoPilotManager implements IMogoOnMessageListener<Dispatch
|
||||
.registerCarLocationChangedListener(TAG, this);
|
||||
mApis.getAdasControllerApi()
|
||||
.addAdasOCHCallback(this);
|
||||
mApis.getEntranceButtonController().addEntranceAutopilotStatusClickListener(this);
|
||||
CallerHmiListenerManager.INSTANCE.addCheckAutoPilotBtnListener(TAG, this);
|
||||
dispatchDialogManager = DispatchDialogManager.getInstance(context);
|
||||
dispatchDialogManager.addIDispatchRemindListener(this);
|
||||
handler.sendEmptyMessageDelayed(MSG_TYPE_UPLOAD_AUTOPILOT_STATUS, 1000L);
|
||||
@@ -210,15 +211,18 @@ public class DispatchAutoPilotManager implements IMogoOnMessageListener<Dispatch
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click() {
|
||||
// 确保到达终点后,再次点击,不会有回馈,并且在下次调开始时,才会重置
|
||||
if (isArriveEnd) {
|
||||
return;
|
||||
}
|
||||
//todo 确认是否要根据停靠时自动驾驶状态,再次开启自动驾驶
|
||||
// 确保处于调度中并且返回的自动驾驶状态为1才开启自动驾驶
|
||||
if (isDispatch ) {
|
||||
startAutoPilot();
|
||||
public void onCheck(boolean isChecked) {
|
||||
if (isChecked) {
|
||||
// 确保到达终点后,再次点击,不会有回馈,并且在下次调开始时,才会重置
|
||||
if (isArriveEnd) {
|
||||
return;
|
||||
}
|
||||
//todo 确认是否要根据停靠时自动驾驶状态,再次开启自动驾驶
|
||||
// 确保处于调度中并且返回的自动驾驶状态为1才开启自动驾驶
|
||||
// 上述等待鄂州项目复盘后,产品输出完成方案后再进操作!!!
|
||||
if (isDispatch) {
|
||||
startAutoPilot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ import com.mogo.module.service.MarkerServiceHandler;
|
||||
import com.mogo.module.service.R;
|
||||
import com.mogo.module.service.status.EnvStatusManager;
|
||||
import com.mogo.module.service.timedelay.TimeDelayUploadManager;
|
||||
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
|
||||
import com.mogo.eagle.core.data.autopilot.RemoteControlAutoPilotParameters;
|
||||
import com.mogo.service.adas.entity.ADASCarStateInfo;
|
||||
import com.mogo.service.adas.entity.ADASRecognizedResult;
|
||||
import com.mogo.service.entrance.ButtonIndex;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.mogo.module.service.routeoverlay;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
|
||||
import com.mogo.eagle.core.data.map.MogoLatLng;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.module.common.drawer.MarkerDrawer;
|
||||
import com.mogo.service.adas.IMogoAdasRouteCallBack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MogoRouteOverlayManager implements IMogoCarLocationChangedListener2 {
|
||||
private static volatile MogoRouteOverlayManager sInstance;
|
||||
private Context mContext;
|
||||
|
||||
private MogoRouteOverlayManager(Context context){
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
MogoApisHandler.getInstance().getApis().getAdasControllerApi().addAdasAutopilotRouteCallBack(new IMogoAdasRouteCallBack(){
|
||||
|
||||
@Override
|
||||
public void routeResult(List<MogoLatLng> routeList) {
|
||||
RouteOverlayDrawer.getInstance(mContext).putRouteList(routeList);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static MogoRouteOverlayManager getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
synchronized (MogoRouteOverlayManager.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new MogoRouteOverlayManager(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCarLocationChanged2(Location latLng) {
|
||||
updateLocation(latLng);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarLocationChanged(MogoLatLng latLng) {
|
||||
|
||||
}
|
||||
public void updateLocation(Location location){
|
||||
if (location == null){
|
||||
return;
|
||||
}
|
||||
//坐标转换
|
||||
MogoLocation loc = new MogoLocation();
|
||||
loc.setTime(loc.getTime());
|
||||
loc.setAccuracy(location.getAccuracy());
|
||||
loc.setSpeed(location.getSpeed());
|
||||
loc.setLongitude(location.getLongitude());
|
||||
loc.setLatitude(location.getLatitude());
|
||||
loc.setAltitude(location.getAltitude());
|
||||
loc.setBearing(location.getBearing());
|
||||
loc.setProvider(location.getProvider());
|
||||
RouteOverlayDrawer.getInstance(mContext).drawRouteOverlay(loc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.mogo.module.service.routeoverlay;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.mogo.eagle.core.data.map.MogoLatLng;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
import com.mogo.map.overlay.IMogoOverlayManager;
|
||||
import com.mogo.map.overlay.IMogoPolyline;
|
||||
import com.mogo.map.overlay.MogoPolylineOptions;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.module.common.drawer.MarkerDrawer;
|
||||
import com.mogo.module.common.utils.LocationUtils;
|
||||
import com.mogo.utils.ColorUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RouteOverlayDrawer {
|
||||
|
||||
private IMogoPolyline mMoGoPolyline;
|
||||
// 连接线参数
|
||||
private MogoPolylineOptions mPolylineOptions;
|
||||
// 线路径集合
|
||||
private List<MogoLatLng> mPolylinePointList;
|
||||
// 渐变色
|
||||
private List<Integer> mPolylineColors;
|
||||
private Context mContext;
|
||||
IMogoOverlayManager mogoOverlayManager;
|
||||
|
||||
private static volatile RouteOverlayDrawer sInstance;
|
||||
|
||||
private RouteOverlayDrawer(Context context) {
|
||||
mPolylineOptions = new MogoPolylineOptions();
|
||||
// 绘制路径集合
|
||||
mPolylinePointList = new ArrayList<>();
|
||||
// 引导线颜色
|
||||
mPolylineColors = new ArrayList<>();
|
||||
mContext = context;
|
||||
mogoOverlayManager = MogoApisHandler.getInstance().getApis().getMapServiceApi().getOverlayManager(mContext);
|
||||
}
|
||||
|
||||
public static RouteOverlayDrawer getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
synchronized (RouteOverlayDrawer.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new RouteOverlayDrawer(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
public synchronized void release() {
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
// 阻止反序列化,必须实现 Serializable 接口
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private List<MogoLatLng> mRouteList;
|
||||
|
||||
public void drawRouteOverlay(MogoLocation location){
|
||||
if (mRouteList == null ){
|
||||
clearMogoRouteOverlay();
|
||||
return;
|
||||
}
|
||||
if (mRouteList.size() >0){
|
||||
//adas回调导航路径 绘制引导线
|
||||
draw(location,mRouteList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制最优路线
|
||||
*
|
||||
* @param routelist 要绘制的经纬度度集合
|
||||
*/
|
||||
public IMogoPolyline draw(MogoLocation carLocal, List<MogoLatLng> routelist) {
|
||||
clearMogoRouteOverlay();
|
||||
if (routelist != null) {
|
||||
|
||||
// 将当前车辆位置放进去
|
||||
mPolylinePointList.add(new MogoLatLng(carLocal.getLatitude(), carLocal.getLongitude()));
|
||||
// 过滤后台推送的推荐路线集合
|
||||
for (MogoLatLng polyline : routelist) {
|
||||
//需要剔除已经行驶过的经纬度,这里需要比对推荐路线集合中的点是否在当前车辆行驶方向前面如果不在则抛弃
|
||||
if (LocationUtils.isPointOnCarFront(carLocal, polyline)) {
|
||||
mPolylinePointList.add(polyline);
|
||||
}
|
||||
}
|
||||
mPolylineColors.addAll(ColorUtils.getGradientAlpha("#002965ED", "#FF2965ED", "#002965ED", mPolylinePointList.size()));
|
||||
// 替换路径集合
|
||||
mPolylineOptions.points(mPolylinePointList);
|
||||
// 线条粗细,渐变,渐变色值
|
||||
mPolylineOptions.width(25).useGradient(true).colorValues(mPolylineColors);
|
||||
// 绘制线
|
||||
mMoGoPolyline = mogoOverlayManager.addPolyline(mPolylineOptions);
|
||||
}
|
||||
return mMoGoPolyline;
|
||||
}
|
||||
|
||||
public void clearMogoRouteOverlay(){
|
||||
if (mMoGoPolyline != null) {
|
||||
mMoGoPolyline.remove();
|
||||
mPolylinePointList.clear();
|
||||
mPolylineColors.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void putRouteList(List<MogoLatLng> routeList) {
|
||||
this.mRouteList = routeList;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
android:paddingStart="@dimen/module_services_panel_item_start"
|
||||
android:paddingBottom="@dimen/module_services_panel_item_padding">
|
||||
|
||||
<com.mogo.module.common.widget.CustomCircleImageView
|
||||
<com.mogo.eagle.core.widget.CustomCircleImageView
|
||||
android:id="@+id/module_services_id_panel_item_avatar"
|
||||
android:layout_width="@dimen/module_services_panel_item_avatar_size"
|
||||
android:layout_height="@dimen/module_services_panel_item_avatar_size"
|
||||
|
||||
@@ -85,6 +85,7 @@ dependencies {
|
||||
implementation project(':modules:mogo-module-service')
|
||||
implementation project(':modules:mogo-module-obu')
|
||||
|
||||
implementation project(':core:mogo-core-res')
|
||||
implementation project(':core:mogo-core-data')
|
||||
implementation project(':core:mogo-core-function-call')
|
||||
}
|
||||
|
||||
@@ -54,14 +54,6 @@ public class V2XConst {
|
||||
public static final String V2X_ACC_OFF_TIME_STR = "v2x_acc_off_time_str";
|
||||
public static final String V2X_STRATEGY_PUSH = "v2x_strategy_push";
|
||||
|
||||
public static final int STATE_ERROR = -1;
|
||||
public static final int STATE_IDLE = 0;
|
||||
public static final int STATE_PREPARING = 1;
|
||||
public static final int STATE_PREPARED = 2;
|
||||
public static final int STATE_PLAYING = 3;
|
||||
public static final int STATE_PAUSED = 4;
|
||||
public static final int STATE_PLAYBACK_COMPLETED = 5;
|
||||
public static final int STATE_SEEKING = 6;
|
||||
|
||||
/**
|
||||
* V2X 埋点
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.mogo.module.v2x.listener.V2XMessageListener_401011;
|
||||
import com.mogo.module.v2x.listener.V2XMessageListener_401012;
|
||||
import com.mogo.module.v2x.listener.V2XMessageListener_402000;
|
||||
import com.mogo.module.v2x.listener.V2XMessageListener_401018;
|
||||
import com.mogo.module.v2x.listener.V2XMessageListener_404000;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
|
||||
@@ -36,6 +37,7 @@ public class V2XSocketManager {
|
||||
private V2XMessageListener_401010 v2XMessageListener_401010;
|
||||
private V2XMessageListener_402000 mV2XMessageListener_402000;
|
||||
private V2XMessageListener_401018 mV2XMessageListener401018;
|
||||
private V2XMessageListener_404000 mV2XMessageListener_404000;
|
||||
|
||||
private V2XSocketManager() {
|
||||
}
|
||||
@@ -66,6 +68,7 @@ public class V2XSocketManager {
|
||||
register401007();
|
||||
register401009();
|
||||
register401020();
|
||||
register404000();
|
||||
registerWarningMsg();
|
||||
|
||||
// TODO 这里是前瞻需求,量产版本需要注释
|
||||
@@ -120,6 +123,11 @@ public class V2XSocketManager {
|
||||
.getMoGoSocketManager()
|
||||
.unregisterOnMessageListener(402000, mV2XMessageListener_402000);
|
||||
}
|
||||
if (mV2XMessageListener_404000 != null) {
|
||||
V2XServiceManager
|
||||
.getMoGoSocketManager()
|
||||
.unregisterOnMessageListener(404000, mV2XMessageListener_404000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,6 +253,17 @@ public class V2XSocketManager {
|
||||
);
|
||||
}
|
||||
|
||||
public void register404000() {
|
||||
mV2XMessageListener_404000 = new V2XMessageListener_404000();
|
||||
// 道路事件,在线车辆绘制
|
||||
V2XServiceManager
|
||||
.getMoGoSocketManager()
|
||||
.registerOnMessageListener(
|
||||
404000,
|
||||
mV2XMessageListener_404000
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 车路云—场景预警-V1.0
|
||||
* * http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=52829799
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.mogo.module.v2x.listener;
|
||||
|
||||
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
|
||||
|
||||
import com.mogo.eagle.core.data.v2x.AdvanceWarningBean;
|
||||
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
import com.mogo.utils.network.utils.GsonUtil;
|
||||
|
||||
/**
|
||||
* @author chenfufeng
|
||||
* @description 路口碰撞预警、盲区预警等
|
||||
* @since: 2021/9/23
|
||||
*/
|
||||
public class V2XMessageListener_404000 implements IMogoOnMessageListener<AdvanceWarningBean> {
|
||||
@Override
|
||||
public Class target() {
|
||||
return AdvanceWarningBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMsgReceived(AdvanceWarningBean message) {
|
||||
// 将接收到的数据转换成最优车道推荐的场景数据
|
||||
Logger.i(MODULE_NAME, "V2XMessageListener_404000:" + GsonUtil.jsonFromObject(message));
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import com.mogo.module.common.utils.CarSeries;
|
||||
import com.mogo.module.service.ServiceConst;
|
||||
import com.mogo.module.service.Utils;
|
||||
import com.mogo.module.v2x.MoGoV2XServicePaths;
|
||||
import com.mogo.module.v2x.R;
|
||||
import com.mogo.module.v2x.V2XConst;
|
||||
import com.mogo.module.v2x.V2XServiceManager;
|
||||
import com.mogo.module.v2x.entity.net.V2XSpecialCarRes.V2XMarkerEntity;
|
||||
@@ -288,7 +289,7 @@ public class MoGoV2XMarkerManager implements IMoGoV2XMarkerManager {
|
||||
MogoMarkerOptions options = new MogoMarkerOptions().object(roadEventEntity)
|
||||
.latitude(roadEventEntity.getLocation().getLat()).longitude(roadEventEntity.getLocation().getLon());
|
||||
options.anchor(0.5f, 0.5f);
|
||||
options.icon3DRes(com.mogo.module.common.R.raw.special_vehicle);
|
||||
options.icon3DRes(R.raw.special_vehicle);
|
||||
options.anchorColor("#FFBF29FF");
|
||||
m3DMarker = V2XServiceManager.getMarkerManager().addMarker(V2X_EVENT_ALARM_POI, options);
|
||||
m3DMarker.setToTop();
|
||||
|
||||
@@ -14,7 +14,7 @@ import com.mogo.module.v2x.R;
|
||||
import com.mogo.module.v2x.V2XServiceManager;
|
||||
import com.mogo.module.v2x.listener.V2XWindowStatusListener;
|
||||
import com.mogo.module.v2x.scenario.view.IV2XWindow;
|
||||
import com.mogo.module.v2x.view.TextureVideoView;
|
||||
import com.mogo.eagle.core.widget.TextureVideoView;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
|
||||
|
||||
@@ -1,366 +0,0 @@
|
||||
package com.mogo.module.v2x.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Message;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.module.v2x.utils.ImageUtil;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 加载图片帧动画
|
||||
*/
|
||||
public class AnimationView extends View implements Handler.Callback {
|
||||
|
||||
public static final int DEFAULT_ANIM_TIME = 20;
|
||||
public static final int PROCESS_DATA = 1;
|
||||
public static final int PROCESS_ANIM_FINISH = 1 << 1;
|
||||
public static final int PROCESS_DELAY = 1 << 2;
|
||||
|
||||
public AnimData mCurAnimData;
|
||||
public int mCurAnimPos;
|
||||
public boolean mIsRepeat;
|
||||
public int mAnimTime;
|
||||
|
||||
private Handler mHandler;
|
||||
private ProcessAnimThread mProcessThread;
|
||||
private Bitmap mCurShowBmp;
|
||||
|
||||
private List<AnimData> mAnimDataList = new ArrayList<>();
|
||||
|
||||
public AnimationView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AnimationView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public AnimationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mHandler = new Handler(this);
|
||||
mProcessThread = new ProcessAnimThread(getContext(), mHandler);
|
||||
mAnimTime = DEFAULT_ANIM_TIME;
|
||||
}
|
||||
|
||||
public void setIsRepeat(boolean repeat) {
|
||||
mIsRepeat = repeat;
|
||||
}
|
||||
|
||||
private int mGravity;
|
||||
|
||||
public void setGravity(int gravity) {
|
||||
mGravity = gravity;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setData(List<AnimData> list) {
|
||||
if (list != null) {
|
||||
mAnimDataList.clear();
|
||||
mAnimDataList.addAll(list);
|
||||
}
|
||||
}
|
||||
|
||||
private Matrix mTempMatrix = new Matrix();
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (mCurShowBmp != null && !mCurShowBmp.isRecycled()) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
float scaleX = 1f;
|
||||
float scaleY = 1f;
|
||||
switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
|
||||
case Gravity.LEFT:
|
||||
x = 0;
|
||||
break;
|
||||
case Gravity.RIGHT:
|
||||
x = this.getWidth() - mCurShowBmp.getWidth();
|
||||
break;
|
||||
case Gravity.CENTER_HORIZONTAL:
|
||||
x = (this.getWidth() - mCurShowBmp.getWidth()) / 2;
|
||||
break;
|
||||
case Gravity.FILL_HORIZONTAL: {
|
||||
int w = mCurShowBmp.getWidth();
|
||||
if (w > 0) {
|
||||
scaleX = (float) this.getWidth() / (float) w;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
|
||||
case Gravity.TOP:
|
||||
y = 0;
|
||||
break;
|
||||
|
||||
case Gravity.BOTTOM:
|
||||
y = this.getHeight() - mCurShowBmp.getHeight();
|
||||
break;
|
||||
|
||||
case Gravity.CENTER_VERTICAL:
|
||||
y = (this.getHeight() - mCurShowBmp.getHeight()) / 2;
|
||||
break;
|
||||
|
||||
case Gravity.FILL_VERTICAL: {
|
||||
int h = mCurShowBmp.getHeight();
|
||||
if (h > 0) {
|
||||
scaleY = (float) this.getHeight() / (float) h;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (scaleX == 1 && scaleY != 1) {
|
||||
scaleX = scaleY;
|
||||
switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
|
||||
case Gravity.RIGHT:
|
||||
x = this.getWidth() - (int) (mCurShowBmp.getWidth() * scaleX);
|
||||
break;
|
||||
case Gravity.CENTER_HORIZONTAL:
|
||||
x = (this.getWidth() - (int) (mCurShowBmp.getWidth() * scaleX)) / 2;
|
||||
break;
|
||||
}
|
||||
} else if (scaleX != 1 && scaleY == 1) {
|
||||
scaleY = scaleX;
|
||||
switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
|
||||
case Gravity.BOTTOM:
|
||||
y = this.getHeight() - (int) (mCurShowBmp.getHeight() * scaleY);
|
||||
break;
|
||||
case Gravity.CENTER_VERTICAL:
|
||||
y = (this.getHeight() - (int) (mCurShowBmp.getHeight() * scaleY)) / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mTempMatrix.reset();
|
||||
mTempMatrix.postScale(scaleX, scaleY);
|
||||
mTempMatrix.postTranslate(x, y);
|
||||
canvas.drawBitmap(mCurShowBmp, mTempMatrix, null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean mHasStarted = false;
|
||||
|
||||
public void start() {
|
||||
mHasStarted = true;
|
||||
if (mWidth == 0 || mHeight == 0) {
|
||||
return;
|
||||
}
|
||||
startPlay();
|
||||
}
|
||||
|
||||
private void startPlay() {
|
||||
if (mAnimDataList != null && mAnimDataList.size() > 0) {
|
||||
mCurAnimPos = 0;
|
||||
AnimData animData = mAnimDataList.get(mCurAnimPos);
|
||||
mCurShowBmp = ImageUtil.getBitmap(getContext(), animData.filePath, mWidth, mHeight);
|
||||
invalidate();
|
||||
if (mListener != null) {
|
||||
mListener.onAnimChange(mCurAnimPos, mCurShowBmp);
|
||||
}
|
||||
checkIsPlayNext();
|
||||
}
|
||||
}
|
||||
|
||||
private void playNext(final int curAnimPosition) {
|
||||
Message msg = Message.obtain();
|
||||
msg.what = PROCESS_DELAY;
|
||||
msg.arg1 = curAnimPosition;
|
||||
mHandler.sendMessageDelayed(msg, mAnimTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
quit();
|
||||
}
|
||||
|
||||
private void quit() {
|
||||
mHasStarted = false;
|
||||
if (mProcessThread != null) {
|
||||
mProcessThread.clearAll();
|
||||
}
|
||||
}
|
||||
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
if (mProcessThread != null) {
|
||||
mProcessThread.setSize(w, h);
|
||||
}
|
||||
if (mHasStarted) {
|
||||
startPlay();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean mHavePause = false;
|
||||
|
||||
public void pause() {
|
||||
mHavePause = true;
|
||||
mHandler.removeMessages(PROCESS_DELAY);
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (mHavePause && mHasStarted) {
|
||||
checkIsPlayNext();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message msg) {
|
||||
//此 handleMessage 在主线程被调用
|
||||
switch (msg.what) {
|
||||
case PROCESS_ANIM_FINISH: {
|
||||
Bitmap bitmap = (Bitmap) msg.obj;
|
||||
if (bitmap != null) {
|
||||
if (mCurShowBmp != null) {
|
||||
mCurShowBmp.recycle();
|
||||
mCurShowBmp = null;
|
||||
}
|
||||
mCurShowBmp = bitmap;
|
||||
if (mListener != null) {
|
||||
mListener.onAnimChange(mCurAnimPos, bitmap);
|
||||
}
|
||||
invalidate();
|
||||
|
||||
}
|
||||
checkIsPlayNext();
|
||||
break;
|
||||
}
|
||||
case PROCESS_DELAY: {
|
||||
int curAnimPosition = msg.arg1;
|
||||
AnimData data = mAnimDataList.get(curAnimPosition);
|
||||
mProcessThread.processData(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void checkIsPlayNext() {
|
||||
mCurAnimPos++;
|
||||
if (mCurAnimPos >= mAnimDataList.size()) {
|
||||
if (mIsRepeat) {
|
||||
mCurAnimPos = 0;
|
||||
playNext(mCurAnimPos);
|
||||
} else {
|
||||
if (mListener != null) {
|
||||
mListener.onAnimEnd();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
playNext(mCurAnimPos);
|
||||
}
|
||||
}
|
||||
|
||||
private AnimCallBack mListener;
|
||||
|
||||
public void setAnimCallBack(AnimCallBack callBack) {
|
||||
mListener = callBack;
|
||||
}
|
||||
|
||||
public interface AnimCallBack {
|
||||
void onAnimChange(int position, Bitmap bitmap);
|
||||
|
||||
void onAnimEnd();
|
||||
}
|
||||
|
||||
public static class AnimData {
|
||||
public Object filePath;
|
||||
}
|
||||
|
||||
public static class ProcessAnimThread {
|
||||
private HandlerThread mHandlerThread;
|
||||
private Handler mProcessHandler;
|
||||
private Handler mUiHandler;
|
||||
|
||||
private AnimData mCurAnimData;
|
||||
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private WeakReference<Context> mContext;
|
||||
|
||||
public ProcessAnimThread(Context context, Handler handler) {
|
||||
mUiHandler = handler;
|
||||
mContext = new WeakReference<Context>(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setSize(int width, int height) {
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mHandlerThread = new HandlerThread("process_anim_thread");
|
||||
mHandlerThread.start();
|
||||
|
||||
mProcessHandler = new Handler(mHandlerThread.getLooper(), new Handler.Callback() {
|
||||
@Override
|
||||
public boolean handleMessage(Message msg) {
|
||||
// 消息是在子线程 HandlerThread 里面被处理,所以这里的 handleMessage 在
|
||||
//子线程里被调用
|
||||
switch (msg.what) {
|
||||
case PROCESS_DATA: {
|
||||
AnimData animData = (AnimData) msg.obj;
|
||||
Bitmap bitmap = ImageUtil.getBitmap(mContext.get(), animData.filePath, mWidth, mHeight);
|
||||
if (bitmap != null) {
|
||||
Message finishMsg = Message.obtain();
|
||||
finishMsg.what = PROCESS_ANIM_FINISH;
|
||||
finishMsg.obj = bitmap;
|
||||
//消息处理完毕,使用主线程的 Handler 将消息发送到主线程
|
||||
mUiHandler.sendMessage(finishMsg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void processData(AnimData animData) {
|
||||
if (animData != null) {
|
||||
Message msg = Message.obtain();
|
||||
msg.what = PROCESS_DATA;
|
||||
msg.obj = animData;
|
||||
mProcessHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAll() {
|
||||
mHandlerThread.quit();
|
||||
mHandlerThread = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import com.mogo.cloud.trafficlive.api.ITrafficCarLiveCallBack;
|
||||
import com.mogo.cloud.trafficlive.api.MoGoAiCloudTrafficLive;
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.commons.voice.AIAssist;
|
||||
import com.mogo.eagle.core.widget.RoundLayout;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
import com.mogo.module.v2x.R;
|
||||
import com.mogo.module.v2x.V2XServiceManager;
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
package com.mogo.module.v2x.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.customview.widget.ViewDragHelper;
|
||||
|
||||
import com.mogo.module.v2x.V2XConst;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* author : donghongyu
|
||||
* e-mail : 1358506549@qq.com
|
||||
* date : 2020/5/25 11:13 AM
|
||||
* desc :
|
||||
* version: 1.0
|
||||
*/
|
||||
public class GestureTopCloseLayout extends ConstraintLayout {
|
||||
private ViewDragHelper mViewDragHelper;
|
||||
|
||||
private ViewCloseListener mViewCloseListener;
|
||||
|
||||
public GestureTopCloseLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public GestureTopCloseLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public GestureTopCloseLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
|
||||
mViewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
|
||||
private int mTop;
|
||||
|
||||
@Override
|
||||
public boolean tryCaptureView(@NotNull View child, int pointerId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clampViewPositionVertical(@NotNull View child, int top, int dy) {
|
||||
final int bottomBound = getPaddingTop();
|
||||
return Math.min(top, bottomBound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clampViewPositionHorizontal(@NotNull View child, int left, int dx) {
|
||||
//取得左边界的坐标
|
||||
final int leftBound = getPaddingLeft();
|
||||
//取得右边界的坐标
|
||||
final int rightBound = getWidth() - child.getWidth() - child.getPaddingRight() - leftBound;
|
||||
//这个地方的含义就是 如果left的值 在leftbound和rightBound之间 那么就返回left
|
||||
//如果left的值 比 leftbound 还要小 那么就说明 超过了左边界 那我们只能返回给他左边界的值
|
||||
//如果right的值 比 rightbound 还要大 那么就说明 超过了右边界,那我们只能返回给他右边界的值
|
||||
return Math.min(Math.max(left, leftBound), rightBound);
|
||||
}
|
||||
|
||||
@Override //不重写该方法默认返回0,返回0时若还设置了点击事件则水平方向不能移动
|
||||
public int getViewHorizontalDragRange(@NotNull View child) {
|
||||
return getMeasuredWidth() - child.getMeasuredWidth();
|
||||
}
|
||||
|
||||
@Override //不重写该方法默认返回0,返回0时若还设置了点击事件则竖直方向不能移动
|
||||
public int getViewVerticalDragRange(@NotNull View child) {
|
||||
return getMeasuredHeight() - child.getMeasuredHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewPositionChanged(@NonNull View changedView, int left, int top, int dx, int dy) {
|
||||
super.onViewPositionChanged(changedView, left, top, dx, dy);
|
||||
Logger.w(V2XConst.MODULE_NAME, "onViewPositionChanged==top=" + top +
|
||||
" changedView.getHeight()==" + changedView.getHeight());
|
||||
if (top < 0) {
|
||||
mTop = top;
|
||||
if (top <= -changedView.getHeight()) {
|
||||
mViewDragHelper.smoothSlideViewTo(changedView, 0, getPaddingTop());
|
||||
invalidate();
|
||||
if (mViewCloseListener != null) {
|
||||
mViewCloseListener.onClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//手指释放的时候回调
|
||||
@Override
|
||||
public void onViewReleased(View releasedChild, float xvel, float yvel) {
|
||||
Logger.w(V2XConst.MODULE_NAME, "onViewReleased==mTop=" + mTop + " getHeight=" + getHeight());
|
||||
if (mTop < 0) {
|
||||
mViewDragHelper.settleCapturedViewAt(0, -getHeight());
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
return mViewDragHelper.shouldInterceptTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
mViewDragHelper.processTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void computeScroll() {
|
||||
if (mViewDragHelper.continueSettling(true)) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void setViewCloseListener(ViewCloseListener mViewCloseListener) {
|
||||
this.mViewCloseListener = mViewCloseListener;
|
||||
}
|
||||
|
||||
public interface ViewCloseListener {
|
||||
void onClose();
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.mogo.module.v2x.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.mogo.module.v2x.R;
|
||||
|
||||
/**
|
||||
* author : donghongyu
|
||||
* e-mail : 1358506549@qq.com
|
||||
* date : 2020/5/27 2:08 PM
|
||||
* desc :
|
||||
* version: 1.0
|
||||
*/
|
||||
public class RoundConstraintLayout extends ConstraintLayout {
|
||||
|
||||
private float roundLayoutRadius = 14f;
|
||||
private Path roundPath;
|
||||
private RectF rectF;
|
||||
|
||||
public RoundConstraintLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public RoundConstraintLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundLayout);
|
||||
roundLayoutRadius = typedArray.getDimensionPixelSize(R.styleable.RoundLayout_roundLayoutRadius, (int) roundLayoutRadius);
|
||||
typedArray.recycle();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
public RoundConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
|
||||
private void init() {
|
||||
setWillNotDraw(false);//如果你继承的是ViewGroup,注意此行,否则draw方法是不会回调的;
|
||||
roundPath = new Path();
|
||||
rectF = new RectF();
|
||||
}
|
||||
|
||||
private void setRoundPath() {
|
||||
//添加一个圆角矩形到path中, 如果要实现任意形状的View, 只需要手动添加path就行
|
||||
roundPath.addRoundRect(rectF, roundLayoutRadius, roundLayoutRadius, Path.Direction.CW);
|
||||
}
|
||||
|
||||
|
||||
public void setRoundLayoutRadius(float roundLayoutRadius) {
|
||||
this.roundLayoutRadius = roundLayoutRadius;
|
||||
setRoundPath();
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
rectF.set(0f, 0f, getMeasuredWidth(), getMeasuredHeight());
|
||||
setRoundPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (roundLayoutRadius > 0f) {
|
||||
canvas.clipPath(roundPath);
|
||||
}
|
||||
super.draw(canvas);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.mogo.module.v2x.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.mogo.module.v2x.R;
|
||||
|
||||
/**
|
||||
* author : donghongyu
|
||||
* e-mail : 1358506549@qq.com
|
||||
* date : 2020/3/25 11:39 AM
|
||||
* desc :
|
||||
* version: 1.0
|
||||
*/
|
||||
public class RoundLayout extends RelativeLayout {
|
||||
private float roundLayoutRadius = 14f;
|
||||
private Path roundPath;
|
||||
private RectF rectF;
|
||||
|
||||
public RoundLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public RoundLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public RoundLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundLayout);
|
||||
roundLayoutRadius = typedArray.getDimensionPixelSize(R.styleable.RoundLayout_roundLayoutRadius, (int) roundLayoutRadius);
|
||||
typedArray.recycle();
|
||||
|
||||
init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void init() {
|
||||
setWillNotDraw(false);//如果你继承的是ViewGroup,注意此行,否则draw方法是不会回调的;
|
||||
roundPath = new Path();
|
||||
rectF = new RectF();
|
||||
}
|
||||
|
||||
private void setRoundPath() {
|
||||
//添加一个圆角矩形到path中, 如果要实现任意形状的View, 只需要手动添加path就行
|
||||
roundPath.addRoundRect(rectF, roundLayoutRadius, roundLayoutRadius, Path.Direction.CW);
|
||||
}
|
||||
|
||||
|
||||
public void setRoundLayoutRadius(float roundLayoutRadius) {
|
||||
this.roundLayoutRadius = roundLayoutRadius;
|
||||
setRoundPath();
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
rectF.set(0f, 0f, getMeasuredWidth(), getMeasuredHeight());
|
||||
setRoundPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (roundLayoutRadius > 0f) {
|
||||
canvas.clipPath(roundPath);
|
||||
}
|
||||
super.draw(canvas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,590 +0,0 @@
|
||||
package com.mogo.module.v2x.view;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.MediaPlayer.OnCompletionListener;
|
||||
import android.media.MediaPlayer.OnErrorListener;
|
||||
import android.media.MediaPlayer.OnSeekCompleteListener;
|
||||
import android.net.Uri;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Surface;
|
||||
import android.view.TextureView;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.MediaController.MediaPlayerControl;
|
||||
|
||||
import com.mogo.module.v2x.R;
|
||||
import com.mogo.module.v2x.V2XConst;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
|
||||
|
||||
/**
|
||||
* Displays a video file. The VideoView class can load images from various
|
||||
* sources (such as resources or content providers), takes care of computing its
|
||||
* measurement from the video so that it can be used in any layout manager, and
|
||||
* provides various display options such as scaling and tinting.
|
||||
*/
|
||||
public class TextureVideoView extends TextureView implements MediaPlayerControl {
|
||||
private String TAG = "V2XModuleProvider";
|
||||
// settable by the client
|
||||
private Uri mUri;
|
||||
private Map<String, String> mHeaders;
|
||||
private int mDuration;
|
||||
|
||||
// all possible internal states
|
||||
private int mCurrentState = V2XConst.STATE_IDLE;
|
||||
private int mTargetState = mCurrentState, mTagetStateBackup = mCurrentState;
|
||||
private int mPrepareState = V2XConst.STATE_PREPARED;
|
||||
|
||||
// All the stuff we need for playing and showing a video
|
||||
private Surface mSurface = null;
|
||||
private MediaPlayer mMediaPlayer = null;
|
||||
private int mVideoWidth, mVideoHeight;
|
||||
|
||||
private OnCompletionListener mOnCompletionListener;
|
||||
private MediaPlayer.OnPreparedListener mOnPreparedListener;
|
||||
private int mCurrentBufferPercentage;
|
||||
private OnErrorListener mOnErrorListener;
|
||||
private MediaPlayer.OnInfoListener mOnInfoListener;
|
||||
private int mSeekWhenPrepared;
|
||||
private boolean isFocusLoss = true;
|
||||
private boolean isSuspendFromActivity = false;
|
||||
private int progressWhileSuspend = 0;
|
||||
public static final int MEDIA_INFO_VIDEO_NOT_SUPPORTED = 860;
|
||||
public static final int MEDIA_INFO_AUDIO_NOT_SUPPORTED = 862;
|
||||
|
||||
public TextureVideoView(Context context) {
|
||||
super(context);
|
||||
initVideoView();
|
||||
}
|
||||
|
||||
public TextureVideoView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs, 0);
|
||||
initVideoView();
|
||||
}
|
||||
|
||||
public TextureVideoView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initVideoView();
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
|
||||
super.onInitializeAccessibilityEvent(event);
|
||||
event.setClassName(TextureVideoView.class.getName());
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
info.setClassName(TextureVideoView.class.getName());
|
||||
}
|
||||
|
||||
private void initVideoView() {
|
||||
mVideoWidth = 0;
|
||||
mVideoHeight = 0;
|
||||
setSurfaceTextureListener(mSurfaceTextureListener);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
mCurrentState = V2XConst.STATE_IDLE;
|
||||
mTargetState = V2XConst.STATE_IDLE;
|
||||
}
|
||||
|
||||
public boolean requestAudioFocus() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setVideoPath(String path) {
|
||||
setVideoURI(Uri.parse(path));
|
||||
}
|
||||
|
||||
public void setVideoURI(Uri uri) {
|
||||
setVideoURI(uri, null);
|
||||
}
|
||||
|
||||
public void setVideoURI(Uri uri, Map<String, String> headers) {
|
||||
if (uri == null) {
|
||||
Logger.i(MODULE_NAME, "setVideoURI--- uri = null");
|
||||
} else {
|
||||
Logger.i(MODULE_NAME, "setVideoURI--- uri = " + uri.getPath());
|
||||
}
|
||||
mUri = uri;
|
||||
mHeaders = headers;
|
||||
mSeekWhenPrepared = 0;
|
||||
isFocusLoss = !requestAudioFocus();
|
||||
openVideo();
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void stopPlayback() {
|
||||
if (mMediaPlayer != null) {
|
||||
mMediaPlayer.stop();
|
||||
mMediaPlayer.release();
|
||||
mMediaPlayer = null;
|
||||
mTargetState = mCurrentState = V2XConst.STATE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void openVideo() {
|
||||
Logger.i(MODULE_NAME, "openVideo");
|
||||
if (mUri == null) {
|
||||
Logger.i(MODULE_NAME, "mUri == null ");
|
||||
}
|
||||
if (mSurface == null) {
|
||||
Logger.i(MODULE_NAME, "mSurface == null ");
|
||||
}
|
||||
if (mUri == null || mSurface == null || isSuspendFromActivity) {
|
||||
Logger.i(MODULE_NAME, "isSuspendFromActivity = " + isSuspendFromActivity);
|
||||
return;
|
||||
}
|
||||
release(false);
|
||||
try {
|
||||
mMediaPlayer = new MediaPlayer();
|
||||
mMediaPlayer.setOnPreparedListener(mPreparedListener);
|
||||
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
|
||||
mDuration = -1;
|
||||
mMediaPlayer.setOnCompletionListener(mCompletionListener);
|
||||
mMediaPlayer.setOnErrorListener(mErrorListener);
|
||||
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
|
||||
mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);
|
||||
mMediaPlayer.setOnInfoListener(mInfoListener);
|
||||
mCurrentBufferPercentage = 0;
|
||||
mMediaPlayer.setDataSource(getContext(), mUri, mHeaders);
|
||||
if (mSurface != null) {
|
||||
/*
|
||||
Canvas mCanvas = mSurface.lockCanvas(new Rect());
|
||||
mCanvas.drawColor(Color.BLACK);
|
||||
mSurface.unlockCanvasAndPost(mCanvas);
|
||||
invalidate();
|
||||
*/
|
||||
mMediaPlayer.setSurface(mSurface);
|
||||
}
|
||||
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||
mMediaPlayer.setScreenOnWhilePlaying(true);
|
||||
mMediaPlayer.setVolume(0, 0);
|
||||
mMediaPlayer.prepare();
|
||||
mPrepareState = mCurrentState = V2XConst.STATE_PREPARING;
|
||||
} catch (IOException | SecurityException | IllegalStateException | IllegalArgumentException ex) {
|
||||
ex.printStackTrace();
|
||||
onError();
|
||||
}
|
||||
}
|
||||
|
||||
private void onError() {
|
||||
mTargetState = mCurrentState = V2XConst.STATE_ERROR;
|
||||
if (mErrorListener != null)
|
||||
mErrorListener.onError(mMediaPlayer,
|
||||
MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
|
||||
}
|
||||
|
||||
MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() {
|
||||
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
|
||||
mVideoWidth = mp.getVideoWidth();
|
||||
mVideoHeight = mp.getVideoHeight();
|
||||
if (mVideoWidth != 0 && mVideoHeight != 0) {
|
||||
Logger.d(MODULE_NAME, "OnVideoSizeChangedListener mVideoWidth:" + " mVideoWidth:" + mVideoWidth + " mVideoHeight:" + mVideoHeight);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
|
||||
public void onPrepared(MediaPlayer mp) {
|
||||
Logger.i(MODULE_NAME, "MediaPlayer.OnPreparedListener");
|
||||
mPrepareState = mCurrentState = V2XConst.STATE_PREPARED;
|
||||
mVideoWidth = mp.getVideoWidth();
|
||||
mVideoHeight = mp.getVideoHeight();
|
||||
|
||||
int seekToPosition = mSeekWhenPrepared;
|
||||
// Logger.i(MODULE_NAME, "seekToPosition = " + seekToPosition);
|
||||
if (seekToPosition != 0) {
|
||||
seekTo(seekToPosition);
|
||||
}
|
||||
if (mTargetState == V2XConst.STATE_PLAYING) {
|
||||
start();
|
||||
}
|
||||
if (mOnPreparedListener != null) {
|
||||
mOnPreparedListener.onPrepared(mMediaPlayer);
|
||||
}
|
||||
mp.setOnInfoListener((mp1, what, extra) -> {
|
||||
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
|
||||
setBackgroundColor(Color.TRANSPARENT);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private OnCompletionListener mCompletionListener = new OnCompletionListener() {
|
||||
public void onCompletion(MediaPlayer mp) {
|
||||
Logger.i(MODULE_NAME, "MediaPlayer.OnCompletionListener");
|
||||
mTargetState = mCurrentState = V2XConst.STATE_PLAYBACK_COMPLETED;
|
||||
if (mOnCompletionListener != null) {
|
||||
mOnCompletionListener.onCompletion(mMediaPlayer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private OnSeekCompleteListener mSeekCompleteListener = mp -> {
|
||||
Logger.i(MODULE_NAME, "MediaPlayer.OnSeekCompleteListener");
|
||||
try {
|
||||
mCurrentState = mMediaPlayer.isPlaying() ? V2XConst.STATE_PLAYING : V2XConst.STATE_PAUSED;
|
||||
} catch (Exception e) {
|
||||
mCurrentState = V2XConst.STATE_PLAYING;
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
|
||||
private OnErrorListener mErrorListener = new OnErrorListener() {
|
||||
public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
|
||||
Logger.i(MODULE_NAME, "MediaPlayer.onError");
|
||||
mTargetState = mPrepareState = mCurrentState = V2XConst.STATE_ERROR;
|
||||
if (mOnErrorListener != null) {
|
||||
mOnErrorListener.onError(mMediaPlayer, framework_err,
|
||||
impl_err);
|
||||
}
|
||||
release(false);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
|
||||
|
||||
@Override
|
||||
public boolean onInfo(MediaPlayer mp, int what, int extra) {
|
||||
Logger.i(MODULE_NAME, "MediaPlayer.OnInfoListener---what = " + what + ";extra = " + extra);
|
||||
int messageId = 0;
|
||||
if (what == MEDIA_INFO_VIDEO_NOT_SUPPORTED) {
|
||||
messageId = R.string.VideoView_info_text_video_not_supported;
|
||||
} else if (what == MEDIA_INFO_AUDIO_NOT_SUPPORTED) {
|
||||
messageId = R.string.file_not_support;
|
||||
}
|
||||
if (messageId != 0) {
|
||||
if (mOnInfoListener != null) {
|
||||
mOnInfoListener.onInfo(mp, what, extra);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {
|
||||
public void onBufferingUpdate(MediaPlayer mp, int percent) {
|
||||
Logger.i(MODULE_NAME, "MediaPlayer.OnBufferingUpdateListener");
|
||||
mCurrentBufferPercentage = percent;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when the media file is loaded and ready
|
||||
* to go.
|
||||
*
|
||||
* @param l The callback that will be run
|
||||
*/
|
||||
public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
|
||||
mOnPreparedListener = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when the end of a media file has been
|
||||
* reached during playback.
|
||||
*
|
||||
* @param l The callback that will be run
|
||||
*/
|
||||
public void setOnCompletionListener(OnCompletionListener l) {
|
||||
mOnCompletionListener = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when an error occurs during playback or
|
||||
* setup. If no listener is specified, or if the listener returned false,
|
||||
* VideoView will inform the user of any errors.
|
||||
*
|
||||
* @param l The callback that will be run
|
||||
*/
|
||||
public void setOnErrorListener(OnErrorListener l) {
|
||||
mOnErrorListener = l;
|
||||
}
|
||||
|
||||
public void setOnInfoListener(MediaPlayer.OnInfoListener l) {
|
||||
mOnInfoListener = l;
|
||||
}
|
||||
|
||||
SurfaceTextureListener mSurfaceTextureListener = new SurfaceTextureListener() {
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
Logger.i(MODULE_NAME, "onSurfaceTextureAvailable");
|
||||
mSurface = new Surface(surface);
|
||||
openVideo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
||||
Logger.d(MODULE_NAME, "onSurfaceTextureSizeChanged mVideoWidth:" + " mVideoWidth:" + mVideoWidth + " mVideoHeight:" + mVideoHeight);
|
||||
boolean isValidState = (mTargetState == V2XConst.STATE_PLAYING);
|
||||
boolean hasValidSize = (mVideoWidth == width && mVideoHeight == height);
|
||||
if (mMediaPlayer != null && isValidState && hasValidSize) {
|
||||
if (mSeekWhenPrepared != 0) {
|
||||
seekTo(mSeekWhenPrepared);
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!isFocusLoss) start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
Logger.i(MODULE_NAME, "onSurfaceTextureDestroyed");
|
||||
mSurface = null;
|
||||
release(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* release the media player in any state
|
||||
*/
|
||||
private void release(boolean cleartargetstate) {
|
||||
Logger.i(MODULE_NAME, "release ---cleartargetstate=" + cleartargetstate);
|
||||
mCurrentState = V2XConst.STATE_IDLE;
|
||||
|
||||
if (cleartargetstate) {
|
||||
mTargetState = V2XConst.STATE_IDLE;
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
|
||||
try {
|
||||
mMediaPlayer.stop();
|
||||
} catch (IllegalStateException e) {
|
||||
try {
|
||||
this.wait(1000);
|
||||
mMediaPlayer.stop();
|
||||
} catch (InterruptedException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mMediaPlayer != null) {
|
||||
mMediaPlayer.release();// release会做reset
|
||||
}
|
||||
mMediaPlayer = null;
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
if (mMediaPlayer != null) {
|
||||
try {
|
||||
mMediaPlayer.stop();
|
||||
mMediaPlayer.reset();
|
||||
mMediaPlayer.release();
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mMediaPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPrepared() {
|
||||
return mPrepareState == V2XConst.STATE_PREPARED
|
||||
|| isSuspendFromActivity;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
Logger.i(MODULE_NAME, "TextureVideoView---start");
|
||||
if (isFocusLoss) {
|
||||
mTagetStateBackup = V2XConst.STATE_PLAYING;
|
||||
return;
|
||||
}
|
||||
//Logger.i(MODULE_NAME, "mCurrentState = " + mCurrentState);
|
||||
if (isInPlaybackState()) {
|
||||
Logger.i(MODULE_NAME, "MediaPlayer.start");
|
||||
mMediaPlayer.start();
|
||||
mCurrentState = V2XConst.STATE_PLAYING;
|
||||
}
|
||||
mTargetState = V2XConst.STATE_PLAYING;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
Logger.i(MODULE_NAME, "TextureVideoView---pause");
|
||||
Logger.i(MODULE_NAME, "mCurrentState = " + mCurrentState);
|
||||
if (isInPlaybackState()) {
|
||||
if (mMediaPlayer.isPlaying()) {
|
||||
Logger.i(MODULE_NAME, " MediaPlayer.pause");
|
||||
mMediaPlayer.pause();
|
||||
mCurrentState = V2XConst.STATE_PAUSED;
|
||||
}
|
||||
}
|
||||
mTagetStateBackup = mTargetState = V2XConst.STATE_PAUSED;
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
Logger.i(MODULE_NAME, "TextureVideoView---suspend");
|
||||
if (!isSuspendFromActivity) {
|
||||
isSuspendFromActivity = true;
|
||||
if (mMediaPlayer != null) {
|
||||
if (isInPlaybackState()) {
|
||||
progressWhileSuspend = mMediaPlayer.getCurrentPosition();
|
||||
}
|
||||
}
|
||||
release(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
Logger.i(MODULE_NAME, "TextureVideoView---resume");
|
||||
isSuspendFromActivity = false;
|
||||
openVideo();
|
||||
seekTo(progressWhileSuspend);
|
||||
|
||||
if (mTagetStateBackup == V2XConst.STATE_IDLE)
|
||||
mTagetStateBackup = mTargetState;
|
||||
Logger.i(MODULE_NAME, "isFocusLoss = " + isFocusLoss);
|
||||
Logger.i(MODULE_NAME, "isInPlaybackState() = " + isInPlaybackState());
|
||||
if (isFocusLoss) {
|
||||
if (isInPlaybackState()) {
|
||||
if (mMediaPlayer.isPlaying()) {
|
||||
mMediaPlayer.pause();
|
||||
mCurrentState = V2XConst.STATE_PAUSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cache duration as mDuration for faster access
|
||||
public int getDuration() {
|
||||
if (isInPlaybackState()) {
|
||||
if (mDuration > 0) {
|
||||
return mDuration;
|
||||
}
|
||||
mDuration = mMediaPlayer.getDuration();
|
||||
return mDuration;
|
||||
}
|
||||
mDuration = -1;
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
public int getCurrentPosition() {
|
||||
if (isInPlaybackState()) {
|
||||
return mMediaPlayer.getCurrentPosition();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void seekTo(int msec) {
|
||||
Logger.i(MODULE_NAME, "TextureVideoView---seekTo---msec = " + msec);
|
||||
if (isInPlaybackState() && mCurrentState != V2XConst.STATE_SEEKING
|
||||
&& msec > 0 && msec < getDuration()) {
|
||||
mCurrentState = V2XConst.STATE_SEEKING;
|
||||
|
||||
Logger.i(MODULE_NAME, "MediaPlayer.seekTo(msec) = " + msec);
|
||||
mMediaPlayer.seekTo(msec);
|
||||
mSeekWhenPrepared = 0;
|
||||
} else {
|
||||
mSeekWhenPrepared = msec;
|
||||
progressWhileSuspend = msec;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
return isInPlaybackState() && mMediaPlayer.isPlaying();
|
||||
}
|
||||
|
||||
public int getBufferPercentage() {
|
||||
if (mMediaPlayer != null) {
|
||||
return mCurrentBufferPercentage;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private boolean isInPlaybackState() {
|
||||
return (mMediaPlayer != null && mCurrentState != V2XConst.STATE_ERROR
|
||||
&& mCurrentState != V2XConst.STATE_IDLE && mCurrentState != V2XConst.STATE_PREPARING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPause() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSeekBackward() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSeekForward() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getVideoPath() {
|
||||
if (mUri != null) {
|
||||
return mUri.getPath();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
|
||||
int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
public boolean isPause() {
|
||||
return mTargetState == V2XConst.STATE_PAUSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAudioSessionId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getCurrentState() {
|
||||
Logger.i(MODULE_NAME, "mCurrentState == " + mCurrentState);
|
||||
return mCurrentState;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.commons.voice.AIAssist;
|
||||
import com.mogo.eagle.core.widget.RoundLayout;
|
||||
import com.mogo.module.common.entity.MarkerCarInfo;
|
||||
import com.mogo.module.v2x.R;
|
||||
import com.mogo.module.v2x.V2XServiceManager;
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.core.content.ContextCompat;
|
||||
import com.mogo.cloud.trafficlive.api.ITrafficIntersectionLiveCallBack;
|
||||
import com.mogo.cloud.trafficlive.api.MoGoAiCloudTrafficLive;
|
||||
import com.mogo.commons.voice.AIAssist;
|
||||
import com.mogo.eagle.core.widget.RoundLayout;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
import com.mogo.module.common.entity.MarkerCarInfo;
|
||||
import com.mogo.module.v2x.R;
|
||||
|
||||
@@ -16,6 +16,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.mogo.commons.voice.AIAssist;
|
||||
import com.mogo.eagle.core.widget.RoundLayout;
|
||||
import com.mogo.module.common.entity.MarkerCarInfo;
|
||||
import com.mogo.module.v2x.R;
|
||||
import com.mogo.module.v2x.utils.V2XUtils;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
android:paddingBottom="@dimen/dp_20"
|
||||
app:roundLayoutRadius="@dimen/dp_30">
|
||||
|
||||
<com.mogo.module.v2x.view.RoundLayout
|
||||
<com.mogo.eagle.core.widget.RoundLayout
|
||||
android:id="@+id/rlRoadEventImg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
@@ -37,7 +37,7 @@
|
||||
android:src="@drawable/v2x_icon_event_play"
|
||||
android:visibility="gone" />
|
||||
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvEventTypeTitle"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.mogo.module.v2x.view.RoundLayout
|
||||
<com.mogo.eagle.core.widget.RoundLayout
|
||||
android:id="@+id/rlRoadEventList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/module_v2x_push_img_height"
|
||||
@@ -15,7 +15,7 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:roundLayoutRadius="@dimen/dp_30">
|
||||
|
||||
<com.mogo.module.v2x.view.RoundLayout
|
||||
<com.mogo.eagle.core.widget.RoundLayout
|
||||
android:id="@+id/rlRoadEventImg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -28,8 +28,8 @@
|
||||
android:scaleType="fitXY"
|
||||
app:actualImageScaleType="fitXY" />
|
||||
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
|
||||
<com.mogo.service.imageloader.MogoImageView
|
||||
android:id="@+id/ivReportHead"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mogo.module.v2x.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.mogo.eagle.core.widget.RoundLayout 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"
|
||||
@@ -50,4 +50,4 @@
|
||||
android:textSize="@dimen/dp_30"
|
||||
android:visibility="gone" />
|
||||
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mogo.module.v2x.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.mogo.eagle.core.widget.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/module_v2x_event_see_live_window_height"
|
||||
@@ -48,4 +48,4 @@
|
||||
android:textSize="@dimen/dp_30"
|
||||
android:visibility="gone" />
|
||||
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mogo.module.v2x.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.mogo.eagle.core.widget.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -48,4 +48,4 @@
|
||||
android:textSize="@dimen/dp_30"
|
||||
android:visibility="gone" />
|
||||
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mogo.module.v2x.view.RoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.mogo.eagle.core.widget.RoundLayout 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"
|
||||
@@ -65,4 +65,4 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/ivErrorIcon" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.mogo.module.v2x.view.RoundLayout
|
||||
<com.mogo.eagle.core.widget.RoundLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:roundLayoutRadius="@dimen/dp_26">
|
||||
@@ -70,6 +70,6 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/ivErrorIcon" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="@dimen/module_main_v2x_animation_width">
|
||||
|
||||
<com.mogo.module.v2x.view.RoundLayout
|
||||
<com.mogo.eagle.core.widget.RoundLayout
|
||||
android:id="@+id/rlRoadEventList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="@dimen/dp_30"
|
||||
app:roundLayoutRadius="@dimen/dp_28">
|
||||
|
||||
<com.mogo.module.v2x.view.TextureVideoView
|
||||
<com.mogo.eagle.core.widget.TextureVideoView
|
||||
android:id="@+id/vvCarAnimation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -24,6 +24,6 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -7,7 +7,7 @@
|
||||
android:background="@drawable/v2x_alert_window_bg"
|
||||
android:layout_margin="@dimen/dp_3">
|
||||
|
||||
<com.mogo.module.v2x.view.RoundLayout
|
||||
<com.mogo.eagle.core.widget.RoundLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:roundLayoutRadius="@dimen/dp_26">
|
||||
@@ -47,6 +47,6 @@
|
||||
android:layout_marginLeft="@dimen/dp_20"
|
||||
android:layout_marginTop="@dimen/dp_20"
|
||||
android:src="@drawable/module_common_close_selector" />
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
android:layout_margin="@dimen/dp_3"
|
||||
android:background="@drawable/v2x_bg_video_tip_vr">
|
||||
|
||||
<com.mogo.module.v2x.view.RoundLayout
|
||||
<com.mogo.eagle.core.widget.RoundLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:roundLayoutRadius="@dimen/dp_20">
|
||||
@@ -48,6 +48,6 @@
|
||||
android:layout_marginLeft="@dimen/dp_20"
|
||||
android:layout_marginTop="@dimen/dp_20"
|
||||
android:src="@drawable/module_common_close_selector_vr" />
|
||||
</com.mogo.module.v2x.view.RoundLayout>
|
||||
</com.mogo.eagle.core.widget.RoundLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">mogo-module-v2x</string>
|
||||
<string name="VideoView_info_text_video_not_supported">"不支持该视频。"</string>
|
||||
<string name="file_not_support">此文件不支持播放</string>
|
||||
<string name="v2x_help_speed_txt">车速</string>
|
||||
<string name="v2x_report_pop_submit_txt">已提交</string>
|
||||
<string name="v2x_report_pop_thank_txt">感谢已送达</string>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="RoundLayout">
|
||||
<attr name="roundLayoutRadius" format="dimension" />
|
||||
</declare-styleable>
|
||||
|
||||
<style name="customTabLayoutTextAppearance" parent="TextAppearance.Design.Tab">
|
||||
<item name="android:textSize">@dimen/dp_40</item>
|
||||
|
||||
Reference in New Issue
Block a user