add camera live
This commit is contained in:
@@ -53,6 +53,7 @@ import com.mogo.module.extensions.navi.NaviInfoView;
|
||||
import com.mogo.module.extensions.navi.VrModeNavInfoView;
|
||||
import com.mogo.module.extensions.userinfo.UserInfo;
|
||||
import com.mogo.module.extensions.utils.AdasNoticeHelper;
|
||||
import com.mogo.module.extensions.utils.CameraLiveNoticeHelper;
|
||||
import com.mogo.module.extensions.utils.EntranceViewHolder;
|
||||
import com.mogo.module.extensions.utils.NoMapTopViewShaderHelper;
|
||||
import com.mogo.module.extensions.utils.TopViewAnimHelper;
|
||||
@@ -205,6 +206,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
private TextView seekHelpNum;
|
||||
|
||||
private AdasNoticeHelper adasNoticeHelper = new AdasNoticeHelper();
|
||||
private CameraLiveNoticeHelper mCameraLiveNoticeHelper = new CameraLiveNoticeHelper();
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
@@ -221,6 +223,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
|
||||
adasNoticeHelper.init(getContext());
|
||||
adasNoticeHelper.initView(getView());
|
||||
mCameraLiveNoticeHelper.init(getContext());
|
||||
|
||||
mEntrancePresenter = new EntrancePresenter(getContext(), this);
|
||||
mMogoFragmentManager = mApis.getFragmentManagerApi();
|
||||
@@ -505,6 +508,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
showVrModeNaviView();
|
||||
mNaviInfo = new VrModeNavInfoView(mRootView);
|
||||
adasNoticeHelper.enterVrMode();
|
||||
mCameraLiveNoticeHelper.enterVrMode();
|
||||
TrafficLightPanelManager.getInstance().showNavPanel();
|
||||
}
|
||||
|
||||
@@ -523,6 +527,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
|
||||
hideVrModeNaviView();
|
||||
mNaviInfo = new NaviInfoView(mRootView);
|
||||
adasNoticeHelper.exitVrMode();
|
||||
mCameraLiveNoticeHelper.exitVrMode();
|
||||
TrafficLightPanelManager.getInstance().hideNavPanel();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.mogo.module.extensions.entrance;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -13,6 +14,7 @@ import com.mogo.map.location.IMogoLocationListener;
|
||||
import com.mogo.map.marker.IMogoMarkerClickListener;
|
||||
import com.mogo.map.navi.IMogoNaviListener;
|
||||
import com.mogo.module.common.MogoModulePaths;
|
||||
import com.mogo.module.extensions.live.ExtensionServiceManager;
|
||||
import com.mogo.service.module.IMogoModuleLifecycle;
|
||||
import com.mogo.service.module.IMogoModuleProvider;
|
||||
import com.mogo.service.module.ModuleType;
|
||||
@@ -32,6 +34,8 @@ public class EntranceProvider implements IMogoModuleProvider {
|
||||
public Fragment createFragment( Context context, Bundle data ) {
|
||||
mFragment = new EntranceFragment();
|
||||
mFragment.setArguments( data );
|
||||
Log.d("liyz", " createFragment ------> ");
|
||||
ExtensionServiceManager.init(context);
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
@@ -73,7 +77,8 @@ public class EntranceProvider implements IMogoModuleProvider {
|
||||
|
||||
@Override
|
||||
public void init( Context context ) {
|
||||
|
||||
Log.d("liyz", " EntranceProvider init ------> ");
|
||||
ExtensionServiceManager.init(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.mogo.module.extensions.live;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.module.extensions.view.LiveRoundLayout;
|
||||
import com.mogo.skin.support.IMogoSkinCompatSupportable;
|
||||
import com.mogo.skin.support.helper.MogoSkinCompatBackgroundHelperDelegate;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
import com.tencent.rtmp.ITXLivePlayListener;
|
||||
import com.tencent.rtmp.TXLiveConstants;
|
||||
import com.tencent.rtmp.TXLivePlayConfig;
|
||||
import com.tencent.rtmp.TXLivePlayer;
|
||||
import com.tencent.rtmp.ui.TXCloudVideoView;
|
||||
|
||||
/**
|
||||
* V2XLiveGSYVideoView
|
||||
*/
|
||||
public class CameraLiveGSYVideoView extends LiveRoundLayout implements IMogoSkinCompatSupportable {
|
||||
private static final String TAG = "CameraLiveGSYVideoView";
|
||||
|
||||
private TXCloudVideoView mTxcVideoView;
|
||||
private ProgressBar mLoading;
|
||||
private TXLivePlayer mLivePlayer;
|
||||
private ConstraintLayout mClLoadError;
|
||||
private TextView mTvRefreshButton;
|
||||
|
||||
private MogoSkinCompatBackgroundHelperDelegate mBackgroundTintHelper;
|
||||
private String mLiveUrl;
|
||||
|
||||
|
||||
public CameraLiveGSYVideoView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CameraLiveGSYVideoView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CameraLiveGSYVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initView(context);
|
||||
|
||||
mBackgroundTintHelper = new MogoSkinCompatBackgroundHelperDelegate(this);
|
||||
mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private void initView(Context context) {
|
||||
LayoutInflater.from(context)
|
||||
.inflate(R.layout.camera_view_video_layout_normal, this);
|
||||
//mPlayerView 即 step1 中添加的界面 view
|
||||
mTxcVideoView = findViewById(R.id.txcVideoView);
|
||||
//创建 player 对象
|
||||
mLivePlayer = new TXLivePlayer(context);
|
||||
//关键 player 对象与界面 view
|
||||
mLivePlayer.setPlayerView(mTxcVideoView);
|
||||
mLivePlayer.setMute(true);
|
||||
|
||||
TXLivePlayConfig txLivePlayConfig = new TXLivePlayConfig();
|
||||
// 增加重试次数
|
||||
txLivePlayConfig.setConnectRetryCount(30);
|
||||
mLivePlayer.setConfig(txLivePlayConfig);
|
||||
|
||||
mLivePlayer.enableHardwareDecode(true);
|
||||
|
||||
mLoading = findViewById(R.id.loading);
|
||||
mLoading.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(context, R.color.module_live_video_progress_bar_loading_color), PorterDuff.Mode.MULTIPLY);
|
||||
|
||||
mClLoadError = findViewById(R.id.clLoadError);
|
||||
mTvRefreshButton = findViewById(R.id.tvRefreshButton);
|
||||
mTvRefreshButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mLoading.setVisibility(VISIBLE);
|
||||
mClLoadError.setVisibility(GONE);
|
||||
if (mLiveUrl != null) {
|
||||
startLive(mLiveUrl);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 开始直播
|
||||
*
|
||||
* @param liveUrl 要直播的车机,如果没有直播的地址需要重新获取最新的直播地址
|
||||
*/
|
||||
public void startLive(String liveUrl) {
|
||||
// 进行直播播放
|
||||
if (mLivePlayer != null) {
|
||||
if (!TextUtils.isEmpty(liveUrl)) {
|
||||
mLiveUrl = liveUrl;
|
||||
playLiveVideo(liveUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放直播流,且开始心跳
|
||||
*/
|
||||
private void playLiveVideo(String liveUrl) {
|
||||
try {
|
||||
if (mLivePlayer != null) {
|
||||
mLivePlayer.startPlay(liveUrl, TXLivePlayer.PLAY_TYPE_LIVE_RTMP);
|
||||
mLivePlayer.setPlayListener(new ITXLivePlayListener() {
|
||||
@Override
|
||||
public void onPlayEvent(int event, Bundle bundle) {
|
||||
Logger.w(TAG,
|
||||
"直播信息= " +
|
||||
"\n播放器:onPlayEvent==" + event +
|
||||
"\nbundle===" + bundle);
|
||||
Logger.d(TAG, "liveUrl = " + liveUrl);
|
||||
if (event == TXLiveConstants.PLAY_EVT_PLAY_LOADING) {
|
||||
mLoading.setVisibility(VISIBLE);
|
||||
mClLoadError.setVisibility(GONE);
|
||||
} else if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {
|
||||
mLoading.setVisibility(GONE);
|
||||
mClLoadError.setVisibility(GONE);
|
||||
} else if (event < 0) {
|
||||
// AIAssist.getInstance(V2XUtils.getApp()).speakTTSVoice("直播获取失败,可以对我说重试", null);
|
||||
stopLive(mLiveUrl);
|
||||
mLoading.setVisibility(GONE);
|
||||
mClLoadError.setVisibility(VISIBLE);
|
||||
// // 注册语音交互
|
||||
// V2XVoiceManager.INSTANCE
|
||||
// .registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_CAR_LIVE,
|
||||
// v2XVoiceCallbackRefreshListener)
|
||||
// .registerUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_LIVE_UN_WAKEUP,
|
||||
// v2XVoiceCallbackRefreshListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetStatus(Bundle bundle) {
|
||||
Logger.w(TAG, "播放器:onNetStatus===bundle===" + bundle);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
mLoading.setVisibility(GONE);
|
||||
mClLoadError.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopLive(String liveUrl) {
|
||||
try {
|
||||
Logger.w(TAG, "心跳:关闭直播...");
|
||||
// 暂停
|
||||
mLivePlayer.pause();
|
||||
// true 代表清除最后一帧画面
|
||||
mLivePlayer.stopPlay(true);
|
||||
mTxcVideoView.onDestroy();
|
||||
// 停止推流
|
||||
// V2XServiceManager
|
||||
// .getV2XRefreshModel()
|
||||
// .livePush(new V2XRefreshCallback<V2XLivePushVoRes>() {
|
||||
// @Override
|
||||
// public void onSuccess(V2XLivePushVoRes result) {
|
||||
// Logger.d(TAG, "播放器:" + result);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFail(String msg) {
|
||||
// Logger.e(TAG, "播放器:" + msg);
|
||||
// }
|
||||
// }, carLiveInfo.getVideoSn(), 1);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (mLiveUrl != null) {
|
||||
startLive(mLiveUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
stopLive(mLiveUrl);
|
||||
mLoading.setVisibility(VISIBLE);
|
||||
// 反注册语音交互
|
||||
// V2XVoiceManager.INSTANCE
|
||||
// .unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_CAR_LIVE)
|
||||
// .unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_LIVE_UN_WAKEUP);
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySkin() {
|
||||
if (mBackgroundTintHelper != null) {
|
||||
mBackgroundTintHelper.applySkin();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package com.mogo.module.extensions.live;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.module.common.entity.CloudRoadData;
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.module.extensions.live.impl.AbsCameraScenario;
|
||||
import com.mogo.service.windowview.IMogoTopViewStatusListener;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
/**
|
||||
* 路边摄像头直播控制 V2XPushLiveCarScenario
|
||||
*/
|
||||
public class CameraLiveManager extends AbsCameraScenario<CloudRoadData> implements IMogoTopViewStatusListener {
|
||||
private static final String TAG = "CameraLiveManager";
|
||||
private static CameraLiveManager mCameraLiveCarScenario;
|
||||
private boolean isShowWindow;
|
||||
|
||||
private CameraLiveManager() {
|
||||
}
|
||||
|
||||
public static CameraLiveManager getInstance() {
|
||||
if (mCameraLiveCarScenario == null) {
|
||||
synchronized (CameraLiveManager.class) {
|
||||
if (mCameraLiveCarScenario == null) {
|
||||
mCameraLiveCarScenario = new CameraLiveManager();
|
||||
mCameraLiveCarScenario.setV2XWindow(new PushCameraLiveWindow());
|
||||
}
|
||||
}
|
||||
}
|
||||
return mCameraLiveCarScenario;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(@Nullable CloudRoadData cloudRoadData) {
|
||||
Log.d(TAG, "CameraLiveManager init -----> ");
|
||||
if (isShowWindow) {
|
||||
close();
|
||||
}
|
||||
|
||||
setmCloudRoadData(cloudRoadData);
|
||||
show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
showWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showWindow() {
|
||||
Log.d(TAG, "CameraLiveManager showWindow --------");
|
||||
if (getV2XWindow() != null) {
|
||||
ViewGroup.LayoutParams layoutParams =
|
||||
new ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
(int) AbsMogoApplication.getApp().getResources()
|
||||
.getDimension(R.dimen.module_video_window_height_content));
|
||||
|
||||
ExtensionServiceManager
|
||||
.getMogoTopViewManager()
|
||||
.addViewNoLinkage(getV2XWindow().getView(), layoutParams, this);
|
||||
getV2XWindow().show(getmCloudRoadData());
|
||||
isShowWindow = true;
|
||||
// ExtensionServiceManager.getMoGoV2XStatusManager().setRoadLiveCarWindowShow(TAG, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeWindow() {
|
||||
if (getV2XWindow() != null) {
|
||||
getV2XWindow().close();
|
||||
}
|
||||
isShowWindow = false;
|
||||
// ExtensionServiceManager.getMoGoV2XStatusManager().setRoadLiveCarWindowShow(TAG, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showButton() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeButton() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPOI() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPOI() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAdded(View view) {
|
||||
Logger.d(TAG, "展示 Window 动画结束");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewRemoved(View view) {
|
||||
Logger.d(TAG, "关闭 Window 动画结束");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeViewAddAnim(View view) {
|
||||
Logger.d(TAG, "展示 Window 开始");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeViewRemoveAnim(View view) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
package com.mogo.module.extensions.live;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter;
|
||||
import com.mogo.map.location.IMogoLocationClient;
|
||||
import com.mogo.map.marker.IMogoMarkerManager;
|
||||
import com.mogo.map.navi.IMogoNavi;
|
||||
import com.mogo.map.overlay.IMogoOverlayManager;
|
||||
import com.mogo.map.search.geo.IMogoGeoSearch;
|
||||
import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
import com.mogo.service.IMogoServiceApis;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
import com.mogo.service.analytics.IMogoAnalytics;
|
||||
import com.mogo.service.connection.IMogoSocketManager;
|
||||
import com.mogo.service.entrance.IMogoEntranceButtonController;
|
||||
import com.mogo.service.eventpanel.IEventPanelProvider;
|
||||
import com.mogo.service.imageloader.IMogoImageloader;
|
||||
import com.mogo.service.intent.IMogoIntentManager;
|
||||
import com.mogo.service.map.IMogoMapService;
|
||||
import com.mogo.service.module.IMogoActionManager;
|
||||
import com.mogo.service.module.IMogoMarkerService;
|
||||
import com.mogo.service.module.IMogoRegisterCenter;
|
||||
import com.mogo.service.module.IMogoSearchManager;
|
||||
import com.mogo.service.share.IMogoShareManager;
|
||||
import com.mogo.service.share.IMogoTanluProvider;
|
||||
import com.mogo.service.share.IMogoTrafficUploadProvider;
|
||||
import com.mogo.service.statusmanager.IMogoStatusManager;
|
||||
import com.mogo.service.strategy.IMogoOnlineCarListPanelProvider;
|
||||
import com.mogo.service.strategy.IMogoRefreshStrategyController;
|
||||
import com.mogo.service.windowview.IMogoTopViewManager;
|
||||
import com.mogo.service.windowview.IMogoWindowManager;
|
||||
|
||||
|
||||
public class ExtensionServiceManager {
|
||||
private static boolean isInit;
|
||||
private static Context mContext;
|
||||
private static IMogoServiceApis mMogoServiceApis;
|
||||
|
||||
private static IMogoMapService mMapService;
|
||||
private static IMogoMarkerManager mMarkerManager;
|
||||
private static IMogoNavi mNavi;
|
||||
private static IMogoMapUIController mMapUIController;
|
||||
private static IMogoLocationClient mMogoLocationClient;
|
||||
private static IMogoGeoSearch mIMogoGeoSearch;
|
||||
private static IMogoSearchManager mIMogoSearchManager;
|
||||
private static IMogoTopViewManager mMogoTopViewManager;
|
||||
private static IMogoStatusManager mMogoStatusManager;
|
||||
private static IMogoWindowManager mIMogoWindowManager;
|
||||
private static IMogoImageloader mImageLoader;
|
||||
private static IMogoSocketManager mMogoSocketManager;
|
||||
private static IMogoAnalytics mMogoAnalytics;
|
||||
private static IMogoOverlayManager mMogoOverlayManager;
|
||||
private static IMogoRegisterCenter mMogoRegisterCenter;
|
||||
private static IMogoRefreshStrategyController mIMogoRefreshStrategyController;
|
||||
private static IMogoMarkerService mIMogoMarkerService;
|
||||
private static IMogoShareManager mIMogoShareManager;
|
||||
private static IMogoTanluProvider mIMogoTanluProvider;
|
||||
private static IMogoTrafficUploadProvider mIMogoTrafficUploadProvider;
|
||||
//事件面板
|
||||
private static IEventPanelProvider mIEventPanelProvider;
|
||||
|
||||
private static IMogoActionManager mMogoActionManager;
|
||||
private static IMogoIntentManager mMogoIntentManager;
|
||||
private static IMogoEntranceButtonController mMogoEntranceButtonController;
|
||||
private static IMogoOnlineCarListPanelProvider mMogoOnlineCarListPanelProvider;
|
||||
|
||||
|
||||
private ExtensionServiceManager() {
|
||||
|
||||
}
|
||||
|
||||
public static void init(final Context context) {
|
||||
if (!isInit) {
|
||||
isInit = true;
|
||||
|
||||
mContext = context;
|
||||
mMogoServiceApis = (IMogoServiceApis) ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation(context);
|
||||
|
||||
mMapService = mMogoServiceApis.getMapServiceApi();
|
||||
mImageLoader = mMogoServiceApis.getImageLoaderApi();
|
||||
mMogoStatusManager = mMogoServiceApis.getStatusManagerApi();
|
||||
mMogoSocketManager = mMogoServiceApis.getSocketManagerApi(context);
|
||||
mMogoAnalytics = mMogoServiceApis.getAnalyticsApi();
|
||||
mIMogoWindowManager = mMogoServiceApis.getWindowManagerApi();
|
||||
mMogoRegisterCenter = mMogoServiceApis.getRegisterCenterApi();
|
||||
mIMogoRefreshStrategyController = mMogoServiceApis.getRefreshStrategyControllerApi();
|
||||
mMogoEntranceButtonController = mMogoServiceApis.getEntranceButtonController();
|
||||
mMogoActionManager = mMogoServiceApis.getActionManagerApi();
|
||||
mMogoTopViewManager = mMogoServiceApis.getTopViewManager();
|
||||
mIMogoSearchManager = mMogoServiceApis.getSearchManagerApi();
|
||||
mIMogoMarkerService = mMogoServiceApis.getMarkerService();
|
||||
mIMogoShareManager = mMogoServiceApis.getShareManager();
|
||||
mIMogoTanluProvider = mMogoServiceApis.getTanluApi();
|
||||
mIMogoTrafficUploadProvider = mMogoServiceApis.getTrafficUploadApi();
|
||||
mMogoOnlineCarListPanelProvider = mMogoServiceApis.getOnlineCarPanelApi();
|
||||
//事件面板
|
||||
mIEventPanelProvider = mMogoServiceApis.getEventPanelManager();
|
||||
|
||||
mMarkerManager = mMapService.getMarkerManager(context);
|
||||
mNavi = mMapService.getNavi(context);
|
||||
mMapUIController = mMapService.getMapUIController();
|
||||
mMogoLocationClient = mMapService.getSingletonLocationClient(context);
|
||||
mMogoOverlayManager = mMapService.getOverlayManager(context);
|
||||
mIMogoGeoSearch = mMapService.getGeoSearch(context);
|
||||
|
||||
mMogoIntentManager = mMogoServiceApis.getIntentManagerApi();
|
||||
}
|
||||
}
|
||||
|
||||
public static Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public static IMogoTopViewManager getMogoTopViewManager() {
|
||||
return mMogoTopViewManager;
|
||||
}
|
||||
|
||||
public static IMogoEntranceButtonController getMogoEntranceButtonController() {
|
||||
return mMogoEntranceButtonController;
|
||||
}
|
||||
|
||||
public static IMogoMapService getMapService() {
|
||||
return mMapService;
|
||||
}
|
||||
|
||||
public static IMogoOverlayManager getMogoOverlayManager() {
|
||||
return mMogoOverlayManager;
|
||||
}
|
||||
|
||||
public static IMogoRegisterCenter getMogoRegisterCenter() {
|
||||
return mMogoRegisterCenter;
|
||||
}
|
||||
|
||||
public static IMogoMarkerManager getMarkerManager() {
|
||||
return mMarkerManager;
|
||||
}
|
||||
|
||||
public static IMogoNavi getNavi() {
|
||||
return mNavi;
|
||||
}
|
||||
|
||||
public static IMogoMapUIController getMapUIController() {
|
||||
return mMapUIController;
|
||||
}
|
||||
|
||||
public static IMogoLocationClient getMogoLocationClient() {
|
||||
return mMogoLocationClient;
|
||||
}
|
||||
|
||||
public static IMogoImageloader getImageLoader() {
|
||||
return mImageLoader;
|
||||
}
|
||||
|
||||
public static IMogoSocketManager getMoGoSocketManager() {
|
||||
return mMogoSocketManager;
|
||||
}
|
||||
|
||||
public static IMogoStatusManager getMoGoStatusManager() {
|
||||
return mMogoStatusManager;
|
||||
}
|
||||
|
||||
public static IMogoWindowManager getIMogoWindowManager() {
|
||||
return mIMogoWindowManager;
|
||||
}
|
||||
|
||||
public static IMogoIntentManager getMogoIntentManager() {
|
||||
return mMogoIntentManager;
|
||||
}
|
||||
|
||||
public static IMogoActionManager getMogoActionManager() {
|
||||
return mMogoActionManager;
|
||||
}
|
||||
|
||||
public static IMogoGeoSearch getMogoGeoSearch() {
|
||||
return mIMogoGeoSearch;
|
||||
}
|
||||
|
||||
public static IMogoSearchManager getSearchManager() {
|
||||
return mIMogoSearchManager;
|
||||
}
|
||||
|
||||
public static IMogoRefreshStrategyController getIMogoRefreshStrategyController() {
|
||||
return mIMogoRefreshStrategyController;
|
||||
}
|
||||
|
||||
public static IMogoAnalytics getMogoAnalytics() {
|
||||
return mMogoAnalytics;
|
||||
}
|
||||
|
||||
public static IMogoMarkerService getIMogoMarkerService() {
|
||||
return mIMogoMarkerService;
|
||||
}
|
||||
|
||||
public static IMogoShareManager getMogoShareManager() {
|
||||
return mIMogoShareManager;
|
||||
}
|
||||
|
||||
public static IMogoTanluProvider getTanluManager() {
|
||||
return mIMogoTanluProvider;
|
||||
}
|
||||
|
||||
public static IMogoTrafficUploadProvider getIMogoTrafficUploadProvider() {
|
||||
return mIMogoTrafficUploadProvider;
|
||||
}
|
||||
|
||||
public static IMogoOnlineCarListPanelProvider getMogoOnlineCarListPanelProvider() {
|
||||
return mMogoOnlineCarListPanelProvider;
|
||||
}
|
||||
|
||||
public static IEventPanelProvider getEventPanelProvider() {
|
||||
return mIEventPanelProvider;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.mogo.module.extensions.live;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.mogo.module.common.entity.CloudRoadData;
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.module.extensions.live.listener.CameraLiveWindowStatusListener;
|
||||
import com.mogo.module.extensions.live.impl.ICameraWindow;
|
||||
import com.mogo.service.imageloader.MogoImageView;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* 点击摄像头 marker
|
||||
* vr路边摄像头弹窗 V2XPushLiveCarWindow
|
||||
*/
|
||||
public class PushCameraLiveWindow extends RelativeLayout implements ICameraWindow<CloudRoadData> {
|
||||
private static final String TAG = "PushCameraLiveWindow";
|
||||
private Context mContext;
|
||||
private CameraLiveGSYVideoView mLiveGSYVideoView;
|
||||
private MogoImageView mIvReportHead;
|
||||
private ImageView pushVideoClose;
|
||||
|
||||
// 弹窗状态监听
|
||||
private CameraLiveWindowStatusListener mWindowStatusListener;
|
||||
|
||||
// 直播30秒自动关闭
|
||||
private static Handler handlerV2XEvent = new Handler();
|
||||
private static Runnable runnableV2XEvent;
|
||||
|
||||
public PushCameraLiveWindow() {
|
||||
this(ExtensionServiceManager.getContext(), null);
|
||||
}
|
||||
|
||||
public PushCameraLiveWindow(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public PushCameraLiveWindow(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public PushCameraLiveWindow(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mContext = context;
|
||||
initView(context);
|
||||
}
|
||||
|
||||
public void initView(Context context) {
|
||||
Logger.w(TAG, "initView 。。。。。");
|
||||
LayoutInflater.from(context).inflate(R.layout.camera_push_live_video, this);
|
||||
// 详情列表
|
||||
mLiveGSYVideoView = findViewById(R.id.videoPlayer);
|
||||
mIvReportHead = findViewById(R.id.ivReportHead);
|
||||
pushVideoClose = findViewById(R.id.pushVideoClose);
|
||||
pushVideoClose.setOnClickListener(v -> {
|
||||
//移除窗体
|
||||
ExtensionServiceManager
|
||||
.getMogoTopViewManager()
|
||||
.removeViewNoLinkage(this);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示直播Windows
|
||||
*/
|
||||
@Override
|
||||
public void show(CloudRoadData entity) {
|
||||
if (entity != null) {
|
||||
Logger.w(TAG, "更新直播信息 show entity = " + entity);
|
||||
if (!TextUtils.isEmpty(entity.getRtmpUrl())) {
|
||||
Logger.w(TAG, "entity.getRtmpUrl() = " + entity.getRtmpUrl());
|
||||
mIvReportHead.setVisibility(VISIBLE);
|
||||
ExtensionServiceManager.getImageLoader()
|
||||
.displayImage(entity.getRtmpUrl(), mIvReportHead);
|
||||
mLiveGSYVideoView.startLive(entity.getRtmpUrl());
|
||||
}
|
||||
|
||||
countDownV2XEvent(entity);
|
||||
if (mWindowStatusListener != null) {
|
||||
mWindowStatusListener.onViewShow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// 修改地图比例
|
||||
// V2XServiceManager.getMoGoStatusManager().setUserInteractionStatus(MODULE_NAME, true, false);
|
||||
// 锁车就是将地图视图移植中心点,因为行驶中的车和地图要相对的跟随
|
||||
// MarkerUtils.resetMapZoom(16);
|
||||
|
||||
// 如果窗体处于展示的时候
|
||||
if (mWindowStatusListener != null) {
|
||||
mWindowStatusListener.onViewClose();
|
||||
}
|
||||
|
||||
// 停止倒计时
|
||||
if (handlerV2XEvent != null && runnableV2XEvent != null) {
|
||||
handlerV2XEvent.removeCallbacks(runnableV2XEvent);
|
||||
runnableV2XEvent = null;
|
||||
}
|
||||
|
||||
//移除窗体
|
||||
ExtensionServiceManager
|
||||
.getMogoTopViewManager()
|
||||
.removeView(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setWindowStatusListener(CameraLiveWindowStatusListener listener) {
|
||||
this.mWindowStatusListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 窗体倒计时 TODO
|
||||
*/
|
||||
public void countDownV2XEvent(CloudRoadData data) {
|
||||
// 倒计时
|
||||
if (runnableV2XEvent == null) {
|
||||
runnableV2XEvent = () -> {
|
||||
//Logger.d(MODULE_NAME, "V2X=== Window 30秒倒计时结束。。。");
|
||||
//移除窗体
|
||||
ExtensionServiceManager
|
||||
.getMogoTopViewManager()
|
||||
.removeViewNoLinkage(this);
|
||||
};
|
||||
} else {
|
||||
handlerV2XEvent.removeCallbacks(runnableV2XEvent);
|
||||
}
|
||||
|
||||
Logger.d(TAG, "V2X=== Window 展示开始倒计时:" );
|
||||
handlerV2XEvent.postDelayed(runnableV2XEvent, 20000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.mogo.module.extensions.live;
|
||||
|
||||
/**
|
||||
* @author lixiaopeng
|
||||
* @description
|
||||
* @since 2020/12/13
|
||||
*/
|
||||
public class PushDataType {
|
||||
/**
|
||||
* Push 摄像头事件场景 VR
|
||||
*/
|
||||
public static final String TYPE_PUSH_CAMERA_DATA = "TYPE_PUSH_CAMERA_DATA";
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.mogo.module.extensions.live.impl;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.module.common.entity.CloudRoadData;
|
||||
|
||||
|
||||
public abstract class AbsCameraScenario<T> implements ICameraScenario {
|
||||
protected String TAG = "AbsCameraScenario";
|
||||
private ICameraWindow mV2XWindow;
|
||||
private CloudRoadData mCloudRoadData;
|
||||
|
||||
// private IV2XButton mV2XButton;
|
||||
// private IV2XMarker mV2XMarker;
|
||||
// private IMoGoV2XStatusManager mV2XStatusManager;
|
||||
// private V2XMessageEntity<T> mV2XMessageEntity;
|
||||
|
||||
// protected AbsCameraScenario() {
|
||||
// this.mV2XStatusManager = V2XServiceManager.getMoGoV2XStatusManager();
|
||||
// }
|
||||
|
||||
public abstract void init(@Nullable CloudRoadData cloudRoadData);
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
closeButton();
|
||||
closeWindow();
|
||||
clearPOI();
|
||||
}
|
||||
|
||||
|
||||
public ICameraWindow getV2XWindow() {
|
||||
return mV2XWindow;
|
||||
}
|
||||
|
||||
public void setV2XWindow(@Nullable ICameraWindow mV2XWindow) {
|
||||
this.mV2XWindow = mV2XWindow;
|
||||
}
|
||||
|
||||
public CloudRoadData getmCloudRoadData() {
|
||||
return mCloudRoadData;
|
||||
}
|
||||
|
||||
public void setmCloudRoadData(CloudRoadData mCloudRoadData) {
|
||||
this.mCloudRoadData = mCloudRoadData;
|
||||
}
|
||||
|
||||
// public IV2XMarker getV2XMarker() {
|
||||
// return mV2XMarker;
|
||||
// }
|
||||
//
|
||||
// public IV2XButton getV2XButton() {
|
||||
// return mV2XButton;
|
||||
// }
|
||||
|
||||
// public void setV2XButton(@Nullable IV2XButton mV2XButton) {
|
||||
// this.mV2XButton = mV2XButton;
|
||||
// }
|
||||
//
|
||||
// public void setV2XMarker(@Nullable IV2XMarker mV2XMarker) {
|
||||
// this.mV2XMarker = mV2XMarker;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.mogo.module.extensions.live.impl;
|
||||
|
||||
|
||||
public interface ICameraScenario {
|
||||
|
||||
/**
|
||||
* 展示场景
|
||||
*/
|
||||
void show();
|
||||
|
||||
/**
|
||||
* 关闭场景
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* 展示Window
|
||||
*/
|
||||
void showWindow();
|
||||
|
||||
/**
|
||||
* 关闭Window
|
||||
*/
|
||||
void closeWindow();
|
||||
|
||||
/**
|
||||
* 展示按钮
|
||||
*/
|
||||
void showButton();
|
||||
|
||||
/**
|
||||
* 关闭按钮
|
||||
*/
|
||||
void closeButton();
|
||||
|
||||
/**
|
||||
* 绘制POI
|
||||
*/
|
||||
void drawPOI();
|
||||
|
||||
/**
|
||||
* 清除POI
|
||||
*/
|
||||
void clearPOI();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.mogo.module.extensions.live.impl;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.mogo.module.extensions.live.listener.CameraLiveWindowStatusListener;
|
||||
|
||||
public interface ICameraWindow<T> {
|
||||
|
||||
/**
|
||||
* 展示1/2窗口
|
||||
*/
|
||||
void show(T entity);
|
||||
|
||||
/**
|
||||
* 关闭1/2窗口
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* 返回窗体
|
||||
*
|
||||
* @return 当前窗体
|
||||
*/
|
||||
View getView();
|
||||
|
||||
/**
|
||||
* 设置Window状态监听
|
||||
*
|
||||
* @param listener 监听器
|
||||
*/
|
||||
void setWindowStatusListener(CameraLiveWindowStatusListener listener);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.mogo.module.extensions.live.listener;
|
||||
|
||||
|
||||
public interface CameraLiveWindowStatusListener {
|
||||
void onViewShow();
|
||||
void onViewClose();
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.mogo.module.extensions.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.map.marker.IMogoMarker;
|
||||
import com.mogo.map.marker.IMogoMarkerClickListener;
|
||||
import com.mogo.map.marker.MogoMarkerOptions;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.module.common.constants.DataTypes;
|
||||
import com.mogo.module.common.entity.CloudRoadData;
|
||||
import com.mogo.module.common.entity.MogoSnapshotSetData;
|
||||
import com.mogo.module.extensions.R;
|
||||
import com.mogo.module.extensions.live.CameraLiveManager;
|
||||
import com.mogo.module.extensions.live.ExtensionServiceManager;
|
||||
import com.mogo.module.extensions.live.PushDataType;
|
||||
import com.mogo.service.connection.IMogoOnWebSocketMessageListener;
|
||||
import com.mogo.service.connection.WebSocketMsgType;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* vr模式下,红绿灯消息 AdasNoticeHelper
|
||||
*
|
||||
*/
|
||||
public class CameraLiveNoticeHelper implements IMogoOnWebSocketMessageListener<MogoSnapshotSetData> {
|
||||
private static final String TAG = "CameraLiveNoticeHelper";
|
||||
private Context mContext;
|
||||
private static IMogoMarker mMogoMarker;
|
||||
private CloudRoadData mCloudRoadData;
|
||||
|
||||
|
||||
public void init(Context context) {
|
||||
Logger.d(TAG, "init====");
|
||||
mContext = context;
|
||||
ExtensionServiceManager
|
||||
.getMogoRegisterCenter().registerMogoMarkerClickListener(PushDataType.TYPE_PUSH_CAMERA_DATA, new IMogoMarkerClickListener() {
|
||||
@Override
|
||||
public boolean onMarkerClicked(IMogoMarker marker) {
|
||||
//点击的marker的具体数据 TODO
|
||||
if (mCloudRoadData != null) {
|
||||
CameraLiveManager.getInstance().init(mCloudRoadData);
|
||||
} else {
|
||||
Logger.e(TAG, " mCloudRoadData == null ");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void enterVrMode() {
|
||||
Logger.d(TAG, "enterVrMode===");
|
||||
MogoApisHandler.getInstance().getApis().getWebSocketManagerApi(mContext).registerOnWebSocketMessageListener(this);
|
||||
}
|
||||
|
||||
public void exitVrMode() {
|
||||
Logger.d(TAG, "退出vr模式===");
|
||||
MogoApisHandler.getInstance().getApis().getWebSocketManagerApi(mContext).unregisterOnWebSocketMessageListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* PushRoadConditionDrawer
|
||||
* @param roadData
|
||||
*/
|
||||
private void addCameraMarker(CloudRoadData roadData) {
|
||||
Logger.d(TAG, "addCameraMarker ------ ");
|
||||
MogoMarkerOptions options = new MogoMarkerOptions()
|
||||
.object(roadData)
|
||||
.latitude(roadData.getLat())
|
||||
.longitude(roadData.getLon());
|
||||
options.anchor(0.5f, 0.5f);
|
||||
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.module_camera_real_time_traffic, null);
|
||||
options.icon(bitmap);
|
||||
mMogoMarker = MogoApisHandler
|
||||
.getInstance()
|
||||
.getApis()
|
||||
.getMapServiceApi()
|
||||
.getMarkerManager(AbsMogoApplication.getApp())
|
||||
.addMarker(DataTypes.TYPE_MARKER_PUSH_DATA, options);
|
||||
|
||||
ExtensionServiceManager.getMapService().getMarkerManager(mContext).addMarker(PushDataType.TYPE_PUSH_CAMERA_DATA, options);
|
||||
}
|
||||
|
||||
private void removeCameraMarker() {
|
||||
if (mMogoMarker != null) {
|
||||
mMogoMarker.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public WebSocketMsgType getDownLinkType() {
|
||||
return WebSocketMsgType.MSG_TYPE_DOWNLINK_CAR_DATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<MogoSnapshotSetData> target() {
|
||||
return MogoSnapshotSetData.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMsgReceived(MogoSnapshotSetData obj) {
|
||||
Logger.d(TAG, "onMsgReceived cameralive : " + obj);
|
||||
mCloudRoadData = obj.getTrafficLight();
|
||||
if (mCloudRoadData != null) {
|
||||
Logger.d(TAG, "onMsgReceived cameralive : ");
|
||||
//添加marker TODO
|
||||
addCameraMarker(mCloudRoadData);
|
||||
|
||||
} else {
|
||||
//删除marker TODO
|
||||
removeCameraMarker();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.mogo.module.extensions.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.extensions.R;
|
||||
import com.mogo.skin.support.IMogoSkinCompatSupportable;
|
||||
import com.mogo.skin.support.helper.MogoSkinCompatBackgroundHelperDelegate;
|
||||
|
||||
|
||||
public class LiveRoundLayout extends RelativeLayout implements IMogoSkinCompatSupportable {
|
||||
private float roundLayoutRadius = 14f;
|
||||
private Path roundPath;
|
||||
private RectF rectF;
|
||||
private MogoSkinCompatBackgroundHelperDelegate mBackgroundTintHelper;
|
||||
|
||||
public LiveRoundLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public LiveRoundLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public LiveRoundLayout(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();
|
||||
|
||||
mBackgroundTintHelper = new MogoSkinCompatBackgroundHelperDelegate(this);
|
||||
mBackgroundTintHelper.loadFromAttributes(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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySkin() {
|
||||
if (mBackgroundTintHelper != null) {
|
||||
mBackgroundTintHelper.applySkin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user