[2.13.0-arch-opt] reduce unuse logic and remove notice to biz
@@ -275,13 +275,11 @@ dependencies {
|
||||
|
||||
androidTestImplementation rootProject.ext.dependencies.mogo_core_function_call
|
||||
androidTestImplementation rootProject.ext.dependencies.mogo_core_res
|
||||
androidTestImplementation rootProject.ext.dependencies.mogo_core_function_notice
|
||||
} else {
|
||||
implementation project(':tts:tts-pad')
|
||||
implementation project(':core:function-impl:mogo-core-function-hmi')
|
||||
androidTestImplementation project(':core:mogo-core-function-call')
|
||||
androidTestImplementation project(':core:mogo-core-res')
|
||||
androidTestImplementation project(':core:function-impl:mogo-core-function-notice')
|
||||
}
|
||||
|
||||
apply from: "./functions/och.gradle"
|
||||
|
||||
@@ -182,7 +182,6 @@ ext {
|
||||
mogo_core_function_map : "com.mogo.eagle.core.function.impl:map:${MOGO_CORE_FUNCTION_MAP_VERSION}",
|
||||
mogo_core_function_main : "com.mogo.eagle.core.function.impl:main:${MOGO_CORE_FUNCTION_MAIN_VERSION}",
|
||||
mogo_core_function_monitoring: "com.mogo.eagle.core.function.impl:monitoring:${MOGO_CORE_FUNCTION_MONITORING_VERSION}",
|
||||
mogo_core_function_notice : "com.mogo.eagle.core.function.impl:notice:${MOGO_CORE_FUNCTION_NOTICE_VERSION}",
|
||||
mogo_core_function_obu_mogo : "com.mogo.eagle.core.function.impl:obu-mogo:${MOGO_CORE_FUNCTION_OBU_MOGO_VERSION}",
|
||||
mogo_core_function_smp : "com.mogo.eagle.core.function.impl:smp:${MOGO_CORE_FUNCTION_SMP_VERSION}",
|
||||
mogo_core_function_v2x : "com.mogo.eagle.core.function.impl:v2x:${MOGO_CORE_FUNCTION_V2X_VERSION}",
|
||||
|
||||
@@ -5,9 +5,10 @@ plugins {
|
||||
id 'kotlin-kapt'
|
||||
id 'com.alibaba.arouter'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
// buildToolsVersion rootProject.ext.android.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
@@ -45,40 +46,23 @@ android {
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation rootProject.ext.dependencies.kotlinstdlibjdk7
|
||||
implementation rootProject.ext.dependencies.androidxccorektx
|
||||
implementation rootProject.ext.dependencies.androidxappcompat
|
||||
implementation rootProject.ext.dependencies.androidxconstraintlayout
|
||||
implementation rootProject.ext.dependencies.arouter
|
||||
implementation rootProject.ext.dependencies.rxandroid
|
||||
implementation rootProject.ext.dependencies.androidxrecyclerview
|
||||
implementation rootProject.ext.dependencies.androidxroomruntime
|
||||
implementation rootProject.ext.dependencies.androidxroomktx
|
||||
implementation rootProject.ext.dependencies.litezxing
|
||||
kapt rootProject.ext.dependencies.androidxroomcompiler
|
||||
kapt rootProject.ext.dependencies.aroutercompiler
|
||||
|
||||
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
|
||||
implementation rootProject.ext.dependencies.mogocommons
|
||||
implementation rootProject.ext.dependencies.mogo_core_data
|
||||
implementation rootProject.ext.dependencies.mogo_core_utils
|
||||
implementation rootProject.ext.dependencies.mogo_core_res
|
||||
implementation rootProject.ext.dependencies.mogo_core_network
|
||||
implementation rootProject.ext.dependencies.mogo_core_function_call
|
||||
} else {
|
||||
implementation project(":foudations:mogo-commons")
|
||||
implementation project(':core:mogo-core-data')
|
||||
implementation project(':core:mogo-core-utils')
|
||||
implementation project(':core:mogo-core-res')
|
||||
implementation project(':core:mogo-core-network')
|
||||
implementation project(':core:mogo-core-function-call')
|
||||
}
|
||||
implementation rootProject.ext.dependencies.rxandroid
|
||||
|
||||
implementation project(':foudations:mogo-commons')
|
||||
implementation project(':core:mogo-core-data')
|
||||
implementation project(':core:mogo-core-utils')
|
||||
implementation project(':core:mogo-core-network')
|
||||
implementation project(':core:mogo-core-function-call')
|
||||
}
|
||||
|
||||
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()
|
||||
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()
|
||||
@@ -1,3 +1,3 @@
|
||||
GROUP=com.mogo.eagle.core.function.impl
|
||||
POM_ARTIFACT_ID=notice
|
||||
POM_ARTIFACT_ID=biz
|
||||
VERSION_CODE=1
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.eagle.core.function.notice;
|
||||
package com.mogo.eagle.function.biz.push;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths;
|
||||
import com.mogo.eagle.core.function.api.notice.IMoGoNoticeProvider;
|
||||
import com.mogo.eagle.core.function.api.notice.NoticeNetCallBack;
|
||||
import com.mogo.eagle.core.function.notice.network.NoticeNetWorkManager;
|
||||
import com.mogo.eagle.function.biz.push.network.NoticeNetWorkManager;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.eagle.core.function.notice;
|
||||
package com.mogo.eagle.function.biz.push;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_NOTICE;
|
||||
|
||||
@@ -60,10 +60,10 @@ class NoticeSocketManager {
|
||||
|
||||
@Override
|
||||
public void onMsgReceived(NoticeNormalData obj) {
|
||||
CallerLogger.INSTANCE.d(M_NOTICE + TAG, "100-- 普通公告数据:" + GsonUtil.jsonFromObject(obj));
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_NOTICE + TAG, "100-- 普通公告数据:" + GsonUtil.jsonFromObject(obj));
|
||||
NoticeFrCloudMsg noticeFromCloudMsg = new NoticeFrCloudMsg(obj, null, 0);
|
||||
CallerMsgBoxManager.INSTANCE.saveMsgBox(new MsgBoxBean(MsgBoxType.NOTICE, noticeFromCloudMsg));
|
||||
}
|
||||
@@ -81,6 +81,9 @@ class NoticeSocketManager {
|
||||
|
||||
@Override
|
||||
public void onMsgReceived(NoticeTrafficStylePushData obj) {
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_NOTICE + TAG, "301001-- 交警类型公告数据:" + GsonUtil.jsonFromObject(obj));
|
||||
NoticeFrCloudMsg noticeFromCloudMsg = new NoticeFrCloudMsg(null, obj, 1);
|
||||
CallerMsgBoxManager.INSTANCE.saveMsgBox(new MsgBoxBean(MsgBoxType.NOTICE, noticeFromCloudMsg));
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.eagle.core.function.notice.network;
|
||||
package com.mogo.eagle.function.biz.push.network;
|
||||
|
||||
import com.mogo.eagle.core.data.BaseData;
|
||||
import com.mogo.eagle.core.data.notice.NoticeNormalDetail;
|
||||
@@ -30,7 +30,6 @@ public interface NoticeApiService {
|
||||
@POST("/deva/accidentInfoManage/queryMyAccidentHandleInfo/server/v1")
|
||||
Observable<NoticeTrafficStyleInfo> getAccidentInfo(@Body RequestBody requestBody);
|
||||
|
||||
|
||||
/**
|
||||
* 反馈对交警事故的操作
|
||||
*
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.eagle.core.function.notice.network;
|
||||
package com.mogo.eagle.function.biz.push.network;
|
||||
|
||||
import android.util.ArrayMap;
|
||||
|
||||
@@ -143,7 +143,6 @@ public class NoticeNetWorkManager {
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull NoticeNormalDetail noticeNormalDetail) {
|
||||
// CallerHmiManager.INSTANCE.showNormalBanner(noticeNormalDetail);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.eagle.core.function.notice.network;
|
||||
package com.mogo.eagle.function.biz.push.network;
|
||||
|
||||
/**
|
||||
* @author Jing
|
||||
@@ -89,7 +89,6 @@ dependencies {
|
||||
api rootProject.ext.dependencies.mogo_core_utils
|
||||
api rootProject.ext.dependencies.mogo_core_network
|
||||
api rootProject.ext.dependencies.mogo_core_function_obu_mogo
|
||||
api rootProject.ext.dependencies.mogo_core_function_notice
|
||||
api rootProject.ext.dependencies.mogo_core_function_bindingcar
|
||||
api rootProject.ext.dependencies.mogo_core_function_autopilot
|
||||
api rootProject.ext.dependencies.mogo_core_function_map
|
||||
@@ -113,7 +112,6 @@ dependencies {
|
||||
api project(':core:function-impl:mogo-core-function-obu-mogo')
|
||||
api project(':core:function-impl:mogo-core-function-autopilot')
|
||||
api project(':core:function-impl:mogo-core-function-map')
|
||||
api project(':core:function-impl:mogo-core-function-notice')
|
||||
api project(':core:function-impl:mogo-core-function-v2x')
|
||||
api project(':core:function-impl:mogo-core-function-monitoring')
|
||||
api project(':core:function-impl:mogo-core-function-devatools')
|
||||
|
||||
@@ -173,5 +173,11 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="com.mogo.eagle.core.function.hmi.receiver.NoticeBroadcastReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="com.hmi.notice.control" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.eagle.core.function.notice.test
|
||||
package com.mogo.eagle.core.function.hmi.receiver
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
@@ -11,7 +11,7 @@ import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
|
||||
* @description 测试类
|
||||
* @since: 10/29/21
|
||||
*/
|
||||
class TestNoticeBroadcastReceiver : BroadcastReceiver() {
|
||||
class NoticeBroadcastReceiver : BroadcastReceiver() {
|
||||
private var mContext: Context? = null
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent) {
|
||||
@@ -1,11 +0,0 @@
|
||||
<?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>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.mogo.eagle.core.function.notice">
|
||||
|
||||
<application>
|
||||
<receiver android:name=".test.TestNoticeBroadcastReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="com.notice.test_notice_control" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.mogo.eagle.core.function.notice
|
||||
|
||||
object Config {
|
||||
const val PUSH_TYPE = 100 //注册长连接类型
|
||||
const val NEWS_ARRIVE = "news_arrive" //Push到达
|
||||
const val NEWS_CARD_SHOW = "news_card_show"//push 展示
|
||||
const val NEWS_CARD_DISAPPEAR = "news_card_disappear"// push 展示到期,自动消失
|
||||
const val NEWS_CARD_CLICK = "news_card_click"//点击消息体
|
||||
const val NEWS_CARD_SWIPE = "news_card_swipe"//划掉消息
|
||||
const val NEWS_CARD_CLICK_BTN = "news_card_click_btn"//点击按钮
|
||||
|
||||
|
||||
const val NEWS_HISTORY_OPEN = "news_history_open"//打开消息列表
|
||||
const val NEWS_HISTORY_CLOSE = "news_history_close"//关闭消息列表
|
||||
const val NEWS_HISTORY_ALL_CLEAR = "news_history_all_clear"//清除消息列表
|
||||
const val NEWS_HISTORY_ONE_CLEAR = "news_history_one_clear"//清除消息历史中的消息
|
||||
const val NEWS_HISTORY_ONE_CLICK = "news_history_one_click"//点击消息历史中的消息
|
||||
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.mogo.eagle.core.function.notice.dao
|
||||
|
||||
import androidx.room.*
|
||||
import com.mogo.eagle.core.function.notice.model.PushBean
|
||||
|
||||
@Dao
|
||||
interface PushBeanDao {
|
||||
@Query("SELECT * FROM pushBean ORDER BY timestamp DESC")
|
||||
fun getAll(): MutableList<PushBean>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertAll(vararg bean: PushBean)
|
||||
|
||||
@Delete
|
||||
fun delete(vararg bean: PushBean)
|
||||
|
||||
@Query("DELETE FROM pushBean")
|
||||
fun deleteAll()
|
||||
|
||||
@Query("SELECT count(1) FROM pushBean")
|
||||
fun getAllCount(): Int
|
||||
|
||||
@Query("DELETE FROM pushBean WHERE timestamp IN (SELECT MIN(timestamp) FROM pushBean)")
|
||||
fun deleteMin()
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.mogo.eagle.core.function.notice.dao
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import com.mogo.eagle.core.function.notice.model.PushBean
|
||||
|
||||
@Database(entities = [PushBean::class], version = 1,exportSchema = false)
|
||||
abstract class PushBeanDatabase : RoomDatabase() {
|
||||
abstract fun pushBeanDao(): PushBeanDao
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.mogo.eagle.core.function.notice.model
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity
|
||||
data class PushBean(
|
||||
@Ignore
|
||||
val speedLimit: Int = 0, //超过速度后延迟显示
|
||||
@Ignore
|
||||
var showTimeout: Int = 0, //显示等待时长
|
||||
@Ignore
|
||||
var showTimeoutShadow: Int = 0, // 显示等待时长备份
|
||||
@ColumnInfo(name = "icon")
|
||||
var appIcon: String = "", //目标app icon图标地址
|
||||
@ColumnInfo(name = "title")
|
||||
var title: String = "", //标题
|
||||
@ColumnInfo(name = "content")
|
||||
var content: String = "", //详细内容
|
||||
@ColumnInfo(name = "image")
|
||||
var imageUrl: String = "", //图片地址
|
||||
@ColumnInfo(name = "qr")
|
||||
var QRCode: String = "", //二维码地址
|
||||
@Ignore
|
||||
val tts: String = "", //语音播报词
|
||||
@ColumnInfo(name = "scheme")
|
||||
var mainSchema: String = "", //schema跳转协议
|
||||
@Ignore
|
||||
val mainVoiceCmd: List<String>? = null, //触发主schema 命令词
|
||||
@Ignore
|
||||
val cancelVoiceCmd: List<String>? = null, //隐藏当前push命令词
|
||||
@Ignore
|
||||
val buttons: List<Button>? = null, //底部buttons列表
|
||||
@PrimaryKey
|
||||
var timestamp: Long = System.currentTimeMillis()
|
||||
|
||||
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other is PushBean) {
|
||||
return timestamp == other.timestamp
|
||||
}
|
||||
return super.equals(other)
|
||||
}
|
||||
}
|
||||
|
||||
data class Button(
|
||||
val text: String = "", // button名称
|
||||
val action: String = "", //scheme 协议
|
||||
val voiceCmd: List<String>? = null //注册命令词
|
||||
)
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.mogo.eagle.core.function.notice.view
|
||||
|
||||
import android.view.View
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1,657 +0,0 @@
|
||||
package com.mogo.eagle.core.function.notice.view;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This implementation of {@link RecyclerView.ItemAnimator} provides basic
|
||||
* animations on remove, add, and move events that happen to the items in
|
||||
* a RecyclerView. RecyclerView uses a DefaultItemAnimator by default.
|
||||
*
|
||||
* @see RecyclerView#setItemAnimator(RecyclerView.ItemAnimator)
|
||||
*/
|
||||
public class PushItemAnimator extends SimpleItemAnimator {
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static TimeInterpolator sDefaultInterpolator;
|
||||
|
||||
private ArrayList<RecyclerView.ViewHolder> mPendingRemovals = new ArrayList<>();
|
||||
private ArrayList<RecyclerView.ViewHolder> mPendingAdditions = new ArrayList<>();
|
||||
private ArrayList<MoveInfo> mPendingMoves = new ArrayList<>();
|
||||
private ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>();
|
||||
|
||||
ArrayList<ArrayList<RecyclerView.ViewHolder>> mAdditionsList = new ArrayList<>();
|
||||
ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>();
|
||||
ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>();
|
||||
|
||||
ArrayList<RecyclerView.ViewHolder> mAddAnimations = new ArrayList<>();
|
||||
ArrayList<RecyclerView.ViewHolder> mMoveAnimations = new ArrayList<>();
|
||||
ArrayList<RecyclerView.ViewHolder> mRemoveAnimations = new ArrayList<>();
|
||||
ArrayList<RecyclerView.ViewHolder> mChangeAnimations = new ArrayList<>();
|
||||
|
||||
private static class MoveInfo {
|
||||
public RecyclerView.ViewHolder holder;
|
||||
public int fromX, fromY, toX, toY;
|
||||
|
||||
MoveInfo(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
|
||||
this.holder = holder;
|
||||
this.fromX = fromX;
|
||||
this.fromY = fromY;
|
||||
this.toX = toX;
|
||||
this.toY = toY;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ChangeInfo {
|
||||
public RecyclerView.ViewHolder oldHolder, newHolder;
|
||||
public int fromX, fromY, toX, toY;
|
||||
|
||||
private ChangeInfo(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder) {
|
||||
this.oldHolder = oldHolder;
|
||||
this.newHolder = newHolder;
|
||||
}
|
||||
|
||||
ChangeInfo(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder,
|
||||
int fromX, int fromY, int toX, int toY) {
|
||||
this(oldHolder, newHolder);
|
||||
this.fromX = fromX;
|
||||
this.fromY = fromY;
|
||||
this.toX = toX;
|
||||
this.toY = toY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChangeInfo{"
|
||||
+ "oldHolder=" + oldHolder
|
||||
+ ", newHolder=" + newHolder
|
||||
+ ", fromX=" + fromX
|
||||
+ ", fromY=" + fromY
|
||||
+ ", toX=" + toX
|
||||
+ ", toY=" + toY
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runPendingAnimations() {
|
||||
boolean removalsPending = !mPendingRemovals.isEmpty();
|
||||
boolean movesPending = !mPendingMoves.isEmpty();
|
||||
boolean changesPending = !mPendingChanges.isEmpty();
|
||||
boolean additionsPending = !mPendingAdditions.isEmpty();
|
||||
if (!removalsPending && !movesPending && !additionsPending && !changesPending) {
|
||||
// nothing to animate
|
||||
return;
|
||||
}
|
||||
// First, remove stuff
|
||||
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
|
||||
animateRemoveImpl(holder);
|
||||
}
|
||||
mPendingRemovals.clear();
|
||||
// Next, move stuff
|
||||
if (movesPending) {
|
||||
final ArrayList<MoveInfo> moves = new ArrayList<>();
|
||||
moves.addAll(mPendingMoves);
|
||||
mMovesList.add(moves);
|
||||
mPendingMoves.clear();
|
||||
Runnable mover = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (MoveInfo moveInfo : moves) {
|
||||
animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY,
|
||||
moveInfo.toX, moveInfo.toY);
|
||||
}
|
||||
moves.clear();
|
||||
mMovesList.remove(moves);
|
||||
}
|
||||
};
|
||||
if (removalsPending) {
|
||||
View view = moves.get(0).holder.itemView;
|
||||
ViewCompat.postOnAnimationDelayed(view, mover, getRemoveDuration());
|
||||
} else {
|
||||
mover.run();
|
||||
}
|
||||
}
|
||||
// Next, change stuff, to run in parallel with move animations
|
||||
if (changesPending) {
|
||||
final ArrayList<ChangeInfo> changes = new ArrayList<>();
|
||||
changes.addAll(mPendingChanges);
|
||||
mChangesList.add(changes);
|
||||
mPendingChanges.clear();
|
||||
Runnable changer = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (ChangeInfo change : changes) {
|
||||
animateChangeImpl(change);
|
||||
}
|
||||
changes.clear();
|
||||
mChangesList.remove(changes);
|
||||
}
|
||||
};
|
||||
if (removalsPending) {
|
||||
RecyclerView.ViewHolder holder = changes.get(0).oldHolder;
|
||||
ViewCompat.postOnAnimationDelayed(holder.itemView, changer, getRemoveDuration());
|
||||
} else {
|
||||
changer.run();
|
||||
}
|
||||
}
|
||||
// Next, add stuff
|
||||
if (additionsPending) {
|
||||
final ArrayList<RecyclerView.ViewHolder> additions = new ArrayList<>();
|
||||
additions.addAll(mPendingAdditions);
|
||||
mAdditionsList.add(additions);
|
||||
mPendingAdditions.clear();
|
||||
Runnable adder = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (RecyclerView.ViewHolder holder : additions) {
|
||||
animateAddImpl(holder);
|
||||
}
|
||||
additions.clear();
|
||||
mAdditionsList.remove(additions);
|
||||
}
|
||||
};
|
||||
if (removalsPending || movesPending || changesPending) {
|
||||
long removeDuration = removalsPending ? getRemoveDuration() : 0;
|
||||
long moveDuration = movesPending ? getMoveDuration() : 0;
|
||||
long changeDuration = changesPending ? getChangeDuration() : 0;
|
||||
long totalDelay = removeDuration + Math.max(moveDuration, changeDuration);
|
||||
View view = additions.get(0).itemView;
|
||||
ViewCompat.postOnAnimationDelayed(view, adder, totalDelay);
|
||||
} else {
|
||||
adder.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean animateRemove(final RecyclerView.ViewHolder holder) {
|
||||
resetAnimation(holder);
|
||||
mPendingRemovals.add(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
|
||||
final View view = holder.itemView;
|
||||
final ViewPropertyAnimator animation = view.animate();
|
||||
mRemoveAnimations.add(holder);
|
||||
animation.setDuration(getRemoveDuration()).alpha(0).translationX(-view.getWidth()).setListener(
|
||||
new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchRemoveStarting(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
animation.setListener(null);
|
||||
view.setAlpha(1);
|
||||
dispatchRemoveFinished(holder);
|
||||
mRemoveAnimations.remove(holder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean animateAdd(final RecyclerView.ViewHolder holder) {
|
||||
resetAnimation(holder);
|
||||
holder.itemView.setAlpha(0);
|
||||
mPendingAdditions.add(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
void animateAddImpl(final RecyclerView.ViewHolder holder) {
|
||||
final View view = holder.itemView;
|
||||
final ViewPropertyAnimator animation = view.animate();
|
||||
mAddAnimations.add(holder);
|
||||
animation.alpha(1).setDuration(getAddDuration())
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchAddStarting(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
view.setAlpha(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
animation.setListener(null);
|
||||
dispatchAddFinished(holder);
|
||||
mAddAnimations.remove(holder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean animateMove(final RecyclerView.ViewHolder holder, int fromX, int fromY,
|
||||
int toX, int toY) {
|
||||
final View view = holder.itemView;
|
||||
fromX += (int) holder.itemView.getTranslationX();
|
||||
fromY += (int) holder.itemView.getTranslationY();
|
||||
resetAnimation(holder);
|
||||
int deltaX = toX - fromX;
|
||||
int deltaY = toY - fromY;
|
||||
if (deltaX == 0 && deltaY == 0) {
|
||||
dispatchMoveFinished(holder);
|
||||
return false;
|
||||
}
|
||||
if (deltaX != 0) {
|
||||
view.setTranslationX(-deltaX);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
view.setTranslationY(-deltaY);
|
||||
}
|
||||
mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
|
||||
return true;
|
||||
}
|
||||
|
||||
void animateMoveImpl(final RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
|
||||
final View view = holder.itemView;
|
||||
final int deltaX = toX - fromX;
|
||||
final int deltaY = toY - fromY;
|
||||
if (deltaX != 0) {
|
||||
view.animate().translationX(0);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
view.animate().translationY(0);
|
||||
}
|
||||
// TODO: make EndActions end listeners instead, since end actions aren't called when
|
||||
// vpas are canceled (and can't end them. why?)
|
||||
// need listener functionality in VPACompat for this. Ick.
|
||||
final ViewPropertyAnimator animation = view.animate();
|
||||
mMoveAnimations.add(holder);
|
||||
animation.setDuration(getMoveDuration()).setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchMoveStarting(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
if (deltaX != 0) {
|
||||
view.setTranslationX(0);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
view.setTranslationY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
animation.setListener(null);
|
||||
dispatchMoveFinished(holder);
|
||||
mMoveAnimations.remove(holder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder,
|
||||
int fromX, int fromY, int toX, int toY) {
|
||||
if (oldHolder == newHolder) {
|
||||
// Don't know how to run change animations when the same view holder is re-used.
|
||||
// run a move animation to handle position changes.
|
||||
return animateMove(oldHolder, fromX, fromY, toX, toY);
|
||||
}
|
||||
final float prevTranslationX = oldHolder.itemView.getTranslationX();
|
||||
final float prevTranslationY = oldHolder.itemView.getTranslationY();
|
||||
final float prevAlpha = oldHolder.itemView.getAlpha();
|
||||
resetAnimation(oldHolder);
|
||||
int deltaX = (int) (toX - fromX - prevTranslationX);
|
||||
int deltaY = (int) (toY - fromY - prevTranslationY);
|
||||
// recover prev translation state after ending animation
|
||||
oldHolder.itemView.setTranslationX(prevTranslationX);
|
||||
oldHolder.itemView.setTranslationY(prevTranslationY);
|
||||
oldHolder.itemView.setAlpha(prevAlpha);
|
||||
if (newHolder != null) {
|
||||
// carry over translation values
|
||||
resetAnimation(newHolder);
|
||||
newHolder.itemView.setTranslationX(-deltaX);
|
||||
newHolder.itemView.setTranslationY(-deltaY);
|
||||
newHolder.itemView.setAlpha(0);
|
||||
}
|
||||
mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
|
||||
return true;
|
||||
}
|
||||
|
||||
void animateChangeImpl(final ChangeInfo changeInfo) {
|
||||
final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
|
||||
final View view = holder == null ? null : holder.itemView;
|
||||
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
|
||||
final View newView = newHolder != null ? newHolder.itemView : null;
|
||||
if (view != null) {
|
||||
final ViewPropertyAnimator oldViewAnim = view.animate().setDuration(
|
||||
getChangeDuration());
|
||||
mChangeAnimations.add(changeInfo.oldHolder);
|
||||
oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX);
|
||||
oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY);
|
||||
oldViewAnim.alpha(0).setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchChangeStarting(changeInfo.oldHolder, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
oldViewAnim.setListener(null);
|
||||
view.setAlpha(1);
|
||||
view.setTranslationX(0);
|
||||
view.setTranslationY(0);
|
||||
dispatchChangeFinished(changeInfo.oldHolder, true);
|
||||
mChangeAnimations.remove(changeInfo.oldHolder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
if (newView != null) {
|
||||
final ViewPropertyAnimator newViewAnimation = newView.animate();
|
||||
mChangeAnimations.add(changeInfo.newHolder);
|
||||
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration())
|
||||
.alpha(1).setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchChangeStarting(changeInfo.newHolder, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
newViewAnimation.setListener(null);
|
||||
newView.setAlpha(1);
|
||||
newView.setTranslationX(0);
|
||||
newView.setTranslationY(0);
|
||||
dispatchChangeFinished(changeInfo.newHolder, false);
|
||||
mChangeAnimations.remove(changeInfo.newHolder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void endChangeAnimation(List<ChangeInfo> infoList, RecyclerView.ViewHolder item) {
|
||||
for (int i = infoList.size() - 1; i >= 0; i--) {
|
||||
ChangeInfo changeInfo = infoList.get(i);
|
||||
if (endChangeAnimationIfNecessary(changeInfo, item)) {
|
||||
if (changeInfo.oldHolder == null && changeInfo.newHolder == null) {
|
||||
infoList.remove(changeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) {
|
||||
if (changeInfo.oldHolder != null) {
|
||||
endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder);
|
||||
}
|
||||
if (changeInfo.newHolder != null) {
|
||||
endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, RecyclerView.ViewHolder item) {
|
||||
boolean oldItem = false;
|
||||
if (changeInfo.newHolder == item) {
|
||||
changeInfo.newHolder = null;
|
||||
} else if (changeInfo.oldHolder == item) {
|
||||
changeInfo.oldHolder = null;
|
||||
oldItem = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
item.itemView.setAlpha(1);
|
||||
item.itemView.setTranslationX(0);
|
||||
item.itemView.setTranslationY(0);
|
||||
dispatchChangeFinished(item, oldItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endAnimation(RecyclerView.ViewHolder item) {
|
||||
final View view = item.itemView;
|
||||
// this will trigger end callback which should set properties to their target values.
|
||||
view.animate().cancel();
|
||||
// TODO if some other animations are chained to end, how do we cancel them as well?
|
||||
for (int i = mPendingMoves.size() - 1; i >= 0; i--) {
|
||||
MoveInfo moveInfo = mPendingMoves.get(i);
|
||||
if (moveInfo.holder == item) {
|
||||
view.setTranslationY(0);
|
||||
view.setTranslationX(0);
|
||||
dispatchMoveFinished(item);
|
||||
mPendingMoves.remove(i);
|
||||
}
|
||||
}
|
||||
endChangeAnimation(mPendingChanges, item);
|
||||
if (mPendingRemovals.remove(item)) {
|
||||
view.setAlpha(1);
|
||||
dispatchRemoveFinished(item);
|
||||
}
|
||||
if (mPendingAdditions.remove(item)) {
|
||||
view.setAlpha(1);
|
||||
dispatchAddFinished(item);
|
||||
}
|
||||
|
||||
for (int i = mChangesList.size() - 1; i >= 0; i--) {
|
||||
ArrayList<ChangeInfo> changes = mChangesList.get(i);
|
||||
endChangeAnimation(changes, item);
|
||||
if (changes.isEmpty()) {
|
||||
mChangesList.remove(i);
|
||||
}
|
||||
}
|
||||
for (int i = mMovesList.size() - 1; i >= 0; i--) {
|
||||
ArrayList<MoveInfo> moves = mMovesList.get(i);
|
||||
for (int j = moves.size() - 1; j >= 0; j--) {
|
||||
MoveInfo moveInfo = moves.get(j);
|
||||
if (moveInfo.holder == item) {
|
||||
view.setTranslationY(0);
|
||||
view.setTranslationX(0);
|
||||
dispatchMoveFinished(item);
|
||||
moves.remove(j);
|
||||
if (moves.isEmpty()) {
|
||||
mMovesList.remove(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = mAdditionsList.size() - 1; i >= 0; i--) {
|
||||
ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i);
|
||||
if (additions.remove(item)) {
|
||||
view.setAlpha(1);
|
||||
dispatchAddFinished(item);
|
||||
if (additions.isEmpty()) {
|
||||
mAdditionsList.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// animations should be ended by the cancel above.
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (mRemoveAnimations.remove(item) && DEBUG) {
|
||||
throw new IllegalStateException("after animation is cancelled, item should not be in "
|
||||
+ "mRemoveAnimations list");
|
||||
}
|
||||
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (mAddAnimations.remove(item) && DEBUG) {
|
||||
throw new IllegalStateException("after animation is cancelled, item should not be in "
|
||||
+ "mAddAnimations list");
|
||||
}
|
||||
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (mChangeAnimations.remove(item) && DEBUG) {
|
||||
throw new IllegalStateException("after animation is cancelled, item should not be in "
|
||||
+ "mChangeAnimations list");
|
||||
}
|
||||
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (mMoveAnimations.remove(item) && DEBUG) {
|
||||
throw new IllegalStateException("after animation is cancelled, item should not be in "
|
||||
+ "mMoveAnimations list");
|
||||
}
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
|
||||
private void resetAnimation(RecyclerView.ViewHolder holder) {
|
||||
if (sDefaultInterpolator == null) {
|
||||
sDefaultInterpolator = new ValueAnimator().getInterpolator();
|
||||
}
|
||||
holder.itemView.animate().setInterpolator(sDefaultInterpolator);
|
||||
endAnimation(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return (!mPendingAdditions.isEmpty()
|
||||
|| !mPendingChanges.isEmpty()
|
||||
|| !mPendingMoves.isEmpty()
|
||||
|| !mPendingRemovals.isEmpty()
|
||||
|| !mMoveAnimations.isEmpty()
|
||||
|| !mRemoveAnimations.isEmpty()
|
||||
|| !mAddAnimations.isEmpty()
|
||||
|| !mChangeAnimations.isEmpty()
|
||||
|| !mMovesList.isEmpty()
|
||||
|| !mAdditionsList.isEmpty()
|
||||
|| !mChangesList.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the state of currently pending and running animations. If there are none
|
||||
* pending/running, call {@link #dispatchAnimationsFinished()} to notify any
|
||||
* listeners.
|
||||
*/
|
||||
void dispatchFinishedWhenDone() {
|
||||
if (!isRunning()) {
|
||||
dispatchAnimationsFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endAnimations() {
|
||||
int count = mPendingMoves.size();
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
MoveInfo item = mPendingMoves.get(i);
|
||||
View view = item.holder.itemView;
|
||||
view.setTranslationY(0);
|
||||
view.setTranslationX(0);
|
||||
dispatchMoveFinished(item.holder);
|
||||
mPendingMoves.remove(i);
|
||||
}
|
||||
count = mPendingRemovals.size();
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
RecyclerView.ViewHolder item = mPendingRemovals.get(i);
|
||||
dispatchRemoveFinished(item);
|
||||
mPendingRemovals.remove(i);
|
||||
}
|
||||
count = mPendingAdditions.size();
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
RecyclerView.ViewHolder item = mPendingAdditions.get(i);
|
||||
item.itemView.setAlpha(1);
|
||||
dispatchAddFinished(item);
|
||||
mPendingAdditions.remove(i);
|
||||
}
|
||||
count = mPendingChanges.size();
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
endChangeAnimationIfNecessary(mPendingChanges.get(i));
|
||||
}
|
||||
mPendingChanges.clear();
|
||||
if (!isRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int listCount = mMovesList.size();
|
||||
for (int i = listCount - 1; i >= 0; i--) {
|
||||
ArrayList<MoveInfo> moves = mMovesList.get(i);
|
||||
count = moves.size();
|
||||
for (int j = count - 1; j >= 0; j--) {
|
||||
MoveInfo moveInfo = moves.get(j);
|
||||
RecyclerView.ViewHolder item = moveInfo.holder;
|
||||
View view = item.itemView;
|
||||
view.setTranslationY(0);
|
||||
view.setTranslationX(0);
|
||||
dispatchMoveFinished(moveInfo.holder);
|
||||
moves.remove(j);
|
||||
if (moves.isEmpty()) {
|
||||
mMovesList.remove(moves);
|
||||
}
|
||||
}
|
||||
}
|
||||
listCount = mAdditionsList.size();
|
||||
for (int i = listCount - 1; i >= 0; i--) {
|
||||
ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i);
|
||||
count = additions.size();
|
||||
for (int j = count - 1; j >= 0; j--) {
|
||||
RecyclerView.ViewHolder item = additions.get(j);
|
||||
View view = item.itemView;
|
||||
view.setAlpha(1);
|
||||
dispatchAddFinished(item);
|
||||
additions.remove(j);
|
||||
if (additions.isEmpty()) {
|
||||
mAdditionsList.remove(additions);
|
||||
}
|
||||
}
|
||||
}
|
||||
listCount = mChangesList.size();
|
||||
for (int i = listCount - 1; i >= 0; i--) {
|
||||
ArrayList<ChangeInfo> changes = mChangesList.get(i);
|
||||
count = changes.size();
|
||||
for (int j = count - 1; j >= 0; j--) {
|
||||
endChangeAnimationIfNecessary(changes.get(j));
|
||||
if (changes.isEmpty()) {
|
||||
mChangesList.remove(changes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cancelAll(mRemoveAnimations);
|
||||
cancelAll(mMoveAnimations);
|
||||
cancelAll(mAddAnimations);
|
||||
cancelAll(mChangeAnimations);
|
||||
|
||||
dispatchAnimationsFinished();
|
||||
}
|
||||
|
||||
void cancelAll(List<RecyclerView.ViewHolder> viewHolders) {
|
||||
for (int i = viewHolders.size() - 1; i >= 0; i--) {
|
||||
viewHolders.get(i).itemView.animate().cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* If the payload list is not empty, DefaultItemAnimator returns <code>true</code>.
|
||||
* When this is the case:
|
||||
* <ul>
|
||||
* <li>If you override {@link #animateChange(RecyclerView.ViewHolder, RecyclerView.ViewHolder, int, int, int, int)}, both
|
||||
* ViewHolder arguments will be the same instance.
|
||||
* </li>
|
||||
* <li>
|
||||
* If you are not overriding {@link #animateChange(RecyclerView.ViewHolder, RecyclerView.ViewHolder, int, int, int, int)},
|
||||
* then DefaultItemAnimator will call {@link #animateMove(RecyclerView.ViewHolder, int, int, int, int)} and
|
||||
* run a move animation instead.
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder,
|
||||
@NonNull List<Object> payloads) {
|
||||
return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads);
|
||||
}
|
||||
}
|
||||
@@ -1,784 +0,0 @@
|
||||
package com.mogo.eagle.core.function.notice.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.Scroller;
|
||||
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* recyclerview滑动删除类
|
||||
*/
|
||||
public class SwipeItemLayout extends ViewGroup {
|
||||
enum Mode {
|
||||
RESET, DRAG, FLING, TAP
|
||||
}
|
||||
|
||||
private Mode mTouchMode;
|
||||
|
||||
private ViewGroup mMainView;
|
||||
private ViewGroup mSideView;
|
||||
|
||||
private ScrollRunnable mScrollRunnable;
|
||||
private int mScrollOffset;
|
||||
private int mMaxScrollOffset;
|
||||
|
||||
private boolean mInLayout;
|
||||
private boolean mIsLaidOut;
|
||||
|
||||
public void setOpenSwipe(boolean mOpenSwipe) {
|
||||
this.mOpenSwipe = mOpenSwipe;
|
||||
}
|
||||
|
||||
private boolean mOpenSwipe = true;
|
||||
|
||||
public SwipeItemLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SwipeItemLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
mTouchMode = Mode.RESET;
|
||||
mScrollOffset = 0;
|
||||
mIsLaidOut = false;
|
||||
|
||||
mScrollRunnable = new ScrollRunnable(context);
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return mScrollOffset != 0;
|
||||
}
|
||||
|
||||
Mode getTouchMode() {
|
||||
return mTouchMode;
|
||||
}
|
||||
|
||||
void setTouchMode(Mode mode) {
|
||||
switch (mTouchMode) {
|
||||
case FLING:
|
||||
mScrollRunnable.abort();
|
||||
break;
|
||||
case RESET:
|
||||
break;
|
||||
}
|
||||
|
||||
mTouchMode = mode;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
if (mScrollOffset != -mMaxScrollOffset) {
|
||||
//正在open,不需要处理
|
||||
if (mTouchMode == Mode.FLING && mScrollRunnable.isScrollToLeft())
|
||||
return;
|
||||
|
||||
//当前正在向右滑,abort
|
||||
if (mTouchMode == Mode.FLING /*&& !mScrollRunnable.mScrollToLeft*/)
|
||||
mScrollRunnable.abort();
|
||||
|
||||
mScrollRunnable.startScroll(mScrollOffset, -mMaxScrollOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
|
||||
super.addOnAttachStateChangeListener(listener);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (mScrollOffset != 0) {
|
||||
//正在close,不需要处理
|
||||
if (mTouchMode == Mode.FLING && !mScrollRunnable.isScrollToLeft())
|
||||
return;
|
||||
|
||||
//当前正向左滑,abort
|
||||
if (mTouchMode == Mode.FLING /*&& mScrollRunnable.mScrollToLeft*/)
|
||||
mScrollRunnable.abort();
|
||||
|
||||
mScrollRunnable.startScroll(mScrollOffset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void fling(int xVel) {
|
||||
mScrollRunnable.startFling(mScrollOffset, xVel);
|
||||
}
|
||||
|
||||
void revise() {
|
||||
if (mScrollOffset < -mMaxScrollOffset / 2)
|
||||
open();
|
||||
else
|
||||
close();
|
||||
}
|
||||
|
||||
boolean trackMotionScroll(int deltaX) {
|
||||
if (deltaX == 0)
|
||||
return false;
|
||||
|
||||
boolean over = false;
|
||||
int newLeft = mScrollOffset + deltaX;
|
||||
if ((deltaX > 0 && newLeft > 0) || (deltaX < 0 && newLeft < -mMaxScrollOffset)) {
|
||||
over = true;
|
||||
newLeft = Math.min(newLeft, 0);
|
||||
newLeft = Math.max(newLeft, -mMaxScrollOffset);
|
||||
}
|
||||
|
||||
offsetChildrenLeftAndRight(newLeft - mScrollOffset);
|
||||
mScrollOffset = newLeft;
|
||||
return over;
|
||||
}
|
||||
|
||||
private boolean ensureChildren() {
|
||||
int childCount = getChildCount();
|
||||
|
||||
if (childCount != 2)
|
||||
return false;
|
||||
|
||||
View childView = getChildAt(0);
|
||||
if (!(childView instanceof ViewGroup))
|
||||
return false;
|
||||
mMainView = (ViewGroup) childView;
|
||||
|
||||
childView = getChildAt(1);
|
||||
if (!(childView instanceof ViewGroup))
|
||||
return false;
|
||||
mSideView = (ViewGroup) childView;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (!ensureChildren())
|
||||
throw new RuntimeException("SwipeItemLayout的子视图不符合规定");
|
||||
|
||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
MarginLayoutParams lp = null;
|
||||
int horizontalMargin, verticalMargin;
|
||||
int horizontalPadding = getPaddingLeft() + getPaddingRight();
|
||||
int verticalPadding = getPaddingTop() + getPaddingBottom();
|
||||
|
||||
lp = (MarginLayoutParams) mMainView.getLayoutParams();
|
||||
horizontalMargin = lp.leftMargin + lp.rightMargin;
|
||||
verticalMargin = lp.topMargin + lp.bottomMargin;
|
||||
measureChildWithMargins(mMainView,
|
||||
widthMeasureSpec, horizontalMargin + horizontalPadding,
|
||||
heightMeasureSpec, verticalMargin + verticalPadding);
|
||||
|
||||
if (widthMode == MeasureSpec.AT_MOST)
|
||||
widthSize = Math.min(widthSize, mMainView.getMeasuredWidth() + horizontalMargin + horizontalPadding);
|
||||
else if (widthMode == MeasureSpec.UNSPECIFIED)
|
||||
widthSize = mMainView.getMeasuredWidth() + horizontalMargin + horizontalPadding;
|
||||
|
||||
if (heightMode == MeasureSpec.AT_MOST)
|
||||
heightSize = Math.min(heightSize, mMainView.getMeasuredHeight() + verticalMargin + verticalPadding);
|
||||
else if (heightMode == MeasureSpec.UNSPECIFIED)
|
||||
heightSize = mMainView.getMeasuredHeight() + verticalMargin + verticalPadding;
|
||||
|
||||
setMeasuredDimension(widthSize, heightSize);
|
||||
|
||||
//side layout大小为自身实际大小
|
||||
lp = (MarginLayoutParams) mSideView.getLayoutParams();
|
||||
verticalMargin = lp.topMargin + lp.bottomMargin;
|
||||
mSideView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
|
||||
MeasureSpec.makeMeasureSpec(getMeasuredHeight() - verticalMargin - verticalPadding, MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
if (!ensureChildren())
|
||||
throw new RuntimeException("SwipeItemLayout的子视图不符合规定");
|
||||
|
||||
mInLayout = true;
|
||||
|
||||
int pl = getPaddingLeft();
|
||||
int pt = getPaddingTop();
|
||||
int pr = getPaddingRight();
|
||||
int pb = getPaddingBottom();
|
||||
|
||||
MarginLayoutParams mainLp = (MarginLayoutParams) mMainView.getLayoutParams();
|
||||
MarginLayoutParams sideParams = (MarginLayoutParams) mSideView.getLayoutParams();
|
||||
|
||||
int childLeft = pl + mainLp.leftMargin;
|
||||
int childTop = pt + mainLp.topMargin;
|
||||
int childRight = getWidth() - (pr + mainLp.rightMargin);
|
||||
int childBottom = getHeight() - (mainLp.bottomMargin + pb);
|
||||
mMainView.layout(childLeft, childTop, childRight, childBottom);
|
||||
|
||||
childLeft = childRight + sideParams.leftMargin;
|
||||
childTop = pt + sideParams.topMargin;
|
||||
childRight = childLeft + sideParams.leftMargin + sideParams.rightMargin + mSideView.getMeasuredWidth();
|
||||
childBottom = getHeight() - (sideParams.bottomMargin + pb);
|
||||
mSideView.layout(childLeft, childTop, childRight, childBottom);
|
||||
if (mOpenSwipe) {
|
||||
mMaxScrollOffset = mSideView.getWidth() + sideParams.leftMargin + sideParams.rightMargin;
|
||||
} else {
|
||||
mMaxScrollOffset = 0;
|
||||
}
|
||||
mScrollOffset = mScrollOffset < -mMaxScrollOffset / 2 ? -mMaxScrollOffset : 0;
|
||||
|
||||
offsetChildrenLeftAndRight(mScrollOffset);
|
||||
mInLayout = false;
|
||||
mIsLaidOut = true;
|
||||
}
|
||||
|
||||
void offsetChildrenLeftAndRight(int delta) {
|
||||
ViewCompat.offsetLeftAndRight(mMainView, delta);
|
||||
ViewCompat.offsetLeftAndRight(mSideView, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
if (!mInLayout) {
|
||||
super.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutParams generateDefaultLayoutParams() {
|
||||
return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutParams generateLayoutParams(LayoutParams p) {
|
||||
return p instanceof MarginLayoutParams ? p : new MarginLayoutParams(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkLayoutParams(LayoutParams p) {
|
||||
return p instanceof MarginLayoutParams && super.checkLayoutParams(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutParams generateLayoutParams(AttributeSet attrs) {
|
||||
return new MarginLayoutParams(getContext(), attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
if (mScrollOffset != 0 && mIsLaidOut) {
|
||||
offsetChildrenLeftAndRight(-mScrollOffset);
|
||||
mScrollOffset = 0;
|
||||
} else
|
||||
mScrollOffset = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
|
||||
if (mScrollOffset != 0 && mIsLaidOut) {
|
||||
offsetChildrenLeftAndRight(-mScrollOffset);
|
||||
mScrollOffset = 0;
|
||||
} else
|
||||
mScrollOffset = 0;
|
||||
removeCallbacks(mScrollRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
final int action = ev.getActionMasked();
|
||||
//click main view,但是它处于open状态,所以,不需要点击效果,直接拦截不调用click listener
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
final int x = (int) ev.getX();
|
||||
final int y = (int) ev.getY();
|
||||
View pointView = findTopChildUnder(this, x, y);
|
||||
if (pointView != null && pointView == mMainView && mScrollOffset != 0)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP: {
|
||||
final int x = (int) ev.getX();
|
||||
final int y = (int) ev.getY();
|
||||
View pointView = findTopChildUnder(this, x, y);
|
||||
if (pointView != null && pointView == mMainView && mTouchMode == Mode.TAP && mScrollOffset != 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
final int action = ev.getActionMasked();
|
||||
//click main view,但是它处于open状态,所以,不需要点击效果,直接拦截不调用click listener
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
final int x = (int) ev.getX();
|
||||
final int y = (int) ev.getY();
|
||||
View pointView = findTopChildUnder(this, x, y);
|
||||
if (pointView != null && pointView == mMainView && mScrollOffset != 0)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP: {
|
||||
final int x = (int) ev.getX();
|
||||
final int y = (int) ev.getY();
|
||||
View pointView = findTopChildUnder(this, x, y);
|
||||
if (pointView != null && pointView == mMainView && mTouchMode == Mode.TAP && mScrollOffset != 0) {
|
||||
close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onVisibilityChanged(View changedView, int visibility) {
|
||||
super.onVisibilityChanged(changedView, visibility);
|
||||
if (getVisibility() != View.VISIBLE) {
|
||||
mScrollOffset = 0;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private static final Interpolator sInterpolator = new Interpolator() {
|
||||
@Override
|
||||
public float getInterpolation(float t) {
|
||||
t -= 1.0f;
|
||||
return t * t * t * t * t + 1.0f;
|
||||
}
|
||||
};
|
||||
|
||||
class ScrollRunnable implements Runnable {
|
||||
private static final int FLING_DURATION = 200;
|
||||
private Scroller mScroller;
|
||||
private boolean mAbort;
|
||||
private int mMinVelocity;
|
||||
private boolean mScrollToLeft;
|
||||
|
||||
ScrollRunnable(Context context) {
|
||||
mScroller = new Scroller(context, sInterpolator);
|
||||
mAbort = false;
|
||||
mScrollToLeft = false;
|
||||
|
||||
ViewConfiguration configuration = ViewConfiguration.get(context);
|
||||
mMinVelocity = configuration.getScaledMinimumFlingVelocity();
|
||||
}
|
||||
|
||||
void startScroll(int startX, int endX) {
|
||||
if (startX != endX) {
|
||||
setTouchMode(Mode.FLING);
|
||||
mAbort = false;
|
||||
mScrollToLeft = endX < startX;
|
||||
mScroller.startScroll(startX, 0, endX - startX, 0, 400);
|
||||
ViewCompat.postOnAnimation(SwipeItemLayout.this, this);
|
||||
}
|
||||
}
|
||||
|
||||
void startFling(int startX, int xVel) {
|
||||
if (xVel > mMinVelocity && startX != 0) {
|
||||
startScroll(startX, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (xVel < -mMinVelocity && startX != -mMaxScrollOffset) {
|
||||
startScroll(startX, -mMaxScrollOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
startScroll(startX, startX > -mMaxScrollOffset / 2 ? 0 : -mMaxScrollOffset);
|
||||
}
|
||||
|
||||
void abort() {
|
||||
if (!mAbort) {
|
||||
mAbort = true;
|
||||
if (!mScroller.isFinished()) {
|
||||
mScroller.abortAnimation();
|
||||
removeCallbacks(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//是否正在滑动需要另外判断
|
||||
boolean isScrollToLeft() {
|
||||
return mScrollToLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!mAbort) {
|
||||
boolean more = mScroller.computeScrollOffset();
|
||||
int curX = mScroller.getCurrX();
|
||||
boolean atEdge = trackMotionScroll(curX - mScrollOffset);
|
||||
if (more && !atEdge) {
|
||||
ViewCompat.postOnAnimation(SwipeItemLayout.this, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (atEdge) {
|
||||
removeCallbacks(this);
|
||||
if (!mScroller.isFinished())
|
||||
mScroller.abortAnimation();
|
||||
setTouchMode(Mode.RESET);
|
||||
}
|
||||
|
||||
if (!more) {
|
||||
setTouchMode(Mode.RESET);
|
||||
//绝对不会出现这种意外的!!!可以注释掉
|
||||
if (mScrollOffset != 0) {
|
||||
if (Math.abs(mScrollOffset) > mMaxScrollOffset / 2)
|
||||
mScrollOffset = -mMaxScrollOffset;
|
||||
else
|
||||
mScrollOffset = 0;
|
||||
ViewCompat.postOnAnimation(SwipeItemLayout.this, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class OnSwipeItemTouchListener implements RecyclerView.OnItemTouchListener {
|
||||
private SwipeItemLayout mCaptureItem;
|
||||
private float mLastMotionX;
|
||||
private float mLastMotionY;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
|
||||
private int mActivePointerId;
|
||||
|
||||
private int mTouchSlop;
|
||||
private int mMaximumVelocity;
|
||||
|
||||
private boolean mDealByParent;
|
||||
private boolean mIsProbeParent;
|
||||
|
||||
public OnSwipeItemTouchListener(Context context) {
|
||||
ViewConfiguration configuration = ViewConfiguration.get(context);
|
||||
mTouchSlop = configuration.getScaledTouchSlop();
|
||||
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
|
||||
mActivePointerId = -1;
|
||||
mDealByParent = false;
|
||||
mIsProbeParent = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent ev) {
|
||||
if (mIsProbeParent)
|
||||
return false;
|
||||
|
||||
boolean intercept = false;
|
||||
final int action = ev.getActionMasked();
|
||||
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
final float x = ev.getX();
|
||||
final float y = ev.getY();
|
||||
mLastMotionX = x;
|
||||
mLastMotionY = y;
|
||||
|
||||
boolean pointOther = false;
|
||||
SwipeItemLayout pointItem = null;
|
||||
//首先知道ev针对的是哪个item
|
||||
View pointView = findTopChildUnder(rv, (int) x, (int) y);
|
||||
if (pointView == null || !(pointView instanceof SwipeItemLayout)) {
|
||||
//可能是head view或bottom view
|
||||
pointOther = true;
|
||||
} else
|
||||
pointItem = (SwipeItemLayout) pointView;
|
||||
|
||||
//此时的pointOther=true,意味着点击的view为空或者点击的不是item
|
||||
//还没有把点击的是item但是不是capture item给过滤出来
|
||||
if (!pointOther && (mCaptureItem == null || mCaptureItem != pointItem))
|
||||
pointOther = true;
|
||||
|
||||
//点击的是capture item
|
||||
if (!pointOther) {
|
||||
Mode touchMode = mCaptureItem.getTouchMode();
|
||||
|
||||
//如果它在fling,就转为drag
|
||||
//需要拦截,并且requestDisallowInterceptTouchEvent
|
||||
boolean disallowIntercept = false;
|
||||
if (touchMode == Mode.FLING) {
|
||||
mCaptureItem.setTouchMode(Mode.DRAG);
|
||||
disallowIntercept = true;
|
||||
intercept = true;
|
||||
} else {//如果是expand的,就不允许parent拦截
|
||||
mCaptureItem.setTouchMode(Mode.TAP);
|
||||
if (mCaptureItem.isOpen())
|
||||
disallowIntercept = true;
|
||||
}
|
||||
|
||||
if (disallowIntercept) {
|
||||
final ViewParent parent = rv.getParent();
|
||||
if (parent != null)
|
||||
parent.requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
} else {//capture item为null或者与point item不一样
|
||||
//直接将其close掉
|
||||
if (mCaptureItem != null && mCaptureItem.isOpen()) {
|
||||
mCaptureItem.close();
|
||||
mCaptureItem = null;
|
||||
intercept = true;
|
||||
}
|
||||
|
||||
if (pointItem != null) {
|
||||
mCaptureItem = pointItem;
|
||||
mCaptureItem.setTouchMode(Mode.TAP);
|
||||
} else
|
||||
mCaptureItem = null;
|
||||
}
|
||||
|
||||
//如果parent处于fling状态,此时,parent就会转为drag。此时,应该将后续move都交给parent处理
|
||||
mIsProbeParent = true;
|
||||
mDealByParent = rv.onInterceptTouchEvent(ev);
|
||||
mIsProbeParent = false;
|
||||
if (mDealByParent)
|
||||
intercept = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_POINTER_DOWN: {
|
||||
final int actionIndex = ev.getActionIndex();
|
||||
mActivePointerId = ev.getPointerId(actionIndex);
|
||||
|
||||
mLastMotionX = ev.getX(actionIndex);
|
||||
mLastMotionY = ev.getY(actionIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
final int actionIndex = ev.getActionIndex();
|
||||
final int pointerId = ev.getPointerId(actionIndex);
|
||||
if (pointerId == mActivePointerId) {
|
||||
final int newIndex = actionIndex == 0 ? 1 : 0;
|
||||
mActivePointerId = ev.getPointerId(newIndex);
|
||||
|
||||
mLastMotionX = ev.getX(newIndex);
|
||||
mLastMotionY = ev.getY(newIndex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//down时,已经将capture item定下来了。所以,后面可以安心考虑event处理
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
|
||||
if (activePointerIndex == -1)
|
||||
break;
|
||||
|
||||
//在down时,就被认定为parent的drag,所以,直接交给parent处理即可
|
||||
if (mDealByParent) {
|
||||
if (mCaptureItem != null && mCaptureItem.isOpen())
|
||||
mCaptureItem.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
final int x = (int) (ev.getX(activePointerIndex) + .5f);
|
||||
final int y = (int) ((int) ev.getY(activePointerIndex) + .5f);
|
||||
|
||||
int deltaX = (int) (x - mLastMotionX);
|
||||
int deltaY = (int) (y - mLastMotionY);
|
||||
final int xDiff = Math.abs(deltaX);
|
||||
final int yDiff = Math.abs(deltaY);
|
||||
|
||||
if (mCaptureItem != null && !mDealByParent) {
|
||||
Mode touchMode = mCaptureItem.getTouchMode();
|
||||
|
||||
if (touchMode == Mode.TAP) {
|
||||
//如果capture item是open的,下拉有两种处理方式:
|
||||
// 1、下拉后,直接close item
|
||||
// 2、只要是open的,就拦截所有它的消息,这样如果点击open的,就只能滑动该capture item
|
||||
//网易邮箱,在open的情况下,下拉直接close
|
||||
//QQ,在open的情况下,下拉也是close。但是,做的不够好,没有达到该效果。
|
||||
if (xDiff > mTouchSlop && xDiff > yDiff) {
|
||||
mCaptureItem.setTouchMode(Mode.DRAG);
|
||||
final ViewParent parent = rv.getParent();
|
||||
parent.requestDisallowInterceptTouchEvent(true);
|
||||
|
||||
deltaX = deltaX > 0 ? deltaX - mTouchSlop : deltaX + mTouchSlop;
|
||||
} else {// if(yDiff>mTouchSlop){
|
||||
mIsProbeParent = true;
|
||||
boolean isParentConsume = rv.onInterceptTouchEvent(ev);
|
||||
mIsProbeParent = false;
|
||||
if (isParentConsume) {
|
||||
//表明不是水平滑动,即不判定为SwipeItemLayout的滑动
|
||||
//但是,可能是下拉刷新SwipeRefreshLayout或者RecyclerView的滑动
|
||||
//一般的下拉判定,都是yDiff>mTouchSlop,所以,此处这么写不会出问题
|
||||
//这里这么做以后,如果判定为下拉,就直接close
|
||||
mDealByParent = true;
|
||||
mCaptureItem.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
touchMode = mCaptureItem.getTouchMode();
|
||||
if (touchMode == Mode.DRAG) {
|
||||
intercept = true;
|
||||
mLastMotionX = x;
|
||||
mLastMotionY = y;
|
||||
|
||||
//对capture item进行拖拽
|
||||
mCaptureItem.trackMotionScroll(deltaX);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (mCaptureItem != null) {
|
||||
Mode touchMode = mCaptureItem.getTouchMode();
|
||||
if (touchMode == Mode.DRAG) {
|
||||
final VelocityTracker velocityTracker = mVelocityTracker;
|
||||
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
|
||||
int xVel = (int) velocityTracker.getXVelocity(mActivePointerId);
|
||||
mCaptureItem.fling(xVel);
|
||||
|
||||
intercept = true;
|
||||
}
|
||||
}
|
||||
cancel();
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (mCaptureItem != null)
|
||||
mCaptureItem.revise();
|
||||
cancel();
|
||||
break;
|
||||
}
|
||||
|
||||
return intercept;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTouchEvent(RecyclerView rv, MotionEvent ev) {
|
||||
final int action = ev.getActionMasked();
|
||||
final int actionIndex = ev.getActionIndex();
|
||||
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
mActivePointerId = ev.getPointerId(actionIndex);
|
||||
|
||||
mLastMotionX = ev.getX(actionIndex);
|
||||
mLastMotionY = ev.getY(actionIndex);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
final int pointerId = ev.getPointerId(actionIndex);
|
||||
if (pointerId == mActivePointerId) {
|
||||
final int newIndex = actionIndex == 0 ? 1 : 0;
|
||||
mActivePointerId = ev.getPointerId(newIndex);
|
||||
|
||||
mLastMotionX = ev.getX(newIndex);
|
||||
mLastMotionY = ev.getY(newIndex);
|
||||
}
|
||||
break;
|
||||
|
||||
//down时,已经将capture item定下来了。所以,后面可以安心考虑event处理
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
|
||||
if (activePointerIndex == -1)
|
||||
break;
|
||||
|
||||
final float x = ev.getX(activePointerIndex);
|
||||
final float y = (int) ev.getY(activePointerIndex);
|
||||
|
||||
int deltaX = (int) (x - mLastMotionX);
|
||||
|
||||
if (mCaptureItem != null && mCaptureItem.getTouchMode() == Mode.DRAG) {
|
||||
mLastMotionX = x;
|
||||
mLastMotionY = y;
|
||||
|
||||
//对capture item进行拖拽
|
||||
mCaptureItem.trackMotionScroll(deltaX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (mCaptureItem != null) {
|
||||
Mode touchMode = mCaptureItem.getTouchMode();
|
||||
if (touchMode == Mode.DRAG) {
|
||||
final VelocityTracker velocityTracker = mVelocityTracker;
|
||||
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
|
||||
int xVel = (int) velocityTracker.getXVelocity(mActivePointerId);
|
||||
mCaptureItem.fling(xVel);
|
||||
}
|
||||
}
|
||||
cancel();
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (mCaptureItem != null)
|
||||
mCaptureItem.revise();
|
||||
|
||||
cancel();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
mDealByParent = false;
|
||||
mActivePointerId = -1;
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static View findTopChildUnder(ViewGroup parent, int x, int y) {
|
||||
final int childCount = parent.getChildCount();
|
||||
for (int i = childCount - 1; i >= 0; i--) {
|
||||
final View child = parent.getChildAt(i);
|
||||
if (x >= child.getLeft() && x < child.getRight()
|
||||
&& y >= child.getTop() && y < child.getBottom()) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void closeAllItems(RecyclerView recyclerView) {
|
||||
for (int i = 0; i < recyclerView.getChildCount(); i++) {
|
||||
View child = recyclerView.getChildAt(i);
|
||||
if (child instanceof SwipeItemLayout) {
|
||||
SwipeItemLayout swipeItemLayout = (SwipeItemLayout) child;
|
||||
if (swipeItemLayout.isOpen())
|
||||
swipeItemLayout.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.mogo.eagle.core.function.notice.view.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;
|
||||
}
|
||||
@@ -1,631 +0,0 @@
|
||||
/*
|
||||
* 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.notice.view.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.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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,606 +0,0 @@
|
||||
/*
|
||||
* 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.notice.view.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.widget.ImageView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.DimenRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.function.notice.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 ImageView.ScaleType[] SCALE_TYPES = {
|
||||
ImageView.ScaleType.MATRIX,
|
||||
ImageView.ScaleType.FIT_XY,
|
||||
ImageView.ScaleType.FIT_START,
|
||||
ImageView.ScaleType.FIT_CENTER,
|
||||
ImageView.ScaleType.FIT_END,
|
||||
ImageView.ScaleType.CENTER,
|
||||
ImageView.ScaleType.CENTER_CROP,
|
||||
ImageView.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 ImageView.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(ImageView.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 ImageView.ScaleType getScaleType() {
|
||||
return mScaleType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleType(ImageView.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(ImageView.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) {
|
||||
CallerLogger.INSTANCE.w(TAG, "Unable to find resource: " + mResource + " , exception : " + 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) {
|
||||
CallerLogger.INSTANCE.w(TAG, "Unable to find resource: " + mBackgroundResource + " , exception : " + 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, ImageView.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, ImageView.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();
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 434 B |
|
Before Width: | Height: | Size: 589 B |
|
Before Width: | Height: | Size: 574 B |
|
Before Width: | Height: | Size: 434 B |
|
Before Width: | Height: | Size: 581 B |
|
Before Width: | Height: | Size: 574 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 434 B |
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/module_push_content_only_line_space" />
|
||||
<solid android:color="#222533" />
|
||||
</shape>
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape>
|
||||
<corners android:radius="@dimen/module_push_ui_decrease_timer_corner"/>
|
||||
<solid android:color="#7F000000"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/module_push_check_dialog_bg_color" />
|
||||
<corners android:radius="@dimen/module_push_dialog_check_bg_corner" />
|
||||
</shape>
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--<selector xmlns:android="http://schemas.android.com/apk/res/android">-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<gradient
|
||||
android:angle="135"
|
||||
android:endColor="#33000000"
|
||||
android:startColor="#33000000"
|
||||
android:type="linear" />
|
||||
<corners android:radius="@dimen/module_push_ui_bkg_corner" />
|
||||
</shape>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="@dimen/module_push_ui_bkg_corner" />
|
||||
<solid android:color="#F23F4057" />
|
||||
</shape>
|
||||
|
||||
|
Before Width: | Height: | Size: 583 B |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:fromDegrees="0"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:toDegrees="360">
|
||||
<shape
|
||||
android:innerRadius="@dimen/module_push_timer_inner_radius"
|
||||
android:shape="ring"
|
||||
android:thickness="@dimen/module_push_timer_thickness"
|
||||
android:useLevel="false">
|
||||
<gradient
|
||||
android:centerY="0.50"
|
||||
android:endColor="#001F7FFF"
|
||||
android:startColor="#7A8199"
|
||||
android:type="sweep"
|
||||
android:useLevel="false" />
|
||||
</shape>
|
||||
</rotate>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<dimen name="module_push_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_size">352dp</dimen>
|
||||
<dimen name="module_push_margin_start">32dp</dimen>
|
||||
<dimen name="module_push_app_icon_size">32dp</dimen>
|
||||
<dimen name="module_push_app_icon_margin_start">16.5dp</dimen>
|
||||
<dimen name="module_push_title_margin_start">12dp</dimen>
|
||||
<dimen name="module_push_title_margin_top">20dp</dimen>
|
||||
<dimen name="module_push_title_text_size">18dp</dimen>
|
||||
<dimen name="module_push_title_mix_width">210dp</dimen>
|
||||
<dimen name="module_push_timer_margin_end">13dp</dimen>
|
||||
<dimen name="module_push_timer_text_size">15dp</dimen>
|
||||
<dimen name="module_push_timer_margin_top">18dp</dimen>
|
||||
<dimen name="module_push_image_width">320dp</dimen>
|
||||
<dimen name="module_push_image_height">180dp</dimen>
|
||||
<dimen name="module_push_image_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_content_only_width">320dp</dimen>
|
||||
<dimen name="module_push_content_only_height">160dp</dimen>
|
||||
<dimen name="module_push_content_only_line_space">9dp</dimen>
|
||||
<dimen name="module_push_content_only_padding">20dp</dimen>
|
||||
<dimen name="module_push_button_width">0dp</dimen>
|
||||
<dimen name="module_push_button_height">48dp</dimen>
|
||||
<dimen name="module_push_button_margin_top">10dp</dimen>
|
||||
<dimen name="module_push_button_margin_bottom">14dp</dimen>
|
||||
<dimen name="module_push_activity_title_margin_top">28dp</dimen>
|
||||
<dimen name="module_push_activity_title_text_size">20dp</dimen>
|
||||
<dimen name="module_push_activity_close_margin_top">20dp</dimen>
|
||||
<dimen name="module_push_activity_close_margin_end">90dp</dimen>
|
||||
<dimen name="module_push_activity_close_padding">5dp</dimen>
|
||||
<dimen name="module_push_activity_recycler_view_margin_top">84dp</dimen>
|
||||
<dimen name="module_push_activity_not_data_text_size">38dp</dimen>
|
||||
<dimen name="module_push_activity_clear_margin_bottom">36dp</dimen>
|
||||
<dimen name="module_push_message_item_height">100dp</dimen>
|
||||
<dimen name="module_push_message_app_icon_size">64dp</dimen>
|
||||
<dimen name="module_push_message_margin_start">24dp</dimen>
|
||||
<dimen name="module_push_item_title_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_item_title_gone_margin_bottom">44dp</dimen>
|
||||
<dimen name="module_push_item_title_margin_bottom">2dp</dimen>
|
||||
<dimen name="module_push_item_content_margin_end">20dp</dimen>
|
||||
<dimen name="module_push_item_content_margin_bottom">27dp</dimen>
|
||||
<dimen name="module_push_item_content_text_size">16dp</dimen>
|
||||
<dimen name="module_push_message_item_image_size">64dp</dimen>
|
||||
<dimen name="module_push_message_item_image_margin_end">8dp</dimen>
|
||||
<dimen name="module_push_massage_time_text_size">16dp</dimen>
|
||||
|
||||
<dimen name="module_push_image_margin_bottom">22dp</dimen>
|
||||
<dimen name="module_push_button_radius">27dp</dimen>
|
||||
<dimen name="module_push_timer_inner_radius">14dp</dimen>
|
||||
<dimen name="module_push_timer_thickness">1.5dp</dimen>
|
||||
<dimen name="module_push_clear_bg_radius">24dp</dimen>
|
||||
<dimen name="module_push_image_radius">10dp</dimen>
|
||||
<dimen name="module_push_item_image_radius">8dp</dimen>
|
||||
<dimen name="module_push_item_content_width">560dp</dimen>
|
||||
<dimen name="module_push_ui_height">194dp</dimen>
|
||||
<dimen name="module_push_ui_image_width">266dp</dimen>
|
||||
<dimen name="module_push_ui_image_height">178dp</dimen>
|
||||
<dimen name="module_push_ui_image_marLeft">8dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin">12dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin">16dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_goneTopMargin">19dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_size">30dp</dimen>
|
||||
<dimen name="module_push_ui_title_textSize">16dp</dimen>
|
||||
<dimen name="module_push_ui_decrease_timer_corner">8dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginTop">17dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginEnd">19dp</dimen>
|
||||
<dimen name="module_push_ui_timer_textSize">16dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_padding">11dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop">6dp</dimen>
|
||||
<dimen name="module_push_ui_title_text_size">18dp</dimen>
|
||||
<dimen name="module_push_ui_button_radius">10dp</dimen>
|
||||
<dimen name="module_push_ui_bkg_corner">17dp</dimen>
|
||||
<dimen name="module_push_button_right_marLeft">10dp</dimen>
|
||||
<dimen name="module_push_ui_image_corner">8dp</dimen>
|
||||
<dimen name="module_push_button_maxWidth">242dp</dimen>
|
||||
<dimen name="module_push_ui_height_vertical">270dp</dimen>
|
||||
<dimen name="module_push_ui_width_vertical">374dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin_vertical">24dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin_vertical">19dp</dimen>
|
||||
<dimen name="module_push_image_marginTop_vertical">8dp</dimen>
|
||||
<dimen name="module_push_ui_image_width_vertical">328dp</dimen>
|
||||
<dimen name="module_push_ui_image_height_vertical">164dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop_vertical">15dp</dimen>
|
||||
<dimen name="module_push_image_qr_size_vertical">150dp</dimen>
|
||||
<dimen name="module_push_window_x">20dp</dimen>
|
||||
<dimen name="module_push_window_y">0dp</dimen>
|
||||
<dimen name="module_push_item_minHeight_vertical">310dp</dimen>
|
||||
<dimen name="module_push_item_maxHeight_vertical">350dp</dimen>
|
||||
<dimen name="module_push_content_paddingBottom_vertical">60dp</dimen>
|
||||
<dimen name="module_push_panel_marginTop">2dp</dimen>
|
||||
<dimen name="module_push_panel_marginBottom">2dp</dimen>
|
||||
<dimen name="module_push_panel_marginRight">8dp</dimen>
|
||||
<dimen name="module_push_panel_paddingLeft">28dp</dimen>
|
||||
<dimen name="module_push_panel_paddingBottom">16dp</dimen>
|
||||
<dimen name="module_push_panel_corner">16dp</dimen>
|
||||
<dimen name="module_push_panel_item_corner">12dp</dimen>
|
||||
<dimen name="module_push_item_time_textSize">5dp</dimen>
|
||||
<dimen name="module_push_item_image_width">118dp</dimen>
|
||||
<dimen name="module_push_item_image_height">86dp</dimen>
|
||||
<dimen name="module_push_panel_bkg_padding">8dp</dimen>
|
||||
</resources>
|
||||
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<dimen name="module_push_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_size">352dp</dimen>
|
||||
<dimen name="module_push_margin_start">32dp</dimen>
|
||||
<dimen name="module_push_app_icon_size">32dp</dimen>
|
||||
<dimen name="module_push_app_icon_margin_start">16.5dp</dimen>
|
||||
<dimen name="module_push_title_margin_start">12dp</dimen>
|
||||
<dimen name="module_push_title_margin_top">20dp</dimen>
|
||||
<dimen name="module_push_title_text_size">18dp</dimen>
|
||||
<dimen name="module_push_title_mix_width">210dp</dimen>
|
||||
<dimen name="module_push_timer_margin_end">13dp</dimen>
|
||||
<dimen name="module_push_timer_text_size">15dp</dimen>
|
||||
<dimen name="module_push_timer_margin_top">18dp</dimen>
|
||||
<dimen name="module_push_image_width">320dp</dimen>
|
||||
<dimen name="module_push_image_height">180dp</dimen>
|
||||
<dimen name="module_push_image_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_content_only_width">320dp</dimen>
|
||||
<dimen name="module_push_content_only_height">160dp</dimen>
|
||||
<dimen name="module_push_content_only_line_space">9dp</dimen>
|
||||
<dimen name="module_push_content_only_padding">20dp</dimen>
|
||||
<dimen name="module_push_button_width">0dp</dimen>
|
||||
<dimen name="module_push_button_height">48dp</dimen>
|
||||
<dimen name="module_push_button_margin_top">10dp</dimen>
|
||||
<dimen name="module_push_button_margin_bottom">14dp</dimen>
|
||||
<dimen name="module_push_activity_title_margin_top">28dp</dimen>
|
||||
<dimen name="module_push_activity_title_text_size">20dp</dimen>
|
||||
<dimen name="module_push_activity_close_margin_top">20dp</dimen>
|
||||
<dimen name="module_push_activity_close_margin_end">90dp</dimen>
|
||||
<dimen name="module_push_activity_close_padding">5dp</dimen>
|
||||
<dimen name="module_push_activity_recycler_view_margin_top">84dp</dimen>
|
||||
<dimen name="module_push_activity_not_data_text_size">38dp</dimen>
|
||||
<dimen name="module_push_activity_clear_margin_bottom">36dp</dimen>
|
||||
<dimen name="module_push_message_item_height">100dp</dimen>
|
||||
<dimen name="module_push_message_app_icon_size">64dp</dimen>
|
||||
<dimen name="module_push_message_margin_start">24dp</dimen>
|
||||
<dimen name="module_push_item_title_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_item_title_gone_margin_bottom">44dp</dimen>
|
||||
<dimen name="module_push_item_title_margin_bottom">2dp</dimen>
|
||||
<dimen name="module_push_item_content_margin_end">20dp</dimen>
|
||||
<dimen name="module_push_item_content_margin_bottom">27dp</dimen>
|
||||
<dimen name="module_push_item_content_text_size">16dp</dimen>
|
||||
<dimen name="module_push_message_item_image_size">64dp</dimen>
|
||||
<dimen name="module_push_message_item_image_margin_end">8dp</dimen>
|
||||
<dimen name="module_push_massage_time_text_size">16dp</dimen>
|
||||
|
||||
<dimen name="module_push_image_margin_bottom">22dp</dimen>
|
||||
<dimen name="module_push_button_radius">27dp</dimen>
|
||||
<dimen name="module_push_timer_inner_radius">14dp</dimen>
|
||||
<dimen name="module_push_timer_thickness">1.5dp</dimen>
|
||||
<dimen name="module_push_clear_bg_radius">24dp</dimen>
|
||||
<dimen name="module_push_image_radius">10dp</dimen>
|
||||
<dimen name="module_push_item_image_radius">8dp</dimen>
|
||||
<dimen name="module_push_item_content_width">560dp</dimen>
|
||||
<dimen name="module_push_ui_height">194dp</dimen>
|
||||
<dimen name="module_push_ui_image_width">266dp</dimen>
|
||||
<dimen name="module_push_ui_image_height">178dp</dimen>
|
||||
<dimen name="module_push_ui_image_marLeft">8dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin">12dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin">16dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_goneTopMargin">19dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_size">30dp</dimen>
|
||||
<dimen name="module_push_ui_title_textSize">16dp</dimen>
|
||||
<dimen name="module_push_ui_decrease_timer_corner">8dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginTop">17dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginEnd">19dp</dimen>
|
||||
<dimen name="module_push_ui_timer_textSize">16dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_padding">11dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop">6dp</dimen>
|
||||
<dimen name="module_push_ui_title_text_size">18dp</dimen>
|
||||
<dimen name="module_push_ui_button_radius">10dp</dimen>
|
||||
<dimen name="module_push_ui_bkg_corner">17dp</dimen>
|
||||
<dimen name="module_push_button_right_marLeft">10dp</dimen>
|
||||
<dimen name="module_push_ui_image_corner">8dp</dimen>
|
||||
<dimen name="module_push_button_maxWidth">242dp</dimen>
|
||||
<dimen name="module_push_ui_height_vertical">270dp</dimen>
|
||||
<dimen name="module_push_ui_width_vertical">374dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin_vertical">24dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin_vertical">19dp</dimen>
|
||||
<dimen name="module_push_image_marginTop_vertical">8dp</dimen>
|
||||
<dimen name="module_push_ui_image_width_vertical">328dp</dimen>
|
||||
<dimen name="module_push_ui_image_height_vertical">164dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop_vertical">15dp</dimen>
|
||||
<dimen name="module_push_image_qr_size_vertical">150dp</dimen>
|
||||
<dimen name="module_push_window_x">20dp</dimen>
|
||||
<dimen name="module_push_window_y">0dp</dimen>
|
||||
<dimen name="module_push_item_minHeight_vertical">310dp</dimen>
|
||||
<dimen name="module_push_item_maxHeight_vertical">350dp</dimen>
|
||||
<dimen name="module_push_content_paddingBottom_vertical">60dp</dimen>
|
||||
<dimen name="module_push_panel_marginTop">2dp</dimen>
|
||||
<dimen name="module_push_panel_marginBottom">2dp</dimen>
|
||||
<dimen name="module_push_panel_marginRight">8dp</dimen>
|
||||
<dimen name="module_push_panel_paddingLeft">28dp</dimen>
|
||||
<dimen name="module_push_panel_paddingBottom">16dp</dimen>
|
||||
<dimen name="module_push_panel_corner">16dp</dimen>
|
||||
<dimen name="module_push_panel_item_corner">12dp</dimen>
|
||||
<dimen name="module_push_item_time_textSize">5dp</dimen>
|
||||
<dimen name="module_push_item_image_width">118dp</dimen>
|
||||
<dimen name="module_push_item_image_height">86dp</dimen>
|
||||
<dimen name="module_push_panel_bkg_padding">8dp</dimen>
|
||||
</resources>
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
|
||||
<dimen name="module_push_ui_height">230dp</dimen>
|
||||
<dimen name="module_push_ui_image_width">230dp</dimen>
|
||||
<dimen name="module_push_ui_image_height">230dp</dimen>
|
||||
<dimen name="module_push_ui_image_corner">30dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin">21dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin">34dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_goneTopMargin">33dp</dimen>
|
||||
<dimen name="module_push_line_width">2dp</dimen>
|
||||
<dimen name="module_push_line_height">120dp</dimen>
|
||||
<dimen name="module_push_line_margin_left">30dp</dimen>
|
||||
<dimen name="module_push_check_margin">55dp</dimen>
|
||||
<dimen name="module_push_check_text_size">42dp</dimen>
|
||||
<dimen name="module_push_check_width">208dp</dimen>
|
||||
<dimen name="module_push_title_mix_width">394dp</dimen>
|
||||
<dimen name="module_push_ui_title_textSize">42dp</dimen>
|
||||
<dimen name="module_push_ui_content_width">567dp</dimen>
|
||||
<dimen name="module_push_ui_content_height">100dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop">20dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginBottom">34dp</dimen>
|
||||
<dimen name="module_push_ui_title_text_size">34dp</dimen>
|
||||
|
||||
|
||||
<dimen name="module_push_dialog_check_width">1200dp</dimen>
|
||||
<dimen name="module_push_dialog_check_height">763dp</dimen>
|
||||
<dimen name="module_push_dialog_check_bg_corner">32dp</dimen>
|
||||
<dimen name="module_push_dialog_close_width">107dp</dimen>
|
||||
<dimen name="module_push_dialog_close_height">107dp</dimen>
|
||||
<dimen name="module_push_dialog_close_margin">40dp</dimen>
|
||||
<dimen name="module_push_dialog_title_margin">54dp</dimen>
|
||||
<dimen name="module_push_dialog_title_size">56dp</dimen>
|
||||
<dimen name="module_push_dialog_content_width">1000dp</dimen>
|
||||
<dimen name="module_push_dialog_content_margin_top">33dp</dimen>
|
||||
<dimen name="module_push_dialog_content_size">43dp</dimen>
|
||||
<dimen name="module_push_ui_margin_top">20dp</dimen>
|
||||
|
||||
</resources>
|
||||
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<dimen name="module_push_margin_top">30dp</dimen>
|
||||
<dimen name="module_push_size">660dp</dimen>
|
||||
<dimen name="module_push_margin_start">60dp</dimen>
|
||||
<dimen name="module_push_app_icon_size">60dp</dimen>
|
||||
<dimen name="module_push_app_icon_margin_start">31dp</dimen>
|
||||
<dimen name="module_push_title_margin_start">22dp</dimen>
|
||||
<dimen name="module_push_title_margin_top">38dp</dimen>
|
||||
<dimen name="module_push_title_text_size">32dp</dimen>
|
||||
<dimen name="module_push_title_mix_width">394dp</dimen>
|
||||
<dimen name="module_push_timer_margin_end">24dp</dimen>
|
||||
<dimen name="module_push_timer_text_size">28dp</dimen>
|
||||
<dimen name="module_push_timer_margin_top">34dp</dimen>
|
||||
<dimen name="module_push_image_width">600dp</dimen>
|
||||
<dimen name="module_push_image_height">338dp</dimen>
|
||||
<dimen name="module_push_image_margin_top">30dp</dimen>
|
||||
<dimen name="module_push_content_only_width">605dp</dimen>
|
||||
<dimen name="module_push_content_only_height">300dp</dimen>
|
||||
<dimen name="module_push_content_only_line_space">16dp</dimen>
|
||||
<dimen name="module_push_content_only_padding">53dp</dimen>
|
||||
<dimen name="module_push_button_width">0dp</dimen>
|
||||
<dimen name="module_push_button_height">90dp</dimen>
|
||||
<dimen name="module_push_button_margin_top">20dp</dimen>
|
||||
<dimen name="module_push_button_margin_bottom">26dp</dimen>
|
||||
<dimen name="module_push_activity_title_margin_top">50dp</dimen>
|
||||
<dimen name="module_push_activity_title_text_size">36dp</dimen>
|
||||
<dimen name="module_push_activity_close_margin_top">36dp</dimen>
|
||||
<dimen name="module_push_activity_close_margin_end">160dp</dimen>
|
||||
<dimen name="module_push_activity_close_padding">10dp</dimen>
|
||||
<dimen name="module_push_activity_recycler_view_margin_top">151dp</dimen>
|
||||
<dimen name="module_push_activity_not_data_text_size">72dp</dimen>
|
||||
<dimen name="module_push_activity_clear_margin_bottom">68dp</dimen>
|
||||
<dimen name="module_push_message_item_height">180dp</dimen>
|
||||
<dimen name="module_push_message_app_icon_size">120dp</dimen>
|
||||
<dimen name="module_push_message_margin_start">50dp</dimen>
|
||||
<dimen name="module_push_item_title_margin_top">22dp</dimen>
|
||||
<dimen name="module_push_item_title_margin_bottom">6dp</dimen>
|
||||
<dimen name="module_push_item_title_gone_margin_bottom">84dp</dimen>
|
||||
|
||||
<dimen name="module_push_item_content_margin_end">40dp</dimen>
|
||||
<dimen name="module_push_item_content_margin_bottom">52dp</dimen>
|
||||
<dimen name="module_push_item_content_text_size">28dp</dimen>
|
||||
<dimen name="module_push_message_item_image_size">120dp</dimen>
|
||||
<dimen name="module_push_message_item_image_margin_end">11dp</dimen>
|
||||
<dimen name="module_push_massage_time_text_size">26dp</dimen>
|
||||
<dimen name="module_push_image_margin_bottom">42dp</dimen>
|
||||
<dimen name="module_push_button_radius">51dp</dimen>
|
||||
<dimen name="module_push_timer_inner_radius">27dp</dimen>
|
||||
<dimen name="module_push_timer_thickness">3dp</dimen>
|
||||
<dimen name="module_push_clear_bg_radius">45dp</dimen>
|
||||
<dimen name="module_push_image_radius">20dp</dimen>
|
||||
<dimen name="module_push_item_image_radius">16dp</dimen>
|
||||
<dimen name="module_push_item_content_width">1000dp</dimen>
|
||||
<dimen name="module_push_ui_height">350dp</dimen>
|
||||
<dimen name="module_push_ui_image_width">480dp</dimen>
|
||||
<dimen name="module_push_ui_image_height">320dp</dimen>
|
||||
<dimen name="module_push_ui_image_marLeft">17dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin">21dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin">30dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_goneTopMargin">33dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_size">50dp</dimen>
|
||||
<dimen name="module_push_ui_title_textSize">30dp</dimen>
|
||||
<dimen name="module_push_ui_decrease_timer_corner">14dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginTop">30dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginEnd">27dp</dimen>
|
||||
<dimen name="module_push_ui_timer_textSize">30dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_padding">21dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop">11dp</dimen>
|
||||
<dimen name="module_push_ui_title_text_size">34dp</dimen>
|
||||
<dimen name="module_push_ui_button_radius">20dp</dimen>
|
||||
<dimen name="module_push_ui_bkg_corner">30dp</dimen>
|
||||
<dimen name="module_push_button_right_marLeft">20dp</dimen>
|
||||
<dimen name="module_push_ui_image_corner">15dp</dimen>
|
||||
<dimen name="module_push_button_maxWidth">242dp</dimen>
|
||||
<dimen name="module_push_ui_height_vertical">486dp</dimen>
|
||||
<dimen name="module_push_ui_width_vertical">700dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin_vertical">30dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin_vertical">33dp</dimen>
|
||||
<dimen name="module_push_image_marginTop_vertical">16dp</dimen>
|
||||
<dimen name="module_push_ui_image_width_vertical">640dp</dimen>
|
||||
<dimen name="module_push_ui_image_height_vertical">296dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop_vertical">30dp</dimen>
|
||||
<dimen name="module_push_image_qr_size_vertical">250dp</dimen>
|
||||
<dimen name="module_push_window_x">20dp</dimen>
|
||||
<dimen name="module_push_window_y">0dp</dimen>
|
||||
<dimen name="module_push_item_minHeight_vertical">618dp</dimen>
|
||||
<dimen name="module_push_item_maxHeight_vertical">350dp</dimen>
|
||||
<dimen name="module_push_content_paddingBottom_vertical">120dp</dimen>
|
||||
<dimen name="module_push_panel_marginTop">20dp</dimen>
|
||||
<dimen name="module_push_panel_marginBottom">20dp</dimen>
|
||||
<dimen name="module_push_panel_marginRight">20dp</dimen>
|
||||
<dimen name="module_push_panel_paddingLeft">50dp</dimen>
|
||||
<dimen name="module_push_panel_paddingBottom">28dp</dimen>
|
||||
<dimen name="module_push_panel_corner">29dp</dimen>
|
||||
<dimen name="module_push_panel_item_corner">22dp</dimen>
|
||||
<dimen name="module_push_item_time_textSize">11dp</dimen>
|
||||
<dimen name="module_push_item_image_width">212dp</dimen>
|
||||
<dimen name="module_push_item_image_height">154dp</dimen>
|
||||
<dimen name="module_push_panel_bkg_padding">10dp</dimen>
|
||||
</resources>
|
||||
@@ -1,30 +0,0 @@
|
||||
<?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>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="module_push_panel_title_textColor">#FFFFFFFF</color>
|
||||
<color name="module_push_item_title_textColor">#FFFFFF</color>
|
||||
<color name="module_push_item_content_textColor">#B2FFFFFF</color>
|
||||
<color name="module_push_item_time_textColor">#999999</color>
|
||||
<color name="module_push_item_line_color">#B3FFFFFF</color>
|
||||
<color name="module_push_check_color">#5A8EFD</color>
|
||||
<color name="module_push_check_dialog_bg_color">#E63B4577</color>
|
||||
</resources>
|
||||
@@ -1,126 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<dimen name="module_push_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_size">352dp</dimen>
|
||||
<dimen name="module_push_margin_start">32dp</dimen>
|
||||
<dimen name="module_push_app_icon_size">32dp</dimen>
|
||||
<dimen name="module_push_app_icon_margin_start">16.5dp</dimen>
|
||||
<dimen name="module_push_title_margin_start">12dp</dimen>
|
||||
<dimen name="module_push_title_margin_top">20dp</dimen>
|
||||
<dimen name="module_push_title_text_size">18dp</dimen>
|
||||
<dimen name="module_push_title_mix_width">210dp</dimen>
|
||||
<dimen name="module_push_timer_margin_end">13dp</dimen>
|
||||
<dimen name="module_push_timer_text_size">15dp</dimen>
|
||||
<dimen name="module_push_timer_margin_top">18dp</dimen>
|
||||
<dimen name="module_push_image_width">320dp</dimen>
|
||||
<dimen name="module_push_image_height">180dp</dimen>
|
||||
<dimen name="module_push_image_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_content_only_width">320dp</dimen>
|
||||
<dimen name="module_push_content_only_height">160dp</dimen>
|
||||
<dimen name="module_push_content_only_line_space">9dp</dimen>
|
||||
<dimen name="module_push_content_only_padding">20dp</dimen>
|
||||
<dimen name="module_push_button_width">0dp</dimen>
|
||||
<dimen name="module_push_button_height">48dp</dimen>
|
||||
<dimen name="module_push_button_margin_top">10dp</dimen>
|
||||
<dimen name="module_push_button_margin_bottom">14dp</dimen>
|
||||
<dimen name="module_push_activity_title_margin_top">50dp</dimen>
|
||||
<dimen name="module_push_activity_title_text_size">20dp</dimen>
|
||||
<dimen name="module_push_activity_close_margin_top">20dp</dimen>
|
||||
<dimen name="module_push_activity_close_margin_end">90dp</dimen>
|
||||
<dimen name="module_push_activity_close_padding">5dp</dimen>
|
||||
<dimen name="module_push_activity_recycler_view_margin_top">84dp</dimen>
|
||||
<dimen name="module_push_activity_not_data_text_size">38dp</dimen>
|
||||
<dimen name="module_push_activity_clear_margin_bottom">36dp</dimen>
|
||||
<dimen name="module_push_message_item_height">100dp</dimen>
|
||||
<dimen name="module_push_message_app_icon_size">64dp</dimen>
|
||||
<dimen name="module_push_message_margin_start">24dp</dimen>
|
||||
<dimen name="module_push_item_title_margin_top">16dp</dimen>
|
||||
<dimen name="module_push_item_title_gone_margin_bottom">44dp</dimen>
|
||||
<dimen name="module_push_item_title_margin_bottom">2dp</dimen>
|
||||
<dimen name="module_push_item_content_margin_end">20dp</dimen>
|
||||
<dimen name="module_push_item_content_margin_bottom">27dp</dimen>
|
||||
<dimen name="module_push_item_content_text_size">16dp</dimen>
|
||||
<dimen name="module_push_message_item_image_size">64dp</dimen>
|
||||
<dimen name="module_push_message_item_image_margin_end">8dp</dimen>
|
||||
<dimen name="module_push_massage_time_text_size">16dp</dimen>
|
||||
|
||||
<dimen name="module_push_image_margin_bottom">22dp</dimen>
|
||||
<dimen name="module_push_button_radius">27dp</dimen>
|
||||
<dimen name="module_push_timer_inner_radius">14dp</dimen>
|
||||
<dimen name="module_push_timer_thickness">1.5dp</dimen>
|
||||
<dimen name="module_push_clear_bg_radius">24dp</dimen>
|
||||
<dimen name="module_push_image_radius">10dp</dimen>
|
||||
<dimen name="module_push_item_image_radius">8dp</dimen>
|
||||
<dimen name="module_push_item_content_width">560dp</dimen>
|
||||
<dimen name="module_push_ui_height">194dp</dimen>
|
||||
<dimen name="module_push_ui_image_width">266dp</dimen>
|
||||
<dimen name="module_push_ui_image_height">178dp</dimen>
|
||||
<dimen name="module_push_ui_image_marLeft">8dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin">12dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin">16dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_goneTopMargin">19dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_size">30dp</dimen>
|
||||
<dimen name="module_push_ui_title_textSize">16dp</dimen>
|
||||
<dimen name="module_push_ui_decrease_timer_corner">8dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginTop">17dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_marginEnd">19dp</dimen>
|
||||
<dimen name="module_push_ui_timer_textSize">16dp</dimen>
|
||||
<dimen name="module_push_progress_bar_frame_padding">11dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop">6dp</dimen>
|
||||
<dimen name="module_push_ui_title_text_size">18dp</dimen>
|
||||
<dimen name="module_push_ui_button_radius">10dp</dimen>
|
||||
<dimen name="module_push_ui_bkg_corner">17dp</dimen>
|
||||
<dimen name="module_push_button_right_marLeft">10dp</dimen>
|
||||
<dimen name="module_push_ui_image_corner">8dp</dimen>
|
||||
<dimen name="module_push_button_maxWidth">242dp</dimen>
|
||||
<dimen name="module_push_ui_height_vertical">270dp</dimen>
|
||||
<dimen name="module_push_ui_width_vertical">374dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_leftMargin_vertical">24dp</dimen>
|
||||
<dimen name="module_push_ui_app_icon_topMargin_vertical">19dp</dimen>
|
||||
<dimen name="module_push_image_marginTop_vertical">8dp</dimen>
|
||||
<dimen name="module_push_ui_image_width_vertical">328dp</dimen>
|
||||
<dimen name="module_push_ui_image_height_vertical">164dp</dimen>
|
||||
<dimen name="module_push_ui_content_marginTop_vertical">15dp</dimen>
|
||||
<dimen name="module_push_image_qr_size_vertical">150dp</dimen>
|
||||
<dimen name="module_push_window_x">20dp</dimen>
|
||||
<dimen name="module_push_window_y">0dp</dimen>
|
||||
<dimen name="module_push_item_minHeight_vertical">310dp</dimen>
|
||||
<dimen name="module_push_item_maxHeight_vertical">350dp</dimen>
|
||||
<dimen name="module_push_content_paddingBottom_vertical">60dp</dimen>
|
||||
<dimen name="module_push_panel_marginTop">2dp</dimen>
|
||||
<dimen name="module_push_panel_marginBottom">2dp</dimen>
|
||||
<dimen name="module_push_panel_marginRight">8dp</dimen>
|
||||
<dimen name="module_push_panel_paddingLeft">28dp</dimen>
|
||||
<dimen name="module_push_panel_paddingBottom">16dp</dimen>
|
||||
<dimen name="module_push_panel_corner">16dp</dimen>
|
||||
<dimen name="module_push_panel_item_corner">12dp</dimen>
|
||||
<dimen name="module_push_item_time_textSize">5dp</dimen>
|
||||
<dimen name="module_push_item_image_width">118dp</dimen>
|
||||
<dimen name="module_push_item_image_height">86dp</dimen>
|
||||
<dimen name="module_push_panel_bkg_padding">8dp</dimen>
|
||||
|
||||
|
||||
<dimen name="module_push_ui_content_marginBottom">34dp</dimen>
|
||||
<dimen name="module_push_ui_content_width">567dp</dimen>
|
||||
<dimen name="module_push_ui_content_height">100dp</dimen>
|
||||
|
||||
<dimen name="module_push_line_width">2dp</dimen>
|
||||
<dimen name="module_push_line_height">120dp</dimen>
|
||||
<dimen name="module_push_line_margin_left">30dp</dimen>
|
||||
<dimen name="module_push_check_margin">55dp</dimen>
|
||||
<dimen name="module_push_check_text_size">42dp</dimen>
|
||||
<dimen name="module_push_check_width">208dp</dimen>
|
||||
|
||||
<dimen name="module_push_dialog_check_width">1200dp</dimen>
|
||||
<dimen name="module_push_dialog_check_height">763dp</dimen>
|
||||
<dimen name="module_push_dialog_check_bg_corner">32dp</dimen>
|
||||
<dimen name="module_push_dialog_close_width">107dp</dimen>
|
||||
<dimen name="module_push_dialog_close_height">107dp</dimen>
|
||||
<dimen name="module_push_dialog_close_margin">40dp</dimen>
|
||||
<dimen name="module_push_dialog_title_margin">54dp</dimen>
|
||||
<dimen name="module_push_dialog_title_size">56dp</dimen>
|
||||
<dimen name="module_push_dialog_content_width">1000dp</dimen>
|
||||
<dimen name="module_push_dialog_content_margin_top">33dp</dimen>
|
||||
<dimen name="module_push_dialog_content_size">43dp</dimen>
|
||||
<dimen name="module_push_ui_margin_top">20dp</dimen>
|
||||
</resources>
|
||||
@@ -1,7 +0,0 @@
|
||||
<resources>
|
||||
<string name="app_name">mogo-core-function-notice</string>
|
||||
<string name="module_push_str_delete">清除</string>
|
||||
<string name="module_push_str_clear">清空历史消息</string>
|
||||
<string name="module_push_str_not_data">暂无消息</string>
|
||||
<string name="module_push_check">查看</string>
|
||||
</resources>
|
||||
@@ -1,9 +0,0 @@
|
||||
<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>
|
||||
@@ -102,7 +102,6 @@ MOGO_CORE_FUNCTION_HMI_VERSION=0.0.58.10
|
||||
MOGO_CORE_FUNCTION_MAIN_VERSION=0.0.58.10
|
||||
MOGO_CORE_FUNCTION_MAP_VERSION=0.0.58.10
|
||||
MOGO_CORE_FUNCTION_MONITORING_VERSION=0.0.58.10
|
||||
MOGO_CORE_FUNCTION_NOTICE_VERSION=0.0.58.10
|
||||
MOGO_CORE_FUNCTION_OBU_MOGO_VERSION=0.0.58.10
|
||||
MOGO_CORE_FUNCTION_SMP_VERSION=0.0.58.10
|
||||
MOGO_CORE_FUNCTION_V2X_VERSION=0.0.58.10
|
||||
|
||||
@@ -23,10 +23,8 @@
|
||||
:core:function-impl:mogo-core-function-hmi
|
||||
:core:function-impl:mogo-core-function-map
|
||||
:core:function-impl:mogo-core-function-monitoring
|
||||
:core:function-impl:mogo-core-function-notice
|
||||
:core:function-impl:mogo-core-function-v2x
|
||||
:core:function-impl:mogo-core-function-dispatch
|
||||
:core:function-impl:mogo-core-function-chat
|
||||
:core:function-impl:mogo-core-function-devatools
|
||||
:core:function-impl:mogo-core-function-main
|
||||
:core:function-impl:mogo-core-function-bindingcar
|
||||
@@ -17,10 +17,8 @@ include ':core:mogo-core-network'
|
||||
include ':core:mogo-core-function-api'
|
||||
// 模块对外暴露等调用接口
|
||||
include ':core:mogo-core-function-call'
|
||||
|
||||
// deva开发工具套件
|
||||
include ':core:function-impl:mogo-core-function-devatools'
|
||||
|
||||
// 业务实现
|
||||
// UI 展示及交互
|
||||
// Main 应用主入口封装,在这里进行初始化应用
|
||||
@@ -32,8 +30,6 @@ include ':core:function-impl:mogo-core-function-map'
|
||||
include ':core:function-impl:mogo-core-function-v2x'
|
||||
// 自研OBU业务
|
||||
include ':core:function-impl:mogo-core-function-obu-mogo'
|
||||
// 云公告相关的业务,UI写到HMI,这里只处理数据及功能逻辑
|
||||
include ':core:function-impl:mogo-core-function-notice'
|
||||
// 自动驾驶相关能力,控制自动驾驶,获取自动驾驶识别信息,自车感知预警等
|
||||
include ':core:function-impl:mogo-core-function-autopilot'
|
||||
// 行车超视距服务,路测摄像头、前车摄像头
|
||||
@@ -44,6 +40,8 @@ include ':core:function-impl:mogo-core-function-dispatch'
|
||||
include ':core:function-impl:mogo-core-function-bindingcar'
|
||||
// 车聊聊业务
|
||||
include ':core:function-impl:mogo-core-function-chat'
|
||||
// 业务biz
|
||||
include ':core:function-impl:mogo-core-function-biz'
|
||||
// 消息盒子
|
||||
include ':core:function-impl:mogo-core-function-datacenter'
|
||||
|
||||
@@ -77,3 +75,4 @@ include ':OCH:mogo-och-taxi-passenger'
|
||||
include ':OCH:mogo-och-noop'
|
||||
include(':OCH:mogo-och-common-module')
|
||||
include ':OCH:mogo-och-sweeper'
|
||||
include ':mogo-core-function-biz'
|
||||
|
||||