From 1d1fb747fc939c7c5c12ade539e594f567f8159d Mon Sep 17 00:00:00 2001
From: pppscn <35696959@qq.com>
Date: Sun, 3 Dec 2023 22:55:09 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E8=87=AA=E5=8A=A8?=
=?UTF-8?q?=E4=BB=BB=E5=8A=A1=C2=B7=E5=BF=AB=E6=8D=B7=E6=8C=87=E4=BB=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/src/main/AndroidManifest.xml | 18 +-
.../sms/forwarder/activity/TaskActivity.kt | 14 +
.../forwarder/adapter/TaskSettingAdapter.kt | 132 +++++++
.../adapter/spinner/ActionAdapterItem.kt | 92 -----
.../adapter/spinner/ConditionAdapterItem.kt | 92 -----
.../sms/forwarder/entity/task/TaskSetting.kt | 18 +-
.../forwarder/fragment/TasksEditFragment.kt | 322 +++++++++++-------
.../fragment/condition/CronFragment.kt | 4 +-
.../idormy/sms/forwarder/utils/Constants.kt | 14 +-
.../res/layout/adapter_task_setting_item.xml | 8 +-
.../main/res/layout/fragment_tasks_edit.xml | 12 +-
app/src/main/res/layout/item_add_action.xml | 68 ----
.../main/res/layout/item_add_condition.xml | 68 ----
app/src/main/res/values/dimens.xml | 4 +-
14 files changed, 393 insertions(+), 473 deletions(-)
create mode 100644 app/src/main/java/com/idormy/sms/forwarder/activity/TaskActivity.kt
create mode 100644 app/src/main/java/com/idormy/sms/forwarder/adapter/TaskSettingAdapter.kt
delete mode 100644 app/src/main/java/com/idormy/sms/forwarder/adapter/spinner/ActionAdapterItem.kt
delete mode 100644 app/src/main/java/com/idormy/sms/forwarder/adapter/spinner/ConditionAdapterItem.kt
delete mode 100644 app/src/main/res/layout/item_add_action.xml
delete mode 100644 app/src/main/res/layout/item_add_condition.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3a26f9ff..ebc18951 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -62,11 +62,12 @@
-
-
-
-
+
+
+
+
+
@@ -280,6 +289,7 @@
+
\ No newline at end of file
diff --git a/app/src/main/java/com/idormy/sms/forwarder/activity/TaskActivity.kt b/app/src/main/java/com/idormy/sms/forwarder/activity/TaskActivity.kt
new file mode 100644
index 00000000..b0fad2b6
--- /dev/null
+++ b/app/src/main/java/com/idormy/sms/forwarder/activity/TaskActivity.kt
@@ -0,0 +1,14 @@
+package com.idormy.sms.forwarder.activity
+
+import android.os.Bundle
+import androidx.viewbinding.ViewBinding
+import com.idormy.sms.forwarder.core.BaseActivity
+import com.idormy.sms.forwarder.fragment.TasksEditFragment
+
+class TaskActivity : BaseActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ openPage(TasksEditFragment::class.java)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/TaskSettingAdapter.kt b/app/src/main/java/com/idormy/sms/forwarder/adapter/TaskSettingAdapter.kt
new file mode 100644
index 00000000..0f7a93f0
--- /dev/null
+++ b/app/src/main/java/com/idormy/sms/forwarder/adapter/TaskSettingAdapter.kt
@@ -0,0 +1,132 @@
+@file:Suppress("DEPRECATION")
+
+package com.idormy.sms.forwarder.adapter
+
+import android.annotation.SuppressLint
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.ItemTouchHelper
+import androidx.recyclerview.widget.RecyclerView
+import com.idormy.sms.forwarder.R
+import com.idormy.sms.forwarder.entity.task.TaskSetting
+
+class TaskSettingAdapter(
+ val itemList: MutableList,
+ private val editClickListener: (Int) -> Unit,
+ private val removeClickListener: (Int) -> Unit
+) : RecyclerView.Adapter(), ItemMoveCallback.Listener {
+
+ private lateinit var touchHelper: ItemTouchHelper
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.adapter_task_setting_item, parent, false)
+ return ViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val item = itemList[position]
+ holder.bind(item)
+ }
+
+ override fun getItemCount(): Int = itemList.size
+
+ fun setTouchHelper(touchHelper: ItemTouchHelper) {
+ this@TaskSettingAdapter.touchHelper = touchHelper
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
+ private val icon: ImageView = itemView.findViewById(R.id.iv_icon)
+ private val title: TextView = itemView.findViewById(R.id.tv_title)
+ private val description: TextView = itemView.findViewById(R.id.tv_description)
+ private val editIcon: ImageView = itemView.findViewById(R.id.iv_edit)
+ private val removeIcon: ImageView = itemView.findViewById(R.id.iv_remove)
+ private val dragIcon: ImageView = itemView.findViewById(R.id.iv_drag)
+
+ init {
+ editIcon.setOnClickListener(this)
+ removeIcon.setOnClickListener(this)
+
+ dragIcon.setOnTouchListener { _, event ->
+ if (event.actionMasked == MotionEvent.ACTION_DOWN) {
+ touchHelper.startDrag(this)
+ }
+ return@setOnTouchListener false
+ }
+ }
+
+ fun bind(taskSetting: TaskSetting) {
+ icon.setImageResource(taskSetting.iconId)
+ title.text = taskSetting.title
+ description.text = taskSetting.description
+ }
+
+ override fun onClick(v: View?) {
+ val position = adapterPosition
+ if (position != RecyclerView.NO_POSITION) {
+ when (v?.id) {
+ R.id.iv_edit -> editClickListener(position)
+ R.id.iv_remove -> removeClickListener(position)
+ }
+ }
+ }
+ }
+
+ override fun onItemMove(fromPosition: Int, toPosition: Int) {
+ if (fromPosition < toPosition) {
+ for (i in fromPosition until toPosition) {
+ itemList[i] = itemList.set(i + 1, itemList[i])
+ }
+ } else {
+ for (i in fromPosition downTo toPosition + 1) {
+ itemList[i] = itemList.set(i - 1, itemList[i])
+ }
+ }
+ notifyItemMoved(fromPosition, toPosition)
+ }
+
+ override fun onDragFinished() {
+ TODO("Not yet implemented")
+ }
+}
+
+class ItemMoveCallback(private val listener: Listener) : ItemTouchHelper.Callback() {
+
+ interface Listener {
+ fun onItemMove(fromPosition: Int, toPosition: Int)
+ fun onDragFinished()
+ }
+
+ override fun getMovementFlags(
+ recyclerView: RecyclerView,
+ viewHolder: RecyclerView.ViewHolder
+ ): Int {
+ val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
+ return makeMovementFlags(dragFlags, 0)
+ }
+
+ override fun onMove(
+ recyclerView: RecyclerView,
+ viewHolder: RecyclerView.ViewHolder,
+ target: RecyclerView.ViewHolder
+ ): Boolean {
+ listener.onItemMove(viewHolder.adapterPosition, target.adapterPosition)
+ return true
+ }
+
+ override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
+ // Swiping is not needed for this example
+ }
+
+ override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
+ super.onSelectedChanged(viewHolder, actionState)
+ if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) {
+ listener.onDragFinished()
+ }
+ }
+}
diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/spinner/ActionAdapterItem.kt b/app/src/main/java/com/idormy/sms/forwarder/adapter/spinner/ActionAdapterItem.kt
deleted file mode 100644
index c3fd14b5..00000000
--- a/app/src/main/java/com/idormy/sms/forwarder/adapter/spinner/ActionAdapterItem.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.idormy.sms.forwarder.adapter.spinner
-
-import android.content.Context
-import android.graphics.drawable.Drawable
-import com.xuexiang.xui.utils.ResUtils
-
-@Suppress("unused")
-class ActionAdapterItem {
-
- //标题内容
- var title: CharSequence
-
- //图标
- var icon: Drawable? = null
-
- //ID
- var id: Long? = 0L
-
- //状态
- var status: Int? = 1
-
- constructor(title: CharSequence) {
- this.title = title
- }
-
- constructor(title: CharSequence, icon: Drawable?) {
- this.title = title
- this.icon = icon
- }
-
- constructor(title: CharSequence, icon: Drawable?, id: Long?) {
- this.title = title
- this.icon = icon
- this.id = id
- }
-
- constructor(title: CharSequence, icon: Drawable?, id: Long?, status: Int?) {
- this.title = title
- this.icon = icon
- this.id = id
- this.status = status
- }
-
- constructor(title: CharSequence, drawableId: Int) : this(title, ResUtils.getDrawable(drawableId))
- constructor(title: CharSequence, drawableId: Int, id: Long) : this(title, ResUtils.getDrawable(drawableId), id)
- constructor(title: CharSequence, drawableId: Int, id: Long, status: Int) : this(title, ResUtils.getDrawable(drawableId), id, status)
- constructor(context: Context?, titleId: Int, drawableId: Int) : this(ResUtils.getString(titleId), ResUtils.getDrawable(context, drawableId))
- constructor(context: Context?, titleId: Int, drawableId: Int, id: Long) : this(ResUtils.getString(titleId), ResUtils.getDrawable(context, drawableId), id)
- constructor(context: Context?, titleId: Int, drawableId: Int, id: Long, status: Int) : this(ResUtils.getString(titleId), ResUtils.getDrawable(context, drawableId), id, status)
- constructor(context: Context?, title: CharSequence, drawableId: Int) : this(title, ResUtils.getDrawable(context, drawableId))
- constructor(context: Context?, title: CharSequence, drawableId: Int, id: Long) : this(title, ResUtils.getDrawable(context, drawableId), id)
- constructor(context: Context?, title: CharSequence, drawableId: Int, id: Long, status: Int) : this(title, ResUtils.getDrawable(context, drawableId), id, status)
-
- fun setStatus(status: Int): ActionAdapterItem {
- this.status = status
- return this
- }
-
- fun setId(id: Long): ActionAdapterItem {
- this.id = id
- return this
- }
-
- fun setTitle(title: CharSequence): ActionAdapterItem {
- this.title = title
- return this
- }
-
- fun setIcon(icon: Drawable?): ActionAdapterItem {
- this.icon = icon
- return this
- }
-
- //注意:自定义实体需要重写对象的toString方法
- override fun toString(): String {
- return title.toString()
- }
-
- companion object {
- fun of(title: CharSequence): ActionAdapterItem {
- return ActionAdapterItem(title)
- }
-
- fun arrayof(title: Array): Array {
- val array = arrayOfNulls(title.size)
- for (i in array.indices) {
- array[i] = ActionAdapterItem(title[i])
- }
- return array
- }
- }
-}
diff --git a/app/src/main/java/com/idormy/sms/forwarder/adapter/spinner/ConditionAdapterItem.kt b/app/src/main/java/com/idormy/sms/forwarder/adapter/spinner/ConditionAdapterItem.kt
deleted file mode 100644
index 5bb30eb2..00000000
--- a/app/src/main/java/com/idormy/sms/forwarder/adapter/spinner/ConditionAdapterItem.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.idormy.sms.forwarder.adapter.spinner
-
-import android.content.Context
-import android.graphics.drawable.Drawable
-import com.xuexiang.xui.utils.ResUtils
-
-@Suppress("unused")
-class ConditionAdapterItem {
-
- //标题内容
- var title: CharSequence
-
- //图标
- var icon: Drawable? = null
-
- //ID
- var id: Long? = 0L
-
- //状态
- var status: Int? = 1
-
- constructor(title: CharSequence) {
- this.title = title
- }
-
- constructor(title: CharSequence, icon: Drawable?) {
- this.title = title
- this.icon = icon
- }
-
- constructor(title: CharSequence, icon: Drawable?, id: Long?) {
- this.title = title
- this.icon = icon
- this.id = id
- }
-
- constructor(title: CharSequence, icon: Drawable?, id: Long?, status: Int?) {
- this.title = title
- this.icon = icon
- this.id = id
- this.status = status
- }
-
- constructor(title: CharSequence, drawableId: Int) : this(title, ResUtils.getDrawable(drawableId))
- constructor(title: CharSequence, drawableId: Int, id: Long) : this(title, ResUtils.getDrawable(drawableId), id)
- constructor(title: CharSequence, drawableId: Int, id: Long, status: Int) : this(title, ResUtils.getDrawable(drawableId), id, status)
- constructor(context: Context?, titleId: Int, drawableId: Int) : this(ResUtils.getString(titleId), ResUtils.getDrawable(context, drawableId))
- constructor(context: Context?, titleId: Int, drawableId: Int, id: Long) : this(ResUtils.getString(titleId), ResUtils.getDrawable(context, drawableId), id)
- constructor(context: Context?, titleId: Int, drawableId: Int, id: Long, status: Int) : this(ResUtils.getString(titleId), ResUtils.getDrawable(context, drawableId), id, status)
- constructor(context: Context?, title: CharSequence, drawableId: Int) : this(title, ResUtils.getDrawable(context, drawableId))
- constructor(context: Context?, title: CharSequence, drawableId: Int, id: Long) : this(title, ResUtils.getDrawable(context, drawableId), id)
- constructor(context: Context?, title: CharSequence, drawableId: Int, id: Long, status: Int) : this(title, ResUtils.getDrawable(context, drawableId), id, status)
-
- fun setStatus(status: Int): ConditionAdapterItem {
- this.status = status
- return this
- }
-
- fun setId(id: Long): ConditionAdapterItem {
- this.id = id
- return this
- }
-
- fun setTitle(title: CharSequence): ConditionAdapterItem {
- this.title = title
- return this
- }
-
- fun setIcon(icon: Drawable?): ConditionAdapterItem {
- this.icon = icon
- return this
- }
-
- //注意:自定义实体需要重写对象的toString方法
- override fun toString(): String {
- return title.toString()
- }
-
- companion object {
- fun of(title: CharSequence): ConditionAdapterItem {
- return ConditionAdapterItem(title)
- }
-
- fun arrayof(title: Array): Array {
- val array = arrayOfNulls(title.size)
- for (i in array.indices) {
- array[i] = ConditionAdapterItem(title[i])
- }
- return array
- }
- }
-}
diff --git a/app/src/main/java/com/idormy/sms/forwarder/entity/task/TaskSetting.kt b/app/src/main/java/com/idormy/sms/forwarder/entity/task/TaskSetting.kt
index 8266861d..c26a66dc 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/entity/task/TaskSetting.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/entity/task/TaskSetting.kt
@@ -1,13 +1,14 @@
package com.idormy.sms.forwarder.entity.task
import com.idormy.sms.forwarder.R
-import com.idormy.sms.forwarder.utils.TYPE_BARK
-import com.idormy.sms.forwarder.utils.TYPE_DINGTALK_GROUP_ROBOT
-import com.idormy.sms.forwarder.utils.TYPE_EMAIL
+import com.idormy.sms.forwarder.utils.TASK_CONDITION_BATTERY
+import com.idormy.sms.forwarder.utils.TASK_CONDITION_CHARGE
+import com.idormy.sms.forwarder.utils.TASK_CONDITION_CRON
+import com.idormy.sms.forwarder.utils.TASK_CONDITION_WLAN
import java.io.Serializable
data class TaskSetting(
- val type: Int,
+ val type: Int, // TASK_CONDITION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_CONDITION 或者 TASK_ACTION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_ACTION
val title: String,
val description: String,
var setting: String = "",
@@ -16,9 +17,10 @@ data class TaskSetting(
val iconId: Int
get() = when (type) {
- TYPE_DINGTALK_GROUP_ROBOT -> R.drawable.icon_dingtalk
- TYPE_EMAIL -> R.drawable.icon_email
- TYPE_BARK -> R.drawable.icon_bark
- else -> R.drawable.icon_sms
+ TASK_CONDITION_CRON -> R.drawable.auto_task_icon_cron
+ TASK_CONDITION_BATTERY -> R.drawable.auto_task_icon_battery
+ TASK_CONDITION_CHARGE -> R.drawable.auto_task_icon_charge
+ TASK_CONDITION_WLAN -> R.drawable.auto_task_icon_wlan
+ else -> R.drawable.auto_task_icon_sim
}
}
diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/TasksEditFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/TasksEditFragment.kt
index 930beda4..d9938333 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/fragment/TasksEditFragment.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/TasksEditFragment.kt
@@ -8,16 +8,17 @@ import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.fragment.app.viewModels
+import androidx.recyclerview.widget.ItemTouchHelper
+import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.gson.Gson
import com.idormy.sms.forwarder.R
+import com.idormy.sms.forwarder.adapter.ItemMoveCallback
+import com.idormy.sms.forwarder.adapter.TaskSettingAdapter
import com.idormy.sms.forwarder.adapter.WidgetItemAdapter
-import com.idormy.sms.forwarder.adapter.spinner.ActionAdapterItem
-import com.idormy.sms.forwarder.adapter.spinner.ConditionAdapterItem
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.database.AppDatabase
-import com.idormy.sms.forwarder.database.entity.Sender
import com.idormy.sms.forwarder.database.entity.Task
import com.idormy.sms.forwarder.database.viewmodel.BaseViewModelFactory
import com.idormy.sms.forwarder.database.viewmodel.TaskViewModel
@@ -46,7 +47,7 @@ import java.util.*
@Page(name = "自动任务·编辑器")
@Suppress("PrivatePropertyName", "unused", "DEPRECATION", "UNUSED_PARAMETER")
-class TasksEditFragment : BaseFragment(), View.OnClickListener, CompoundButton.OnCheckedChangeListener, RecyclerViewHolder.OnItemClickListener {
+class TasksEditFragment : BaseFragment(), View.OnClickListener, RecyclerViewHolder.OnItemClickListener {
private val TAG: String = TasksEditFragment::class.java.simpleName
private val that = this
@@ -56,37 +57,26 @@ class TasksEditFragment : BaseFragment(), View.OnClic
BottomSheetDialog(requireContext())
}
- //触发条件列表
- private var conditionId = 0L
- private var conditionListSelected: MutableList = mutableListOf()
- private var conditionItemMap = HashMap(2)
-
- //执行动作列表
- private var actionId = 0L
- private var actionListSelected: MutableList = mutableListOf()
- private var actionItemMap = HashMap(2)
-
@JvmField
- @AutoWired(name = KEY_RULE_ID)
+ @AutoWired(name = KEY_TASK_ID)
var taskId: Long = 0
@JvmField
- @AutoWired(name = KEY_RULE_TYPE)
- var taskType: String = "sms"
+ @AutoWired(name = KEY_TASK_TYPE)
+ var taskType: Int = 0
@JvmField
- @AutoWired(name = KEY_RULE_CLONE)
+ @AutoWired(name = KEY_TASK_CLONE)
var isClone: Boolean = false
- //初始化数据
- private val itemListConditions = mutableListOf(
- TaskSetting(TYPE_DINGTALK_GROUP_ROBOT, "Item 1", "Description 1"), TaskSetting(TYPE_EMAIL, "Item 2", "Description 2"), TaskSetting(TYPE_BARK, "Item 3", "Description 3")
- // ... other items
- )
- private val itemListActions = mutableListOf(
- TaskSetting(TYPE_DINGTALK_GROUP_ROBOT, "Apple", "Description Apple"), TaskSetting(TYPE_EMAIL, "Banana", "Description Banana"), TaskSetting(TYPE_BARK, "Orange", "Description Orange")
- // ... other items
- )
+ private lateinit var recyclerConditions: RecyclerView
+ private lateinit var recyclerActions: RecyclerView
+
+ private lateinit var conditionsAdapter: TaskSettingAdapter
+ private lateinit var actionsAdapter: TaskSettingAdapter
+
+ private var itemListConditions = mutableListOf()
+ private var itemListActions = mutableListOf()
override fun initArgs() {
XRouter.getInstance().inject(this)
@@ -116,6 +106,50 @@ class TasksEditFragment : BaseFragment(), View.OnClic
binding!!.btnDel.setText(R.string.del)
initForm()
}
+
+ recyclerConditions = findViewById(R.id.recycler_conditions)
+ recyclerActions = findViewById(R.id.recycler_actions)
+
+ // 初始化 RecyclerView 和 Adapter
+ initRecyclerViews()
+
+ // 添加示例项目
+ // addSampleItems()
+
+ // 设置拖动排序
+ val conditionsCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
+ override fun onItemMove(fromPosition: Int, toPosition: Int) {
+ Log.d(TAG, "onItemMove: $fromPosition $toPosition")
+ conditionsAdapter.onItemMove(fromPosition, toPosition)
+ }
+
+ override fun onDragFinished() {
+ //itemListConditions保持与adapter一致
+ itemListConditions = conditionsAdapter.itemList.toMutableList()
+ Log.d(TAG, "onItemMove: $itemListConditions")
+ }
+ })
+
+ val itemTouchHelperConditions = ItemTouchHelper(conditionsCallback)
+ itemTouchHelperConditions.attachToRecyclerView(recyclerConditions)
+ conditionsAdapter.setTouchHelper(itemTouchHelperConditions)
+
+ val actionsCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
+ override fun onItemMove(fromPosition: Int, toPosition: Int) {
+ Log.d(TAG, "onItemMove: $fromPosition $toPosition")
+ actionsAdapter.onItemMove(fromPosition, toPosition)
+ }
+
+ override fun onDragFinished() {
+ //itemListActions保持与adapter一致
+ itemListActions = actionsAdapter.itemList.toMutableList()
+ Log.d(TAG, "onItemMove: $itemListActions")
+ }
+ })
+
+ val itemTouchHelperActions = ItemTouchHelper(actionsCallback)
+ itemTouchHelperActions.attachToRecyclerView(recyclerActions)
+ actionsAdapter.setTouchHelper(itemTouchHelperActions)
}
override fun initListeners() {
@@ -126,10 +160,6 @@ class TasksEditFragment : BaseFragment(), View.OnClic
binding!!.btnSave.setOnClickListener(this)
}
- override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {/*when (buttonView?.id) {
- }*/
- }
-
@SuppressLint("InflateParams")
@SingleClick
override fun onClick(v: View) {
@@ -199,82 +229,6 @@ class TasksEditFragment : BaseFragment(), View.OnClic
}
}
- /**
- * 动态增删ConditionItem
- *
- * @param conditionItemMap 管理item的map,用于删除指定header
- * @param layoutConditions 需要挂载item的LinearLayout
- * @param condition ConditionAdapterItem
- */
- @SuppressLint("SetTextI18n")
- private fun addConditionItemLinearLayout(
- conditionItemMap: MutableMap, layoutConditions: LinearLayout, condition: ConditionAdapterItem
- ) {
- val layoutConditionItem = View.inflate(requireContext(), R.layout.item_add_condition, null) as LinearLayout
- val ivRemoveCondition = layoutConditionItem.findViewById(R.id.iv_remove_condition)
- val ivConditionImage = layoutConditionItem.findViewById(R.id.iv_condition_image)
- val tvConditionName = layoutConditionItem.findViewById(R.id.tv_condition_name)
-
- ivConditionImage.setImageDrawable(condition.icon)
- val conditionItemId = condition.id as Long
- tvConditionName.text = "ID-$conditionItemId:${condition.title}"
-
- ivRemoveCondition.tag = conditionItemId
- ivRemoveCondition.setOnClickListener { view2: View ->
- val tagId = view2.tag as Long
- layoutConditions.removeView(conditionItemMap[tagId])
- conditionItemMap.remove(tagId)
- }
- layoutConditions.addView(layoutConditionItem)
- conditionItemMap[conditionItemId] = layoutConditionItem
-
- if (conditionItemMap.isNotEmpty()) {
- binding!!.tvAddCondition.text = getString(R.string.add_condition_continue)
- binding!!.tvAddConditionTips.visibility = View.GONE
- } else {
- binding!!.tvAddCondition.text = getString(R.string.add_condition)
- binding!!.tvAddConditionTips.visibility = View.VISIBLE
- }
- }
-
- /**
- * 动态增删ActionItem
- *
- * @param actionItemMap 管理item的map,用于删除指定header
- * @param layoutActions 需要挂载item的LinearLayout
- * @param action ActionAdapterItem
- */
- @SuppressLint("SetTextI18n")
- private fun addActionItemLinearLayout(
- actionItemMap: MutableMap, layoutActions: LinearLayout, action: ActionAdapterItem
- ) {
- val layoutActionItem = View.inflate(requireContext(), R.layout.item_add_action, null) as LinearLayout
- val ivRemoveAction = layoutActionItem.findViewById(R.id.iv_remove_action)
- val ivActionImage = layoutActionItem.findViewById(R.id.iv_action_image)
- val tvActionName = layoutActionItem.findViewById(R.id.tv_action_name)
-
- ivActionImage.setImageDrawable(action.icon)
- val actionItemId = action.id as Long
- tvActionName.text = "ID-$actionItemId:${action.title}"
-
- ivRemoveAction.tag = actionItemId
- ivRemoveAction.setOnClickListener { view2: View ->
- val tagId = view2.tag as Long
- layoutActions.removeView(actionItemMap[tagId])
- actionItemMap.remove(tagId)
- }
- layoutActions.addView(layoutActionItem)
- actionItemMap[actionItemId] = layoutActionItem
-
- if (actionItemMap.isNotEmpty()) {
- binding!!.tvAddAction.text = getString(R.string.add_action_continue)
- binding!!.tvAddActionTips.visibility = View.GONE
- } else {
- binding!!.tvAddAction.text = getString(R.string.add_action)
- binding!!.tvAddActionTips.visibility = View.VISIBLE
- }
- }
-
//初始化表单
private fun initForm() {
AppDatabase.getInstance(requireContext()).taskDao().get(taskId).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver {
@@ -300,18 +254,10 @@ class TasksEditFragment : BaseFragment(), View.OnClic
//提交前检查表单
private fun checkForm(): Task {
- if (conditionListSelected.isEmpty() || conditionId == 0L) {
- throw Exception(getString(R.string.new_sender_first))
- }
-
- if (actionListSelected.isEmpty() || actionId == 0L) {
- throw Exception(getString(R.string.new_sender_first))
- }
return Task()
}
private fun testTask(task: Task) {
-
}
@SingleClick
@@ -319,8 +265,28 @@ class TasksEditFragment : BaseFragment(), View.OnClic
try {
dialog.dismiss()
Log.d(TAG, "onItemClick: $widgetInfo")
+ //判断点击的是条件还是动作
+ if (widgetInfo.classPath.contains(".condition.")) {
+ //判断是否已经添加过该类型条件
+ for (item in itemListConditions) {
+ //注意:TASK_CONDITION_XXX 枚举值 等于 TASK_CONDITION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_CONDITION,不可改变
+ if (item.type == pos + KEY_BACK_CODE_CONDITION) {
+ XToastUtils.error("已经添加过该类型条件")
+ return
+ }
+ }
+ } else {
+ //判断是否已经添加过该类型动作
+ for (item in itemListActions) {
+ //注意:TASK_ACTION_XXX 枚举值 等于 TASK_ACTION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_ACTION,不可改变
+ if (item.type == pos + KEY_BACK_CODE_ACTION) {
+ XToastUtils.error("已经添加过该类型动作")
+ return
+ }
+ }
+ }
@Suppress("UNCHECKED_CAST") PageOption.to(Class.forName(widgetInfo.classPath) as Class) //跳转的fragment
- .setRequestCode(pos) //请求码,用于返回结果
+ .setRequestCode(0) //requestCode: 0 新增 、>0 编辑(itemListXxx 的索引加1)
.open(this)
} catch (e: Exception) {
e.printStackTrace()
@@ -328,25 +294,127 @@ class TasksEditFragment : BaseFragment(), View.OnClic
}
}
+ @SuppressLint("NotifyDataSetChanged")
override fun onFragmentResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onFragmentResult(requestCode, resultCode, data)
+ Log.d(TAG, "requestCode:$requestCode resultCode:$resultCode data:$data")
if (data != null) {
val extras = data.extras
- var backData: String? = null
- if (resultCode == KEY_BACK_CODE_CONDITION) {
- backData = extras!!.getString(KEY_BACK_DATA_CONDITION)
- if (backData == null) return
- when (requestCode) {
- 0 -> {
- val settingVo = Gson().fromJson(backData, CronSetting::class.java)
- val condition = ConditionAdapterItem(settingVo.expression) //TODO: 构建列表项目
- addConditionItemLinearLayout(conditionItemMap, binding!!.layoutConditions, condition)
+ var setting: String? = null
+ if (resultCode in KEY_BACK_CODE_CONDITION..KEY_BACK_CODE_CONDITION + 999) {
+ setting = extras!!.getString(KEY_BACK_DATA_CONDITION)
+ if (setting == null) return
+ //注意:TASK_CONDITION_XXX 枚举值 等于 TASK_CONDITION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_CONDITION,不可改变
+ val widgetInfoIndex = resultCode - KEY_BACK_CODE_CONDITION
+ if (widgetInfoIndex >= TASK_CONDITION_FRAGMENT_LIST.size) return
+ val widgetInfo = TASK_CONDITION_FRAGMENT_LIST[widgetInfoIndex]
+ val taskSetting: TaskSetting
+ when (resultCode) {
+ TASK_CONDITION_CRON -> {
+ val settingVo = Gson().fromJson(setting, CronSetting::class.java)
+ Log.d(TAG, settingVo.toString())
+ taskSetting = TaskSetting(
+ resultCode, widgetInfo.name, settingVo.description, setting, requestCode
+ )
+ }
+
+ TASK_CONDITION_BATTERY -> {
+ val settingVo = Gson().fromJson(setting, CronSetting::class.java)
+ Log.d(TAG, settingVo.toString())
+ taskSetting = TaskSetting(
+ resultCode, widgetInfo.name, settingVo.description, setting, requestCode
+ )
+ }
+
+ else -> {
+ return
}
}
+ //requestCode: 等于 itemListConditions 的索引加1
+ if (requestCode == 0) {
+ taskSetting.position = itemListConditions.size
+ itemListConditions.add(taskSetting)
+ } else {
+ itemListConditions[requestCode - 1] = taskSetting
+ }
+ conditionsAdapter.notifyDataSetChanged()
} else if (resultCode == KEY_BACK_CODE_ACTION) {
- backData = extras!!.getString(KEY_BACK_DATA_ACTION)
+ setting = extras!!.getString(KEY_BACK_DATA_ACTION)
}
- Log.d(TAG, "requestCode:$requestCode resultCode:$resultCode backData:$backData")
+ Log.d(TAG, "requestCode:$requestCode resultCode:$resultCode setting:$setting")
}
}
+
+ @SuppressLint("NotifyDataSetChanged")
+ private fun addSampleItems() {
+ // 添加示例项目到列表中
+ itemListConditions.add(TaskSetting(TYPE_DINGTALK_GROUP_ROBOT, "DingTalk 1", "Description 1"))
+ itemListConditions.add(TaskSetting(TYPE_DINGTALK_GROUP_ROBOT, "DingTalk 2", "Description 2"))
+ itemListConditions.add(TaskSetting(TYPE_DINGTALK_GROUP_ROBOT, "DingTalk 3", "Description 3"))
+ itemListActions.add(TaskSetting(TYPE_EMAIL, "Email 1", "Description 1"))
+ itemListActions.add(TaskSetting(TYPE_EMAIL, "Email 2", "Description 2"))
+ itemListActions.add(TaskSetting(TYPE_EMAIL, "Email 3", "Description 3"))
+
+ // 更新 Adapter
+ conditionsAdapter.notifyDataSetChanged()
+ actionsAdapter.notifyDataSetChanged()
+ }
+
+ private fun initRecyclerViews() {
+ conditionsAdapter = TaskSettingAdapter(itemListConditions, { position -> editCondition(position) }, { position -> removeCondition(position) })
+
+ actionsAdapter = TaskSettingAdapter(itemListActions, { position -> editAction(position) }, { position -> removeAction(position) })
+
+ recyclerConditions.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ adapter = conditionsAdapter
+ }
+
+ recyclerActions.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ adapter = actionsAdapter
+ }
+ }
+
+ private fun editCondition(position: Int) {
+ // 实现编辑条件项目的逻辑
+ // 根据 position 对特定项目进行编辑
+ val condition = itemListConditions[position]
+ Log.d(TAG, "editCondition: $position, $condition")
+
+ val widgetInfoIndex = condition.type - KEY_BACK_CODE_CONDITION
+ //判断是否存在
+ if (widgetInfoIndex < 0 || widgetInfoIndex >= TASK_CONDITION_FRAGMENT_LIST.size) return
+ val widgetInfo = TASK_CONDITION_FRAGMENT_LIST[condition.type - KEY_BACK_CODE_CONDITION]
+ @Suppress("UNCHECKED_CAST") PageOption.to(Class.forName(widgetInfo.classPath) as Class) //跳转的fragment
+ .setRequestCode(position + 1) //requestCode: 0 新增 、>0 编辑(itemListConditions 的索引加1)
+ .putString(KEY_EVENT_DATA_CONDITION, condition.setting)
+ .open(this)
+ }
+
+ private fun removeCondition(position: Int) {
+ itemListConditions.removeAt(position)
+ conditionsAdapter.notifyItemRemoved(position)
+ }
+
+ private fun editAction(position: Int) {
+ // 实现编辑操作项目的逻辑
+ // 根据 position 对特定项目进行编辑
+ val action = itemListActions[position]
+ Log.d(TAG, "editAction: $position, $action")
+
+ val widgetInfoIndex = action.type - KEY_BACK_CODE_ACTION
+ //判断是否存在
+ if (widgetInfoIndex < 0 || widgetInfoIndex >= TASK_ACTION_FRAGMENT_LIST.size) return
+ val widgetInfo = TASK_ACTION_FRAGMENT_LIST[action.type - KEY_BACK_CODE_ACTION]
+ @Suppress("UNCHECKED_CAST") PageOption.to(Class.forName(widgetInfo.classPath) as Class) //跳转的fragment
+ .setRequestCode(position + 1) //requestCode: 0 新增 、>0 编辑(itemListActions 的索引加1)
+ .putString(KEY_EVENT_DATA_ACTION, action.setting)
+ .open(this)
+ }
+
+ private fun removeAction(position: Int) {
+ itemListActions.removeAt(position)
+ actionsAdapter.notifyItemRemoved(position)
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/idormy/sms/forwarder/fragment/condition/CronFragment.kt b/app/src/main/java/com/idormy/sms/forwarder/fragment/condition/CronFragment.kt
index eaa7ba0e..1abcfdae 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/fragment/condition/CronFragment.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/fragment/condition/CronFragment.kt
@@ -15,10 +15,10 @@ import com.idormy.sms.forwarder.R
import com.idormy.sms.forwarder.core.BaseFragment
import com.idormy.sms.forwarder.databinding.FragmentTasksCronBinding
import com.idormy.sms.forwarder.entity.task.CronSetting
-import com.idormy.sms.forwarder.utils.KEY_BACK_CODE_CONDITION
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_CONDITION
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_CONDITION
import com.idormy.sms.forwarder.utils.KEY_TEST_CONDITION
+import com.idormy.sms.forwarder.utils.TASK_CONDITION_CRON
import com.idormy.sms.forwarder.utils.XToastUtils
import com.jeremyliao.liveeventbus.LiveEventBus
import com.xuexiang.xaop.annotation.SingleClick
@@ -203,7 +203,7 @@ class CronFragment : BaseFragment(), View.OnClickList
val settingVo = checkSetting()
val intent = Intent()
intent.putExtra(KEY_BACK_DATA_CONDITION, Gson().toJson(settingVo))
- setFragmentResult(KEY_BACK_CODE_CONDITION, intent)
+ setFragmentResult(TASK_CONDITION_CRON, intent)
popToBack()
return
}
diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt b/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt
index 81d7f46e..b2a1e956 100644
--- a/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt
+++ b/app/src/main/java/com/idormy/sms/forwarder/utils/Constants.kt
@@ -476,6 +476,10 @@ var CLIENT_FRAGMENT_LIST = listOf(
)
//自动任务
+const val KEY_TASK_ID = "key_task_id"
+const val KEY_TASK_TYPE = "key_task_type"
+const val KEY_TASK_CLONE = "key_task_clone"
+
const val KEY_TEST_CONDITION = "key_test_condition"
const val KEY_EVENT_DATA_CONDITION = "event_data_condition"
const val KEY_BACK_CODE_CONDITION = 1000
@@ -486,14 +490,18 @@ const val KEY_EVENT_DATA_ACTION = "event_data_action"
const val KEY_BACK_CODE_ACTION = 2000
const val KEY_BACK_DATA_ACTION = "back_data_action"
-const val TASK_CRON = 0
+//注意:TASK_CONDITION_XXX 枚举值 等于 TASK_CONDITION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_CONDITION,不可改变
+const val TASK_CONDITION_CRON = 1000
+const val TASK_CONDITION_BATTERY = 1001
+const val TASK_CONDITION_CHARGE = 1002
+const val TASK_CONDITION_WLAN = 1003
var TASK_CONDITION_FRAGMENT_LIST = listOf(
PageInfo(
getString(R.string.task_cron),
"com.idormy.sms.forwarder.fragment.condition.CronFragment",
"{\"\":\"\"}",
CoreAnim.slide,
- R.drawable.auto_task_icon_cron
+ R.drawable.auto_task_icon_cron,
),
PageInfo(
getString(R.string.email),
@@ -517,6 +525,8 @@ var TASK_CONDITION_FRAGMENT_LIST = listOf(
R.drawable.auto_task_icon_wlan
),
)
+
+//注意:TASK_ACTION_XXX 枚举值 等于 TASK_ACTION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_ACTION,不可改变
var TASK_ACTION_FRAGMENT_LIST = listOf(
PageInfo(
getString(R.string.task_cron),
diff --git a/app/src/main/res/layout/adapter_task_setting_item.xml b/app/src/main/res/layout/adapter_task_setting_item.xml
index 736e1de7..5c7d5ff1 100644
--- a/app/src/main/res/layout/adapter_task_setting_item.xml
+++ b/app/src/main/res/layout/adapter_task_setting_item.xml
@@ -6,15 +6,15 @@
android:layout_height="wrap_content"
android:background="@color/xui_config_color_white"
android:orientation="vertical"
- android:paddingStart="5dp"
- android:paddingEnd="5dp"
tools:ignore="UseCompoundDrawables">
+ android:orientation="horizontal"
+ android:paddingTop="@dimen/config_padding_5dp"
+ android:paddingBottom="@dimen/config_padding_5dp">
+ android:orientation="horizontal"
+ android:paddingTop="@dimen/config_padding_5dp"
+ android:paddingBottom="@dimen/config_padding_5dp">
+ android:orientation="horizontal"
+ android:paddingTop="@dimen/config_padding_5dp"
+ android:paddingBottom="@dimen/config_padding_5dp">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_add_condition.xml b/app/src/main/res/layout/item_add_condition.xml
deleted file mode 100644
index c08f5f60..00000000
--- a/app/src/main/res/layout/item_add_condition.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 2fca673c..efa00ede 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -58,6 +58,6 @@
20dp
24dp
30dp
- 36dp
- 8dp
+ 32dp
+ 4dp
\ No newline at end of file