opt
@@ -9,6 +9,7 @@ import android.view.animation.OvershootInterpolator
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.commons.voice.AIAssist
|
||||
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalData
|
||||
import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData
|
||||
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
@@ -16,6 +17,7 @@ import com.mogo.eagle.core.function.hmi.notification.WarningFloat
|
||||
import com.mogo.eagle.core.function.hmi.notification.anim.DefaultAnimator
|
||||
import com.mogo.eagle.core.function.hmi.notification.enums.SidePattern
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeBannerView
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeFloatView
|
||||
import com.mogo.eagle.core.function.hmi.ui.widget.V2XNotificationView
|
||||
import com.mogo.module.common.enums.EventTypeEnum
|
||||
import com.mogo.utils.logger.Logger
|
||||
@@ -257,4 +259,18 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var floatView: NoticeFloatView? = null
|
||||
|
||||
/**
|
||||
* 展示普通公告 liyz
|
||||
* @param normalData
|
||||
*/
|
||||
override fun showNoticeNormal(normalData: NoticeNormalData) {
|
||||
if (floatView == null) {
|
||||
floatView = this.getContext()?.let { NoticeFloatView(it) }
|
||||
}
|
||||
floatView?.pushBeanChanged(normalData)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.mogo.eagle.core.function.hmi.ui
|
||||
import com.mogo.commons.mvp.IView
|
||||
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
|
||||
import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalData
|
||||
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
|
||||
|
||||
|
||||
@@ -102,5 +103,11 @@ interface MoGoWarningContract {
|
||||
* @param trafficStylePushData
|
||||
*/
|
||||
fun showNoticeForTrafficWithData(trafficStylePushData: NoticeTrafficStylePushData)
|
||||
|
||||
/**
|
||||
* 展示普通云公告
|
||||
* @param normalData
|
||||
*/
|
||||
fun showNoticeNormal(normalData: NoticeNormalData)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.notice
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
import com.mogo.module.common.dialog.BaseFloatDialog
|
||||
|
||||
/**
|
||||
* 点击查看对话框,需要做接口的请求 TODO
|
||||
*/
|
||||
class NoticeCheckDialog(context: Context) : BaseFloatDialog(context) {
|
||||
|
||||
private var pushCheckClose: ImageView? = null
|
||||
private var pushCheckTitle: TextView? = null
|
||||
private var pushCheckContent: TextView? = null
|
||||
|
||||
init {
|
||||
setContentView(R.layout.notice_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()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.notice
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.LayoutRes
|
||||
import com.mogo.commons.context.ContextHolderUtil
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalData
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.roundimage.RoundedImageView
|
||||
import com.mogo.eagle.core.function.hmi.ui.utils.getApis
|
||||
import com.mogo.eagle.core.function.hmi.ui.utils.gone
|
||||
import com.mogo.eagle.core.function.hmi.ui.utils.visible
|
||||
import com.mogo.service.windowview.IMogoTopViewManager
|
||||
import com.mogo.service.windowview.IMogoTopViewStatusListener
|
||||
import com.mogo.utils.glide.GlideApp
|
||||
|
||||
/**
|
||||
* 云公告弹框view
|
||||
*/
|
||||
class NoticeFloatView constructor(
|
||||
private val context: Context
|
||||
) {
|
||||
|
||||
companion object {
|
||||
const val TYPE_TOP_VIEW = 1
|
||||
const val TYPE_WINDOW_MANAGER = 2
|
||||
const val TAG: String = "FloatView.kt"
|
||||
}
|
||||
|
||||
interface PushViewController {
|
||||
fun show(bean: NoticeNormalData?)
|
||||
fun hide()
|
||||
fun inflateView(@LayoutRes layoutId: Int)
|
||||
}
|
||||
|
||||
abstract inner class PushView(context: Context) : FrameLayout(context),
|
||||
PushViewController {
|
||||
private lateinit var titleIconContainer: View
|
||||
private lateinit var pushTitle: TextView
|
||||
private lateinit var pushImage: RoundedImageView
|
||||
private lateinit var pushContent: TextView
|
||||
private lateinit var pushCheck: TextView
|
||||
private var pushData: NoticeNormalData? = null
|
||||
|
||||
override fun inflateView(layoutId: Int) {
|
||||
LayoutInflater.from(context).inflate(layoutId, this, true)
|
||||
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)
|
||||
titleIconContainer = findViewById(R.id.module_push_app_icon_title)
|
||||
|
||||
//查看结果
|
||||
pushCheck.setOnClickListener {
|
||||
pushData?.let {
|
||||
if (pushCheckDialog == null) {
|
||||
pushCheckDialog = NoticeCheckDialog(ContextHolderUtil.getContext())
|
||||
}
|
||||
pushCheckDialog!!.showCheckDialog(it.title, it.content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open fun setBean(bean: NoticeNormalData) {
|
||||
pushData = bean
|
||||
// title
|
||||
pushTitle.text = bean.title
|
||||
|
||||
// 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()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
override fun show(bean: NoticeNormalData?) {
|
||||
isAddWindow = true
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
isAddWindow = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open inner class PushViewInTopView(context: Context) : PushView(context) {
|
||||
|
||||
private val mTopViewManager: IMogoTopViewManager = getApis(context).topViewManager
|
||||
|
||||
init {
|
||||
inflateView(R.layout.notice_module_push_item)
|
||||
}
|
||||
|
||||
private var topViewStatusListener = object : IMogoTopViewStatusListener {
|
||||
override fun onViewRemoved(view: View?) {
|
||||
isAddWindow = false
|
||||
}
|
||||
|
||||
override fun onViewAdded(view: View?) {
|
||||
|
||||
}
|
||||
|
||||
override fun beforeViewRemoveAnim(view: View?) {
|
||||
}
|
||||
|
||||
override fun beforeViewAddAnim(view: View?) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun show(bean: NoticeNormalData?) {
|
||||
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)
|
||||
}
|
||||
|
||||
private var pushCheckDialog: NoticeCheckDialog? = null
|
||||
private val delayClosePush: Runnable
|
||||
private var isAddWindow = false
|
||||
private val uiHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
private var currentBean: NoticeNormalData? = null
|
||||
private var mLastVisibleType = -1
|
||||
private var pushViewController: PushViewController? = null
|
||||
|
||||
init {
|
||||
delayClosePush = Runnable {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun pushBeanChanged(bean: NoticeNormalData?) {
|
||||
Log.d("liyz", "NoticeFloatVideo pushBeanChanged -----> bean = " + bean)
|
||||
uiHandler.post {
|
||||
uiHandler.removeCallbacks(delayClosePush)
|
||||
if (bean == null) {
|
||||
hide()
|
||||
} else {
|
||||
show(bean)
|
||||
}
|
||||
currentBean = bean
|
||||
}
|
||||
}
|
||||
|
||||
private fun show(bean: NoticeNormalData) {
|
||||
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: NoticeNormalData) {
|
||||
if (pushViewController !is PushViewInTopView) {
|
||||
pushViewController = PushViewInTopView(context)
|
||||
}
|
||||
pushViewController?.show(bean)
|
||||
}
|
||||
|
||||
private fun showByWindowManager(bean: NoticeNormalData?) {
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.notice.roundimage;
|
||||
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
Corner.TOP_LEFT, Corner.TOP_RIGHT,
|
||||
Corner.BOTTOM_LEFT, Corner.BOTTOM_RIGHT
|
||||
})
|
||||
public @interface Corner {
|
||||
int TOP_LEFT = 0;
|
||||
int TOP_RIGHT = 1;
|
||||
int BOTTOM_RIGHT = 2;
|
||||
int BOTTOM_LEFT = 3;
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Vincent Mi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.mogo.eagle.core.function.hmi.ui.notice.roundimage;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
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.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public class RoundedDrawable extends Drawable {
|
||||
|
||||
public static final String TAG = "RoundedDrawable";
|
||||
public static final int DEFAULT_BORDER_COLOR = Color.BLACK;
|
||||
|
||||
private final RectF mBounds = new RectF();
|
||||
private final RectF mDrawableRect = new RectF();
|
||||
private final RectF mBitmapRect = new RectF();
|
||||
private final Bitmap mBitmap;
|
||||
private final Paint mBitmapPaint;
|
||||
private final int mBitmapWidth;
|
||||
private final int mBitmapHeight;
|
||||
private final RectF mBorderRect = new RectF();
|
||||
private final Paint mBorderPaint;
|
||||
private final Matrix mShaderMatrix = new Matrix();
|
||||
private final RectF mSquareCornersRect = new RectF();
|
||||
|
||||
private Shader.TileMode mTileModeX = Shader.TileMode.CLAMP;
|
||||
private Shader.TileMode mTileModeY = Shader.TileMode.CLAMP;
|
||||
private boolean mRebuildShader = true;
|
||||
|
||||
// [ topLeft, topRight, bottomLeft, bottomRight ]
|
||||
private float mCornerRadius = 0f;
|
||||
private final boolean[] mCornersRounded = new boolean[] { true, true, true, true };
|
||||
|
||||
private boolean mOval = false;
|
||||
private float mBorderWidth = 0;
|
||||
private ColorStateList mBorderColor = ColorStateList.valueOf(DEFAULT_BORDER_COLOR);
|
||||
private ScaleType mScaleType = ScaleType.FIT_CENTER;
|
||||
|
||||
public RoundedDrawable(Bitmap bitmap) {
|
||||
mBitmap = bitmap;
|
||||
|
||||
mBitmapWidth = bitmap.getWidth();
|
||||
mBitmapHeight = bitmap.getHeight();
|
||||
mBitmapRect.set(0, 0, mBitmapWidth, mBitmapHeight);
|
||||
|
||||
mBitmapPaint = new Paint();
|
||||
mBitmapPaint.setStyle(Paint.Style.FILL);
|
||||
mBitmapPaint.setAntiAlias(true);
|
||||
|
||||
mBorderPaint = new Paint();
|
||||
mBorderPaint.setStyle(Paint.Style.STROKE);
|
||||
mBorderPaint.setAntiAlias(true);
|
||||
mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR));
|
||||
mBorderPaint.setStrokeWidth(mBorderWidth);
|
||||
}
|
||||
|
||||
public static RoundedDrawable fromBitmap(Bitmap bitmap) {
|
||||
if (bitmap != null) {
|
||||
return new RoundedDrawable(bitmap);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Drawable fromDrawable(Drawable drawable) {
|
||||
if (drawable != null) {
|
||||
if (drawable instanceof RoundedDrawable) {
|
||||
// just return if it's already a RoundedDrawable
|
||||
return drawable;
|
||||
} else if (drawable instanceof LayerDrawable) {
|
||||
LayerDrawable ld = (LayerDrawable) drawable;
|
||||
int num = ld.getNumberOfLayers();
|
||||
|
||||
// loop through layers to and change to RoundedDrawables if possible
|
||||
for (int i = 0; i < num; i++) {
|
||||
Drawable d = ld.getDrawable(i);
|
||||
ld.setDrawableByLayerId(ld.getId(i), fromDrawable(d));
|
||||
}
|
||||
return ld;
|
||||
}
|
||||
|
||||
// try to get a bitmap from the drawable and
|
||||
Bitmap bm = drawableToBitmap(drawable);
|
||||
if (bm != null) {
|
||||
return new RoundedDrawable(bm);
|
||||
}
|
||||
}
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public static Bitmap drawableToBitmap(Drawable drawable) {
|
||||
if (drawable instanceof BitmapDrawable) {
|
||||
return ((BitmapDrawable) drawable).getBitmap();
|
||||
}
|
||||
|
||||
Bitmap bitmap;
|
||||
int width = Math.max(drawable.getIntrinsicWidth(), 2);
|
||||
int height = Math.max(drawable.getIntrinsicHeight(), 2);
|
||||
try {
|
||||
bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.w(TAG, "Failed to create bitmap from drawable!");
|
||||
bitmap = null;
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public Bitmap getSourceBitmap() {
|
||||
return mBitmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateful() {
|
||||
return mBorderColor.isStateful();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onStateChange(int[] state) {
|
||||
int newColor = mBorderColor.getColorForState(state, 0);
|
||||
if (mBorderPaint.getColor() != newColor) {
|
||||
mBorderPaint.setColor(newColor);
|
||||
return true;
|
||||
} else {
|
||||
return super.onStateChange(state);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateShaderMatrix() {
|
||||
float scale;
|
||||
float dx;
|
||||
float dy;
|
||||
|
||||
switch (mScaleType) {
|
||||
case CENTER:
|
||||
mBorderRect.set(mBounds);
|
||||
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
|
||||
|
||||
mShaderMatrix.reset();
|
||||
mShaderMatrix.setTranslate((int) ((mBorderRect.width() - mBitmapWidth) * 0.5f + 0.5f),
|
||||
(int) ((mBorderRect.height() - mBitmapHeight) * 0.5f + 0.5f));
|
||||
break;
|
||||
|
||||
case CENTER_CROP:
|
||||
mBorderRect.set(mBounds);
|
||||
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
|
||||
|
||||
mShaderMatrix.reset();
|
||||
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
|
||||
if (mBitmapWidth * mBorderRect.height() > mBorderRect.width() * mBitmapHeight) {
|
||||
scale = mBorderRect.height() / (float) mBitmapHeight;
|
||||
dx = (mBorderRect.width() - mBitmapWidth * scale) * 0.5f;
|
||||
} else {
|
||||
scale = mBorderRect.width() / (float) mBitmapWidth;
|
||||
dy = (mBorderRect.height() - mBitmapHeight * scale) * 0.5f;
|
||||
}
|
||||
|
||||
mShaderMatrix.setScale(scale, scale);
|
||||
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth / 2,
|
||||
(int) (dy + 0.5f) + mBorderWidth / 2);
|
||||
break;
|
||||
|
||||
case CENTER_INSIDE:
|
||||
mShaderMatrix.reset();
|
||||
|
||||
if (mBitmapWidth <= mBounds.width() && mBitmapHeight <= mBounds.height()) {
|
||||
scale = 1.0f;
|
||||
} else {
|
||||
scale = Math.min(mBounds.width() / (float) mBitmapWidth,
|
||||
mBounds.height() / (float) mBitmapHeight);
|
||||
}
|
||||
|
||||
dx = (int) ((mBounds.width() - mBitmapWidth * scale) * 0.5f + 0.5f);
|
||||
dy = (int) ((mBounds.height() - mBitmapHeight * scale) * 0.5f + 0.5f);
|
||||
|
||||
mShaderMatrix.setScale(scale, scale);
|
||||
mShaderMatrix.postTranslate(dx, dy);
|
||||
|
||||
mBorderRect.set(mBitmapRect);
|
||||
mShaderMatrix.mapRect(mBorderRect);
|
||||
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
|
||||
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
|
||||
break;
|
||||
|
||||
default:
|
||||
case FIT_CENTER:
|
||||
mBorderRect.set(mBitmapRect);
|
||||
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.CENTER);
|
||||
mShaderMatrix.mapRect(mBorderRect);
|
||||
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
|
||||
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
|
||||
break;
|
||||
|
||||
case FIT_END:
|
||||
mBorderRect.set(mBitmapRect);
|
||||
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.END);
|
||||
mShaderMatrix.mapRect(mBorderRect);
|
||||
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
|
||||
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
|
||||
break;
|
||||
|
||||
case FIT_START:
|
||||
mBorderRect.set(mBitmapRect);
|
||||
mShaderMatrix.setRectToRect(mBitmapRect, mBounds, Matrix.ScaleToFit.START);
|
||||
mShaderMatrix.mapRect(mBorderRect);
|
||||
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
|
||||
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
|
||||
break;
|
||||
|
||||
case FIT_XY:
|
||||
mBorderRect.set(mBounds);
|
||||
mBorderRect.inset(mBorderWidth / 2, mBorderWidth / 2);
|
||||
mShaderMatrix.reset();
|
||||
mShaderMatrix.setRectToRect(mBitmapRect, mBorderRect, Matrix.ScaleToFit.FILL);
|
||||
break;
|
||||
}
|
||||
|
||||
mDrawableRect.set(mBorderRect);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(@NonNull Rect bounds) {
|
||||
super.onBoundsChange(bounds);
|
||||
|
||||
mBounds.set(bounds);
|
||||
|
||||
updateShaderMatrix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
if (mRebuildShader) {
|
||||
BitmapShader bitmapShader = new BitmapShader(mBitmap, mTileModeX, mTileModeY);
|
||||
if (mTileModeX == Shader.TileMode.CLAMP && mTileModeY == Shader.TileMode.CLAMP) {
|
||||
bitmapShader.setLocalMatrix(mShaderMatrix);
|
||||
}
|
||||
mBitmapPaint.setShader(bitmapShader);
|
||||
mRebuildShader = false;
|
||||
}
|
||||
|
||||
if (mOval) {
|
||||
if (mBorderWidth > 0) {
|
||||
canvas.drawOval(mDrawableRect, mBitmapPaint);
|
||||
canvas.drawOval(mBorderRect, mBorderPaint);
|
||||
} else {
|
||||
canvas.drawOval(mDrawableRect, mBitmapPaint);
|
||||
}
|
||||
} else {
|
||||
if (any(mCornersRounded)) {
|
||||
float radius = mCornerRadius;
|
||||
if (mBorderWidth > 0) {
|
||||
canvas.drawRoundRect(mDrawableRect, radius, radius, mBitmapPaint);
|
||||
canvas.drawRoundRect(mBorderRect, radius, radius, mBorderPaint);
|
||||
redrawBitmapForSquareCorners(canvas);
|
||||
redrawBorderForSquareCorners(canvas);
|
||||
} else {
|
||||
canvas.drawRoundRect(mDrawableRect, radius, radius, mBitmapPaint);
|
||||
redrawBitmapForSquareCorners(canvas);
|
||||
}
|
||||
} else {
|
||||
canvas.drawRect(mDrawableRect, mBitmapPaint);
|
||||
if (mBorderWidth > 0) {
|
||||
canvas.drawRect(mBorderRect, mBorderPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void redrawBitmapForSquareCorners(Canvas canvas) {
|
||||
if (all(mCornersRounded)) {
|
||||
// no square corners
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCornerRadius == 0) {
|
||||
return; // no round corners
|
||||
}
|
||||
|
||||
float left = mDrawableRect.left;
|
||||
float top = mDrawableRect.top;
|
||||
float right = left + mDrawableRect.width();
|
||||
float bottom = top + mDrawableRect.height();
|
||||
float radius = mCornerRadius;
|
||||
|
||||
if (!mCornersRounded[Corner.TOP_LEFT]) {
|
||||
mSquareCornersRect.set(left, top, left + radius, top + radius);
|
||||
canvas.drawRect(mSquareCornersRect, mBitmapPaint);
|
||||
}
|
||||
|
||||
if (!mCornersRounded[Corner.TOP_RIGHT]) {
|
||||
mSquareCornersRect.set(right - radius, top, right, radius);
|
||||
canvas.drawRect(mSquareCornersRect, mBitmapPaint);
|
||||
}
|
||||
|
||||
if (!mCornersRounded[Corner.BOTTOM_RIGHT]) {
|
||||
mSquareCornersRect.set(right - radius, bottom - radius, right, bottom);
|
||||
canvas.drawRect(mSquareCornersRect, mBitmapPaint);
|
||||
}
|
||||
|
||||
if (!mCornersRounded[Corner.BOTTOM_LEFT]) {
|
||||
mSquareCornersRect.set(left, bottom - radius, left + radius, bottom);
|
||||
canvas.drawRect(mSquareCornersRect, mBitmapPaint);
|
||||
}
|
||||
}
|
||||
|
||||
private void redrawBorderForSquareCorners(Canvas canvas) {
|
||||
if (all(mCornersRounded)) {
|
||||
// no square corners
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCornerRadius == 0) {
|
||||
return; // no round corners
|
||||
}
|
||||
|
||||
float left = mDrawableRect.left;
|
||||
float top = mDrawableRect.top;
|
||||
float right = left + mDrawableRect.width();
|
||||
float bottom = top + mDrawableRect.height();
|
||||
float radius = mCornerRadius;
|
||||
float offset = mBorderWidth / 2;
|
||||
|
||||
if (!mCornersRounded[Corner.TOP_LEFT]) {
|
||||
canvas.drawLine(left - offset, top, left + radius, top, mBorderPaint);
|
||||
canvas.drawLine(left, top - offset, left, top + radius, mBorderPaint);
|
||||
}
|
||||
|
||||
if (!mCornersRounded[Corner.TOP_RIGHT]) {
|
||||
canvas.drawLine(right - radius - offset, top, right, top, mBorderPaint);
|
||||
canvas.drawLine(right, top - offset, right, top + radius, mBorderPaint);
|
||||
}
|
||||
|
||||
if (!mCornersRounded[Corner.BOTTOM_RIGHT]) {
|
||||
canvas.drawLine(right - radius - offset, bottom, right + offset, bottom, mBorderPaint);
|
||||
canvas.drawLine(right, bottom - radius, right, bottom, mBorderPaint);
|
||||
}
|
||||
|
||||
if (!mCornersRounded[Corner.BOTTOM_LEFT]) {
|
||||
canvas.drawLine(left - offset, bottom, left + radius, bottom, mBorderPaint);
|
||||
canvas.drawLine(left, bottom - radius, left, bottom, mBorderPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlpha() {
|
||||
return mBitmapPaint.getAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mBitmapPaint.setAlpha(alpha);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorFilter getColorFilter() {
|
||||
return mBitmapPaint.getColorFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
mBitmapPaint.setColorFilter(cf);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDither(boolean dither) {
|
||||
mBitmapPaint.setDither(dither);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilterBitmap(boolean filter) {
|
||||
mBitmapPaint.setFilterBitmap(filter);
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mBitmapWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mBitmapHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the corner radius.
|
||||
*/
|
||||
public float getCornerRadius() {
|
||||
return mCornerRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param corner the specific corner to get radius of.
|
||||
* @return the corner radius of the specified corner.
|
||||
*/
|
||||
public float getCornerRadius(@Corner int corner) {
|
||||
return mCornersRounded[corner] ? mCornerRadius : 0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all corners to the specified radius.
|
||||
*
|
||||
* @param radius the radius.
|
||||
* @return the {@link RoundedDrawable} for chaining.
|
||||
*/
|
||||
public RoundedDrawable setCornerRadius(float radius) {
|
||||
setCornerRadius(radius, radius, radius, radius);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the corner radius of one specific corner.
|
||||
*
|
||||
* @param corner the corner.
|
||||
* @param radius the radius.
|
||||
* @return the {@link RoundedDrawable} for chaining.
|
||||
*/
|
||||
public RoundedDrawable setCornerRadius(@Corner int corner, float radius) {
|
||||
if (radius != 0 && mCornerRadius != 0 && mCornerRadius != radius) {
|
||||
throw new IllegalArgumentException("Multiple nonzero corner radii not yet supported.");
|
||||
}
|
||||
|
||||
if (radius == 0) {
|
||||
if (only(corner, mCornersRounded)) {
|
||||
mCornerRadius = 0;
|
||||
}
|
||||
mCornersRounded[corner] = false;
|
||||
} else {
|
||||
if (mCornerRadius == 0) {
|
||||
mCornerRadius = radius;
|
||||
}
|
||||
mCornersRounded[corner] = true;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the corner radii of all the corners.
|
||||
*
|
||||
* @param topLeft top left corner radius.
|
||||
* @param topRight top right corner radius
|
||||
* @param bottomRight bototm right corner radius.
|
||||
* @param bottomLeft bottom left corner radius.
|
||||
* @return the {@link RoundedDrawable} for chaining.
|
||||
*/
|
||||
public RoundedDrawable setCornerRadius(float topLeft, float topRight, float bottomRight,
|
||||
float bottomLeft) {
|
||||
Set<Float> radiusSet = new HashSet<>(4);
|
||||
radiusSet.add(topLeft);
|
||||
radiusSet.add(topRight);
|
||||
radiusSet.add(bottomRight);
|
||||
radiusSet.add(bottomLeft);
|
||||
|
||||
radiusSet.remove(0f);
|
||||
|
||||
if (radiusSet.size() > 1) {
|
||||
throw new IllegalArgumentException("Multiple nonzero corner radii not yet supported.");
|
||||
}
|
||||
|
||||
if (!radiusSet.isEmpty()) {
|
||||
float radius = radiusSet.iterator().next();
|
||||
if (Float.isInfinite(radius) || Float.isNaN(radius) || radius < 0) {
|
||||
throw new IllegalArgumentException("Invalid radius value: " + radius);
|
||||
}
|
||||
mCornerRadius = radius;
|
||||
} else {
|
||||
mCornerRadius = 0f;
|
||||
}
|
||||
|
||||
mCornersRounded[Corner.TOP_LEFT] = topLeft > 0;
|
||||
mCornersRounded[Corner.TOP_RIGHT] = topRight > 0;
|
||||
mCornersRounded[Corner.BOTTOM_RIGHT] = bottomRight > 0;
|
||||
mCornersRounded[Corner.BOTTOM_LEFT] = bottomLeft > 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float getBorderWidth() {
|
||||
return mBorderWidth;
|
||||
}
|
||||
|
||||
public RoundedDrawable setBorderWidth(float width) {
|
||||
mBorderWidth = width;
|
||||
mBorderPaint.setStrokeWidth(mBorderWidth);
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getBorderColor() {
|
||||
return mBorderColor.getDefaultColor();
|
||||
}
|
||||
|
||||
public RoundedDrawable setBorderColor(@ColorInt int color) {
|
||||
return setBorderColor(ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
public ColorStateList getBorderColors() {
|
||||
return mBorderColor;
|
||||
}
|
||||
|
||||
public RoundedDrawable setBorderColor(ColorStateList colors) {
|
||||
mBorderColor = colors != null ? colors : ColorStateList.valueOf(0);
|
||||
mBorderPaint.setColor(mBorderColor.getColorForState(getState(), DEFAULT_BORDER_COLOR));
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isOval() {
|
||||
return mOval;
|
||||
}
|
||||
|
||||
public RoundedDrawable setOval(boolean oval) {
|
||||
mOval = oval;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScaleType getScaleType() {
|
||||
return mScaleType;
|
||||
}
|
||||
|
||||
public RoundedDrawable setScaleType(ScaleType scaleType) {
|
||||
if (scaleType == null) {
|
||||
scaleType = ScaleType.FIT_CENTER;
|
||||
}
|
||||
if (mScaleType != scaleType) {
|
||||
mScaleType = scaleType;
|
||||
updateShaderMatrix();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Shader.TileMode getTileModeX() {
|
||||
return mTileModeX;
|
||||
}
|
||||
|
||||
public RoundedDrawable setTileModeX(Shader.TileMode tileModeX) {
|
||||
if (mTileModeX != tileModeX) {
|
||||
mTileModeX = tileModeX;
|
||||
mRebuildShader = true;
|
||||
invalidateSelf();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Shader.TileMode getTileModeY() {
|
||||
return mTileModeY;
|
||||
}
|
||||
|
||||
public RoundedDrawable setTileModeY(Shader.TileMode tileModeY) {
|
||||
if (mTileModeY != tileModeY) {
|
||||
mTileModeY = tileModeY;
|
||||
mRebuildShader = true;
|
||||
invalidateSelf();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private static boolean only(int index, boolean[] booleans) {
|
||||
for (int i = 0, len = booleans.length; i < len; i++) {
|
||||
if (booleans[i] != (i == index)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean any(boolean[] booleans) {
|
||||
for (boolean b : booleans) {
|
||||
if (b) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean all(boolean[] booleans) {
|
||||
for (boolean b : booleans) {
|
||||
if (b) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Bitmap toBitmap() {
|
||||
return drawableToBitmap(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Vincent Mi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.mogo.eagle.core.function.hmi.ui.notice.roundimage;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.net.Uri;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.DimenRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
|
||||
import com.mogo.eagle.core.function.hmi.R;
|
||||
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public class RoundedImageView extends AppCompatImageView {
|
||||
|
||||
// Constants for tile mode attributes
|
||||
private static final int TILE_MODE_UNDEFINED = -2;
|
||||
private static final int TILE_MODE_CLAMP = 0;
|
||||
private static final int TILE_MODE_REPEAT = 1;
|
||||
private static final int TILE_MODE_MIRROR = 2;
|
||||
|
||||
public static final String TAG = "RoundedImageView";
|
||||
public static final float DEFAULT_RADIUS = 0f;
|
||||
public static final float DEFAULT_BORDER_WIDTH = 0f;
|
||||
public static final Shader.TileMode DEFAULT_TILE_MODE = Shader.TileMode.CLAMP;
|
||||
private static final ScaleType[] SCALE_TYPES = {
|
||||
ScaleType.MATRIX,
|
||||
ScaleType.FIT_XY,
|
||||
ScaleType.FIT_START,
|
||||
ScaleType.FIT_CENTER,
|
||||
ScaleType.FIT_END,
|
||||
ScaleType.CENTER,
|
||||
ScaleType.CENTER_CROP,
|
||||
ScaleType.CENTER_INSIDE
|
||||
};
|
||||
|
||||
private final float[] mCornerRadii =
|
||||
new float[] { DEFAULT_RADIUS, DEFAULT_RADIUS, DEFAULT_RADIUS, DEFAULT_RADIUS };
|
||||
|
||||
private Drawable mBackgroundDrawable;
|
||||
private ColorStateList mBorderColor =
|
||||
ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
|
||||
private float mBorderWidth = DEFAULT_BORDER_WIDTH;
|
||||
private ColorFilter mColorFilter = null;
|
||||
private boolean mColorMod = false;
|
||||
private Drawable mDrawable;
|
||||
private boolean mHasColorFilter = false;
|
||||
private boolean mIsOval = false;
|
||||
private boolean mMutateBackground = false;
|
||||
private int mResource;
|
||||
private int mBackgroundResource;
|
||||
private ScaleType mScaleType;
|
||||
private Shader.TileMode mTileModeX = DEFAULT_TILE_MODE;
|
||||
private Shader.TileMode mTileModeY = DEFAULT_TILE_MODE;
|
||||
|
||||
public RoundedImageView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public RoundedImageView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageView, defStyle, 0);
|
||||
|
||||
int index = a.getInt(R.styleable.RoundedImageView_android_scaleType, -1);
|
||||
if (index >= 0) {
|
||||
setScaleType(SCALE_TYPES[index]);
|
||||
} else {
|
||||
// default scaletype to FIT_CENTER
|
||||
setScaleType(ScaleType.FIT_CENTER);
|
||||
}
|
||||
|
||||
float cornerRadiusOverride =
|
||||
a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius, -1);
|
||||
|
||||
mCornerRadii[Corner.TOP_LEFT] =
|
||||
a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_top_left, -1);
|
||||
mCornerRadii[Corner.TOP_RIGHT] =
|
||||
a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_top_right, -1);
|
||||
mCornerRadii[Corner.BOTTOM_RIGHT] =
|
||||
a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_bottom_right, -1);
|
||||
mCornerRadii[Corner.BOTTOM_LEFT] =
|
||||
a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_bottom_left, -1);
|
||||
|
||||
boolean any = false;
|
||||
for (int i = 0, len = mCornerRadii.length; i < len; i++) {
|
||||
if (mCornerRadii[i] < 0) {
|
||||
mCornerRadii[i] = 0f;
|
||||
} else {
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!any) {
|
||||
if (cornerRadiusOverride < 0) {
|
||||
cornerRadiusOverride = DEFAULT_RADIUS;
|
||||
}
|
||||
for (int i = 0, len = mCornerRadii.length; i < len; i++) {
|
||||
mCornerRadii[i] = cornerRadiusOverride;
|
||||
}
|
||||
}
|
||||
|
||||
mBorderWidth = a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_border_width, -1);
|
||||
if (mBorderWidth < 0) {
|
||||
mBorderWidth = DEFAULT_BORDER_WIDTH;
|
||||
}
|
||||
|
||||
mBorderColor = a.getColorStateList(R.styleable.RoundedImageView_riv_border_color);
|
||||
if (mBorderColor == null) {
|
||||
mBorderColor = ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
|
||||
}
|
||||
|
||||
mMutateBackground = a.getBoolean(R.styleable.RoundedImageView_riv_mutate_background, false);
|
||||
mIsOval = a.getBoolean(R.styleable.RoundedImageView_riv_oval, false);
|
||||
|
||||
final int tileMode = a.getInt(R.styleable.RoundedImageView_riv_tile_Mode, TILE_MODE_UNDEFINED);
|
||||
if (tileMode != TILE_MODE_UNDEFINED) {
|
||||
setTileModeX(parseTileMode(tileMode));
|
||||
setTileModeY(parseTileMode(tileMode));
|
||||
}
|
||||
|
||||
final int tileModeX =
|
||||
a.getInt(R.styleable.RoundedImageView_riv_tile_Mode_x, TILE_MODE_UNDEFINED);
|
||||
if (tileModeX != TILE_MODE_UNDEFINED) {
|
||||
setTileModeX(parseTileMode(tileModeX));
|
||||
}
|
||||
|
||||
final int tileModeY =
|
||||
a.getInt(R.styleable.RoundedImageView_riv_tile_Mode_y, TILE_MODE_UNDEFINED);
|
||||
if (tileModeY != TILE_MODE_UNDEFINED) {
|
||||
setTileModeY(parseTileMode(tileModeY));
|
||||
}
|
||||
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(true);
|
||||
|
||||
if (mMutateBackground) {
|
||||
// when setBackground() is called by View constructor, mMutateBackground is not loaded from the attribute,
|
||||
// so it's false by default, what doesn't allow to create the RoundedDrawable. At this point, after load
|
||||
// mMutateBackground and updated BackgroundDrawable to RoundedDrawable, the View's background drawable needs to
|
||||
// be changed to this new drawable.
|
||||
//noinspection deprecation
|
||||
super.setBackgroundDrawable(mBackgroundDrawable);
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
private static Shader.TileMode parseTileMode(int tileMode) {
|
||||
switch (tileMode) {
|
||||
case TILE_MODE_CLAMP:
|
||||
return Shader.TileMode.CLAMP;
|
||||
case TILE_MODE_REPEAT:
|
||||
return Shader.TileMode.REPEAT;
|
||||
case TILE_MODE_MIRROR:
|
||||
return Shader.TileMode.MIRROR;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaleType getScaleType() {
|
||||
return mScaleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleType(ScaleType scaleType) {
|
||||
assert scaleType != null;
|
||||
|
||||
if (mScaleType != scaleType) {
|
||||
mScaleType = scaleType;
|
||||
|
||||
switch (scaleType) {
|
||||
case CENTER:
|
||||
case CENTER_CROP:
|
||||
case CENTER_INSIDE:
|
||||
case FIT_CENTER:
|
||||
case FIT_START:
|
||||
case FIT_END:
|
||||
case FIT_XY:
|
||||
super.setScaleType(ScaleType.FIT_XY);
|
||||
break;
|
||||
default:
|
||||
super.setScaleType(scaleType);
|
||||
break;
|
||||
}
|
||||
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(false);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageDrawable(Drawable drawable) {
|
||||
mResource = 0;
|
||||
mDrawable = RoundedDrawable.fromDrawable(drawable);
|
||||
updateDrawableAttrs();
|
||||
super.setImageDrawable(mDrawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageBitmap(Bitmap bm) {
|
||||
mResource = 0;
|
||||
mDrawable = RoundedDrawable.fromBitmap(bm);
|
||||
updateDrawableAttrs();
|
||||
super.setImageDrawable(mDrawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageResource(@DrawableRes int resId) {
|
||||
if (mResource != resId) {
|
||||
mResource = resId;
|
||||
mDrawable = resolveResource();
|
||||
updateDrawableAttrs();
|
||||
super.setImageDrawable(mDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setImageURI(Uri uri) {
|
||||
super.setImageURI(uri);
|
||||
setImageDrawable(getDrawable());
|
||||
}
|
||||
|
||||
private Drawable resolveResource() {
|
||||
Resources rsrc = getResources();
|
||||
if (rsrc == null) { return null; }
|
||||
|
||||
Drawable d = null;
|
||||
|
||||
if (mResource != 0) {
|
||||
try {
|
||||
d = rsrc.getDrawable(mResource);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unable to find resource: " + mResource, e);
|
||||
// Don't try again.
|
||||
mResource = 0;
|
||||
}
|
||||
}
|
||||
return RoundedDrawable.fromDrawable(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Drawable background) {
|
||||
setBackgroundDrawable(background);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundResource(@DrawableRes int resId) {
|
||||
if (mBackgroundResource != resId) {
|
||||
mBackgroundResource = resId;
|
||||
mBackgroundDrawable = resolveBackgroundResource();
|
||||
setBackgroundDrawable(mBackgroundDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundColor(int color) {
|
||||
mBackgroundDrawable = new ColorDrawable(color);
|
||||
setBackgroundDrawable(mBackgroundDrawable);
|
||||
}
|
||||
|
||||
private Drawable resolveBackgroundResource() {
|
||||
Resources rsrc = getResources();
|
||||
if (rsrc == null) { return null; }
|
||||
|
||||
Drawable d = null;
|
||||
|
||||
if (mBackgroundResource != 0) {
|
||||
try {
|
||||
d = rsrc.getDrawable(mBackgroundResource);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unable to find resource: " + mBackgroundResource, e);
|
||||
// Don't try again.
|
||||
mBackgroundResource = 0;
|
||||
}
|
||||
}
|
||||
return RoundedDrawable.fromDrawable(d);
|
||||
}
|
||||
|
||||
private void updateDrawableAttrs() {
|
||||
updateAttrs(mDrawable, mScaleType);
|
||||
}
|
||||
|
||||
private void updateBackgroundDrawableAttrs(boolean convert) {
|
||||
if (mMutateBackground) {
|
||||
if (convert) {
|
||||
mBackgroundDrawable = RoundedDrawable.fromDrawable(mBackgroundDrawable);
|
||||
}
|
||||
updateAttrs(mBackgroundDrawable, ScaleType.FIT_XY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setColorFilter(ColorFilter cf) {
|
||||
if (mColorFilter != cf) {
|
||||
mColorFilter = cf;
|
||||
mHasColorFilter = true;
|
||||
mColorMod = true;
|
||||
applyColorMod();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyColorMod() {
|
||||
// Only mutate and apply when modifications have occurred. This should
|
||||
// not reset the mColorMod flag, since these filters need to be
|
||||
// re-applied if the Drawable is changed.
|
||||
if (mDrawable != null && mColorMod) {
|
||||
mDrawable = mDrawable.mutate();
|
||||
if (mHasColorFilter) {
|
||||
mDrawable.setColorFilter(mColorFilter);
|
||||
}
|
||||
//mDrawable.setXfermode(mXfermode);
|
||||
//mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAttrs(Drawable drawable, ScaleType scaleType) {
|
||||
if (drawable == null) { return; }
|
||||
|
||||
if (drawable instanceof RoundedDrawable) {
|
||||
((RoundedDrawable) drawable)
|
||||
.setScaleType(scaleType)
|
||||
.setBorderWidth(mBorderWidth)
|
||||
.setBorderColor(mBorderColor)
|
||||
.setOval(mIsOval)
|
||||
.setTileModeX(mTileModeX)
|
||||
.setTileModeY(mTileModeY);
|
||||
|
||||
if (mCornerRadii != null) {
|
||||
((RoundedDrawable) drawable).setCornerRadius(
|
||||
mCornerRadii[Corner.TOP_LEFT],
|
||||
mCornerRadii[Corner.TOP_RIGHT],
|
||||
mCornerRadii[Corner.BOTTOM_RIGHT],
|
||||
mCornerRadii[Corner.BOTTOM_LEFT]);
|
||||
}
|
||||
|
||||
applyColorMod();
|
||||
} else if (drawable instanceof LayerDrawable) {
|
||||
// loop through layers to and set drawable attrs
|
||||
LayerDrawable ld = ((LayerDrawable) drawable);
|
||||
for (int i = 0, layers = ld.getNumberOfLayers(); i < layers; i++) {
|
||||
updateAttrs(ld.getDrawable(i), scaleType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setBackgroundDrawable(Drawable background) {
|
||||
mBackgroundDrawable = background;
|
||||
updateBackgroundDrawableAttrs(true);
|
||||
//noinspection deprecation
|
||||
super.setBackgroundDrawable(mBackgroundDrawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the largest corner radius.
|
||||
*/
|
||||
public float getCornerRadius() {
|
||||
return getMaxCornerRadius();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the largest corner radius.
|
||||
*/
|
||||
public float getMaxCornerRadius() {
|
||||
float maxRadius = 0;
|
||||
for (float r : mCornerRadii) {
|
||||
maxRadius = Math.max(r, maxRadius);
|
||||
}
|
||||
return maxRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the corner radius of a specified corner.
|
||||
*
|
||||
* @param corner the corner.
|
||||
* @return the radius.
|
||||
*/
|
||||
public float getCornerRadius(@Corner int corner) {
|
||||
return mCornerRadii[corner];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all the corner radii from a dimension resource id.
|
||||
*
|
||||
* @param resId dimension resource id of radii.
|
||||
*/
|
||||
public void setCornerRadiusDimen(@DimenRes int resId) {
|
||||
float radius = getResources().getDimension(resId);
|
||||
setCornerRadius(radius, radius, radius, radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the corner radius of a specific corner from a dimension resource id.
|
||||
*
|
||||
* @param corner the corner to set.
|
||||
* @param resId the dimension resource id of the corner radius.
|
||||
*/
|
||||
public void setCornerRadiusDimen(@Corner int corner, @DimenRes int resId) {
|
||||
setCornerRadius(corner, getResources().getDimensionPixelSize(resId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the corner radii of all corners in px.
|
||||
*
|
||||
* @param radius the radius to set.
|
||||
*/
|
||||
public void setCornerRadius(float radius) {
|
||||
setCornerRadius(radius, radius, radius, radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the corner radius of a specific corner in px.
|
||||
*
|
||||
* @param corner the corner to set.
|
||||
* @param radius the corner radius to set in px.
|
||||
*/
|
||||
public void setCornerRadius(@Corner int corner, float radius) {
|
||||
if (mCornerRadii[corner] == radius) {
|
||||
return;
|
||||
}
|
||||
mCornerRadii[corner] = radius;
|
||||
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the corner radii of each corner individually. Currently only one unique nonzero value is
|
||||
* supported.
|
||||
*
|
||||
* @param topLeft radius of the top left corner in px.
|
||||
* @param topRight radius of the top right corner in px.
|
||||
* @param bottomRight radius of the bottom right corner in px.
|
||||
* @param bottomLeft radius of the bottom left corner in px.
|
||||
*/
|
||||
public void setCornerRadius(float topLeft, float topRight, float bottomLeft, float bottomRight) {
|
||||
if (mCornerRadii[Corner.TOP_LEFT] == topLeft
|
||||
&& mCornerRadii[Corner.TOP_RIGHT] == topRight
|
||||
&& mCornerRadii[Corner.BOTTOM_RIGHT] == bottomRight
|
||||
&& mCornerRadii[Corner.BOTTOM_LEFT] == bottomLeft) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCornerRadii[Corner.TOP_LEFT] = topLeft;
|
||||
mCornerRadii[Corner.TOP_RIGHT] = topRight;
|
||||
mCornerRadii[Corner.BOTTOM_LEFT] = bottomLeft;
|
||||
mCornerRadii[Corner.BOTTOM_RIGHT] = bottomRight;
|
||||
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getBorderWidth() {
|
||||
return mBorderWidth;
|
||||
}
|
||||
|
||||
public void setBorderWidth(@DimenRes int resId) {
|
||||
setBorderWidth(getResources().getDimension(resId));
|
||||
}
|
||||
|
||||
public void setBorderWidth(float width) {
|
||||
if (mBorderWidth == width) { return; }
|
||||
|
||||
mBorderWidth = width;
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
public int getBorderColor() {
|
||||
return mBorderColor.getDefaultColor();
|
||||
}
|
||||
|
||||
public void setBorderColor(@ColorInt int color) {
|
||||
setBorderColor(ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
public ColorStateList getBorderColors() {
|
||||
return mBorderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(ColorStateList colors) {
|
||||
if (mBorderColor.equals(colors)) { return; }
|
||||
|
||||
mBorderColor =
|
||||
(colors != null) ? colors : ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(false);
|
||||
if (mBorderWidth > 0) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOval() {
|
||||
return mIsOval;
|
||||
}
|
||||
|
||||
public void setOval(boolean oval) {
|
||||
mIsOval = oval;
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public Shader.TileMode getTileModeX() {
|
||||
return mTileModeX;
|
||||
}
|
||||
|
||||
public void setTileModeX(Shader.TileMode tileModeX) {
|
||||
if (this.mTileModeX == tileModeX) { return; }
|
||||
|
||||
this.mTileModeX = tileModeX;
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public Shader.TileMode getTileModeY() {
|
||||
return mTileModeY;
|
||||
}
|
||||
|
||||
public void setTileModeY(Shader.TileMode tileModeY) {
|
||||
if (this.mTileModeY == tileModeY) { return; }
|
||||
|
||||
this.mTileModeY = tileModeY;
|
||||
updateDrawableAttrs();
|
||||
updateBackgroundDrawableAttrs(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public boolean mutatesBackground() {
|
||||
return mMutateBackground;
|
||||
}
|
||||
|
||||
public void mutateBackground(boolean mutate) {
|
||||
if (mMutateBackground == mutate) { return; }
|
||||
|
||||
mMutateBackground = mutate;
|
||||
updateBackgroundDrawableAttrs(true);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.mogo.service.IMogoServiceApis
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2020/6/28
|
||||
*
|
||||
* 描述
|
||||
*/
|
||||
private var apis: IMogoServiceApis? = null
|
||||
|
||||
fun getApis(context: Context): IMogoServiceApis {
|
||||
if (apis == null) {
|
||||
apis = ARouter.getInstance().build(com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_SERVICE_APIS).navigation(context) as IMogoServiceApis;
|
||||
}
|
||||
return apis!!
|
||||
}
|
||||
|
||||
fun View.gone() {
|
||||
if (this.visibility != View.GONE) {
|
||||
this.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
fun View.visible() {
|
||||
if (this.visibility != View.VISIBLE) {
|
||||
this.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
fun View.invisible() {
|
||||
if (this.visibility != View.INVISIBLE) {
|
||||
this.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,9 @@ class MoGoWarningProvider : IMoGoWaringProvider {
|
||||
}
|
||||
|
||||
override fun showNoticeNormalData(normalData: NoticeNormalData?) {
|
||||
TODO("Not yet implemented")
|
||||
if (normalData != null) {
|
||||
mMoGoHmiFragment?.showNoticeNormal(normalData)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
|
After Width: | Height: | Size: 434 B |
|
After Width: | Height: | Size: 589 B |
|
After Width: | Height: | Size: 574 B |
|
After Width: | Height: | Size: 434 B |
|
After Width: | Height: | Size: 581 B |
|
After Width: | Height: | Size: 574 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,11 @@
|
||||
<?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="#80000000"
|
||||
android:startColor="#80000000"
|
||||
android:type="linear" />
|
||||
<corners android:radius="@dimen/module_push_ui_bkg_corner" />
|
||||
</shape>
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?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:layout_marginTop="@dimen/module_push_ui_margin_top"
|
||||
android:background="@drawable/notice_item_background">
|
||||
|
||||
<com.mogo.eagle.core.function.hmi.ui.notice.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:scaleType="fitXY"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
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"
|
||||
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:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/module_push_image"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_goneMarginTop="@dimen/module_push_ui_app_icon_goneTopMargin">
|
||||
|
||||
<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:maxLength="25"
|
||||
android:singleLine="true"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/module_push_ui_title_textSize"
|
||||
app:layout_constrainedWidth="true"
|
||||
tools:text="官方公告" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_push_content"
|
||||
android:layout_width="@dimen/module_push_ui_content_width"
|
||||
android:layout_height="@dimen/module_push_ui_content_height"
|
||||
android:ellipsize="end"
|
||||
android:layout_marginTop="@dimen/module_push_ui_content_topMargin"
|
||||
android:gravity="top|left"
|
||||
android:maxLines="2"
|
||||
android:text="这是测试数据,当前测试数据是为了查看换行的显示效果,如果最多3行呢,怎么显示的呢"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="@dimen/module_push_ui_title_text_size" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<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/dp_100"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/module_push_app_icon_title"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<!-- android:background="@color/module_push_item_line_color"-->
|
||||
|
||||
<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/motice_push_check"
|
||||
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" />
|
||||
<!-- android:textColor="@color/module_push_check_color"-->
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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"
|
||||
android:text="官方公告"
|
||||
android:textStyle="bold"
|
||||
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>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="RoundedImageView">
|
||||
<attr name="riv_corner_radius" format="dimension" />
|
||||
<attr name="riv_corner_radius_top_left" format="dimension" />
|
||||
<attr name="riv_corner_radius_top_right" format="dimension" />
|
||||
<attr name="riv_corner_radius_bottom_left" format="dimension" />
|
||||
<attr name="riv_corner_radius_bottom_right" format="dimension" />
|
||||
<attr name="riv_border_width" format="dimension" />
|
||||
<attr name="riv_border_color" format="color" />
|
||||
<attr name="riv_mutate_background" format="boolean" />
|
||||
<attr name="riv_oval" format="boolean" />
|
||||
<attr name="android:scaleType" />
|
||||
<attr name="riv_tile_Mode">
|
||||
<enum name="clamp" value="0" />
|
||||
<enum name="repeat" value="1" />
|
||||
<enum name="mirror" value="2" />
|
||||
</attr>
|
||||
<attr name="riv_tile_Mode_x">
|
||||
<enum name="clamp" value="0" />
|
||||
<enum name="repeat" value="1" />
|
||||
<enum name="mirror" value="2" />
|
||||
</attr>
|
||||
<attr name="riv_tile_Mode_y">
|
||||
<enum name="clamp" value="0" />
|
||||
<enum name="repeat" value="1" />
|
||||
<enum name="mirror" value="2" />
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
@@ -30,4 +30,131 @@
|
||||
<dimen name="dp_588">588px</dimen>
|
||||
<dimen name="dp_1066">1066px</dimen>
|
||||
|
||||
<!--old-->
|
||||
<dimen name="module_push_margin_top">16px</dimen>
|
||||
<dimen name="module_push_size">352px</dimen>
|
||||
<dimen name="module_push_margin_start">32px</dimen>
|
||||
<dimen name="module_push_app_icon_size">32px</dimen>
|
||||
<dimen name="module_push_app_icon_margin_start">16.5px</dimen>
|
||||
<dimen name="module_push_title_margin_start">12px</dimen>
|
||||
<dimen name="module_push_title_margin_top">20px</dimen>
|
||||
<dimen name="module_push_title_text_size">18px</dimen>
|
||||
<dimen name="module_push_title_mix_width">210px</dimen>
|
||||
<dimen name="module_push_timer_margin_end">13px</dimen>
|
||||
<dimen name="module_push_timer_text_size">15px</dimen>
|
||||
<dimen name="module_push_timer_margin_top">18px</dimen>
|
||||
<dimen name="module_push_image_width">320px</dimen>
|
||||
<dimen name="module_push_image_height">180px</dimen>
|
||||
<dimen name="module_push_image_margin_top">16px</dimen>
|
||||
<dimen name="module_push_content_only_width">320px</dimen>
|
||||
<dimen name="module_push_content_only_height">160px</dimen>
|
||||
<dimen name="module_push_content_only_line_space">9px</dimen>
|
||||
<dimen name="module_push_content_only_padding">20px</dimen>
|
||||
<dimen name="module_push_button_width">0px</dimen>
|
||||
<dimen name="module_push_button_height">48px</dimen>
|
||||
<dimen name="module_push_button_margin_top">10px</dimen>
|
||||
<dimen name="module_push_button_margin_bottom">14px</dimen>
|
||||
<dimen name="module_push_activity_title_margin_top">50px</dimen>
|
||||
<dimen name="module_push_activity_title_text_size">20px</dimen>
|
||||
<dimen name="module_push_activity_close_margin_top">20px</dimen>
|
||||
<dimen name="module_push_activity_close_margin_end">90px</dimen>
|
||||
<dimen name="module_push_activity_close_padding">5px</dimen>
|
||||
<dimen name="module_push_activity_recycler_view_margin_top">84px</dimen>
|
||||
<dimen name="module_push_activity_not_data_text_size">38px</dimen>
|
||||
<dimen name="module_push_activity_clear_margin_bottom">36px</dimen>
|
||||
<dimen name="module_push_message_item_height">100px</dimen>
|
||||
<dimen name="module_push_message_app_icon_size">64px</dimen>
|
||||
<dimen name="module_push_message_margin_start">24px</dimen>
|
||||
<dimen name="module_push_item_title_margin_top">16px</dimen>
|
||||
<dimen name="module_push_item_title_gone_margin_bottom">44px</dimen>
|
||||
<dimen name="module_push_item_title_margin_bottom">2px</dimen>
|
||||
<dimen name="module_push_item_content_margin_end">20px</dimen>
|
||||
<dimen name="module_push_item_content_margin_bottom">27px</dimen>
|
||||
<dimen name="module_push_item_content_text_size">16px</dimen>
|
||||
<dimen name="module_push_message_item_image_size">64px</dimen>
|
||||
<dimen name="module_push_message_item_image_margin_end">8px</dimen>
|
||||
<dimen name="module_push_massage_time_text_size">16px</dimen>
|
||||
|
||||
<dimen name="module_push_image_margin_bottom">22px</dimen>
|
||||
<dimen name="module_push_button_radius">27px</dimen>
|
||||
<dimen name="module_push_timer_inner_radius">14px</dimen>
|
||||
<dimen name="module_push_timer_thickness">1.5px</dimen>
|
||||
<dimen name="module_push_clear_bg_radius">24px</dimen>
|
||||
<dimen name="module_push_image_radius">10px</dimen>
|
||||
<dimen name="module_push_item_image_radius">8px</dimen>
|
||||
<dimen name="module_push_item_content_width">560px</dimen>
|
||||
<dimen name="module_push_ui_height">194px</dimen>
|
||||
<dimen name="module_push_ui_image_width">266px</dimen>
|
||||
<dimen name="module_push_ui_image_height">178px</dimen>
|
||||
<dimen name="module_push_ui_image_marLeft">8px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin">12px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin">16px</dimen>
|
||||
<dimen name="module_push_ui_content_topMargin">6px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_goneTopMargin">19px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_size">30px</dimen>
|
||||
<dimen name="module_push_ui_title_textSize">16px</dimen>
|
||||
<dimen name="module_push_ui_decrease_timer_corner">8px</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginTop">17px</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginEnd">19px</dimen>
|
||||
<dimen name="module_push_ui_timer_textSize">16px</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_padding">11px</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop">6px</dimen>
|
||||
<dimen name="module_push_ui_title_text_size">18px</dimen>
|
||||
<dimen name="module_push_ui_button_radius">10px</dimen>
|
||||
<dimen name="module_push_ui_bkg_corner">17px</dimen>
|
||||
<dimen name="module_push_button_right_marLeft">10px</dimen>
|
||||
<dimen name="module_push_ui_image_corner">8px</dimen>
|
||||
<dimen name="module_push_button_maxWidth">242px</dimen>
|
||||
<dimen name="module_push_ui_height_vertical">270px</dimen>
|
||||
<dimen name="module_push_ui_width_vertical">374px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin_vertical">24px</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin_vertical">19px</dimen>
|
||||
<dimen name="module_push_image_marginTop_vertical">8px</dimen>
|
||||
<dimen name="module_push_ui_image_width_vertical">328px</dimen>
|
||||
<dimen name="module_push_ui_image_height_vertical">164px</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop_vertical">15px</dimen>
|
||||
<dimen name="module_push_image_qr_size_vertical">150px</dimen>
|
||||
<dimen name="module_push_window_x">20px</dimen>
|
||||
<dimen name="module_push_window_y">0px</dimen>
|
||||
<dimen name="module_push_item_minHeight_vertical">310px</dimen>
|
||||
<dimen name="module_push_item_maxHeight_vertical">350px</dimen>
|
||||
<dimen name="module_push_content_paddingBottom_vertical">60px</dimen>
|
||||
<dimen name="module_push_panel_marginTop">2px</dimen>
|
||||
<dimen name="module_push_panel_marginBottom">2px</dimen>
|
||||
<dimen name="module_push_panel_marginRight">8px</dimen>
|
||||
<dimen name="module_push_panel_paddingLeft">28px</dimen>
|
||||
<dimen name="module_push_panel_paddingBottom">16px</dimen>
|
||||
<dimen name="module_push_panel_corner">16px</dimen>
|
||||
<dimen name="module_push_panel_item_corner">12px</dimen>
|
||||
<dimen name="module_push_item_time_textSize">5px</dimen>
|
||||
<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">120px</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>
|
||||
@@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">mogo-module-push</string>
|
||||
<string name="motice_push_check">查看</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<resources>
|
||||
|
||||
<style name="ModulePushMessageTheme" parent="Theme.AppCompat.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
|
||||
<item name="android:windowBackground">@drawable/module_push_message_background</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -3,8 +3,13 @@ package com.mogo.eagle.core.function.notice;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalData;
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
|
||||
import com.mogo.eagle.core.function.notice.receiver.NoticeMessageListener;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.service.cloud.socket.IMogoOnMessageListener;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
import com.mogo.utils.network.utils.GsonUtil;
|
||||
|
||||
/**
|
||||
* @author Jing
|
||||
@@ -32,13 +37,45 @@ class NoticeSocketManager {
|
||||
mNoticeMessageListener = new NoticeMessageListener();
|
||||
MogoApisHandler.getInstance().getApis().getSocketManagerApi(context).
|
||||
registerOnMessageListener(301001, mNoticeMessageListener);
|
||||
MogoApisHandler.getInstance().getApis().getSocketManagerApi(context).
|
||||
registerOnMessageListener(100, mNormalNoticeListener);
|
||||
}
|
||||
|
||||
public void unRegisterSocketMessageListener() {
|
||||
if (mNoticeMessageListener != null) {
|
||||
MogoApisHandler.getInstance().getApis().getSocketManagerApi(mContext).
|
||||
unregisterOnMessageListener(301001, mNoticeMessageListener);
|
||||
MogoApisHandler.getInstance().getApis().getSocketManagerApi(mContext).
|
||||
unregisterOnMessageListener(100, mNormalNoticeListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通云公告
|
||||
*/
|
||||
private IMogoOnMessageListener<NoticeNormalData> mNormalNoticeListener = new IMogoOnMessageListener< NoticeNormalData >() {
|
||||
@Override
|
||||
public Class<NoticeNormalData> target() {
|
||||
return NoticeNormalData.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMsgReceived(NoticeNormalData obj) {
|
||||
Logger.i("liyz", "100-- 普通公告数据:" + GsonUtil.jsonFromObject(obj));
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO 展示弹框
|
||||
CallerHmiManager.INSTANCE.showNormalBanner(obj);
|
||||
|
||||
// NoticePushData data = new NoticePushData();
|
||||
// data.setImageUrl(obj.getImageUrl());
|
||||
// data.setContent(obj.getContent());
|
||||
// data.setInfoId(obj.getDbId());
|
||||
// CallerHmiManager.INSTANCE.showTrafficBanner(data);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -62,37 +62,37 @@ class PushRepository(mContext: Context) {
|
||||
}
|
||||
|
||||
init {
|
||||
// 注册push通道监听 type 100时为push消息
|
||||
getApis(mContext).getSocketManagerApi(mContext)
|
||||
.registerOnMessageListener(Config.PUSH_TYPE, object : IMogoOnMessageListener<PushBean> {
|
||||
override fun target(): Class<PushBean> {
|
||||
return PushBean::class.java
|
||||
}
|
||||
|
||||
override fun onMsgReceived(bean: PushBean?) {
|
||||
Log.d("PushRepository", "pushBean = $bean")
|
||||
if (bean != null) {
|
||||
AnalyticsUtils.track(Config.NEWS_ARRIVE, "title", bean.title)
|
||||
if (bean.mainSchema.isBlank()) {
|
||||
bean.mainSchema = ""
|
||||
}
|
||||
if (bean.imageUrl.isBlank()) {
|
||||
bean.imageUrl = ""
|
||||
}
|
||||
if (bean.appIcon.isBlank()) {
|
||||
bean.appIcon = ""
|
||||
}
|
||||
pushBeanQueue.offer(bean)
|
||||
}
|
||||
if ( bean != null) {
|
||||
HandlerUtils.mBgHandler.post {
|
||||
pushBeanDao.insertAll(bean)
|
||||
updateMsgNum()
|
||||
}
|
||||
}
|
||||
startIterate()
|
||||
}
|
||||
})
|
||||
// 注册push通道监听 type 100时为push消息 lixp TODO
|
||||
// getApis(mContext).getSocketManagerApi(mContext)
|
||||
// .registerOnMessageListener(Config.PUSH_TYPE, object : IMogoOnMessageListener<PushBean> {
|
||||
// override fun target(): Class<PushBean> {
|
||||
// return PushBean::class.java
|
||||
// }
|
||||
//
|
||||
// override fun onMsgReceived(bean: PushBean?) {
|
||||
// Log.d("PushRepository", "pushBean = $bean")
|
||||
// if (bean != null) {
|
||||
// AnalyticsUtils.track(Config.NEWS_ARRIVE, "title", bean.title)
|
||||
// if (bean.mainSchema.isBlank()) {
|
||||
// bean.mainSchema = ""
|
||||
// }
|
||||
// if (bean.imageUrl.isBlank()) {
|
||||
// bean.imageUrl = ""
|
||||
// }
|
||||
// if (bean.appIcon.isBlank()) {
|
||||
// bean.appIcon = ""
|
||||
// }
|
||||
// pushBeanQueue.offer(bean)
|
||||
// }
|
||||
// if ( bean != null) {
|
||||
// HandlerUtils.mBgHandler.post {
|
||||
// pushBeanDao.insertAll(bean)
|
||||
// updateMsgNum()
|
||||
// }
|
||||
// }
|
||||
// startIterate()
|
||||
// }
|
||||
// })
|
||||
HandlerUtils.mBgHandler.postDelayed({
|
||||
updateMsgNum()
|
||||
}, 5000)
|
||||
|
||||