新增:自动任务·快捷指令 (开发中)
This commit is contained in:
parent
e69716affc
commit
0c950c835a
|
@ -0,0 +1,104 @@
|
|||
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.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.database.entity.Frpc
|
||||
import java.util.Collections
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class FrpcRecyclerAdapter(
|
||||
var itemList: MutableList<Frpc>,
|
||||
private var removeClickListener: ((Int) -> Unit)? = null,
|
||||
private var editClickListener: ((Int) -> Unit)? = null,
|
||||
) : RecyclerView.Adapter<FrpcRecyclerAdapter.ViewHolder>(), 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_frpc_list_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@FrpcRecyclerAdapter.touchHelper = touchHelper
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
|
||||
private val image: ImageView = itemView.findViewById(R.id.iv_image)
|
||||
private val status: ImageView = itemView.findViewById(R.id.iv_status)
|
||||
private val title: TextView = itemView.findViewById(R.id.tv_title)
|
||||
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 {
|
||||
if (removeClickListener == null) {
|
||||
removeIcon.visibility = View.GONE
|
||||
} else {
|
||||
removeIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
if (editClickListener == null) {
|
||||
editIcon.visibility = View.GONE
|
||||
} else {
|
||||
editIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
dragIcon.setOnTouchListener { _, event ->
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
touchHelper.startDrag(this)
|
||||
}
|
||||
return@setOnTouchListener false
|
||||
}
|
||||
}
|
||||
|
||||
fun bind(frpc: Frpc) {
|
||||
image.setImageResource(frpc.imageId)
|
||||
status.setImageResource(frpc.autorunImageId)
|
||||
title.text = frpc.name
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
val position = adapterPosition
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
when (v?.id) {
|
||||
R.id.iv_edit -> editClickListener?.let { it(position) }
|
||||
R.id.iv_remove -> removeClickListener?.let { it(position) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
if (fromPosition < toPosition) {
|
||||
for (i in fromPosition until toPosition) {
|
||||
Collections.swap(itemList, i, i + 1)
|
||||
}
|
||||
} else {
|
||||
for (i in fromPosition downTo toPosition + 1) {
|
||||
Collections.swap(itemList, i, i - 1)
|
||||
}
|
||||
}
|
||||
notifyItemMoved(fromPosition, toPosition)
|
||||
}
|
||||
|
||||
override fun onDragFinished() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
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.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.database.entity.Rule
|
||||
import java.util.Collections
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class RuleRecyclerAdapter(
|
||||
var itemList: MutableList<Rule>,
|
||||
private var removeClickListener: ((Int) -> Unit)? = null,
|
||||
private var editClickListener: ((Int) -> Unit)? = null,
|
||||
) : RecyclerView.Adapter<RuleRecyclerAdapter.ViewHolder>(), 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_rule_list_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@RuleRecyclerAdapter.touchHelper = touchHelper
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
|
||||
private val image: ImageView = itemView.findViewById(R.id.iv_image)
|
||||
private val status: ImageView = itemView.findViewById(R.id.iv_status)
|
||||
private val title: TextView = itemView.findViewById(R.id.tv_title)
|
||||
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 {
|
||||
if (removeClickListener == null) {
|
||||
removeIcon.visibility = View.GONE
|
||||
} else {
|
||||
removeIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
if (editClickListener == null) {
|
||||
editIcon.visibility = View.GONE
|
||||
} else {
|
||||
editIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
dragIcon.setOnTouchListener { _, event ->
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
touchHelper.startDrag(this)
|
||||
}
|
||||
return@setOnTouchListener false
|
||||
}
|
||||
}
|
||||
|
||||
fun bind(rule: Rule) {
|
||||
val icon = when (rule.type) {
|
||||
"sms" -> R.drawable.auto_task_icon_sms
|
||||
"call" -> R.drawable.auto_task_icon_incall
|
||||
"app" -> R.drawable.auto_task_icon_start_activity
|
||||
else -> R.drawable.auto_task_icon_sms
|
||||
}
|
||||
image.setImageResource(icon)
|
||||
status.setImageResource(rule.statusImageId)
|
||||
title.text = rule.name
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
val position = adapterPosition
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
when (v?.id) {
|
||||
R.id.iv_edit -> editClickListener?.let { it(position) }
|
||||
R.id.iv_remove -> removeClickListener?.let { it(position) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
if (fromPosition < toPosition) {
|
||||
for (i in fromPosition until toPosition) {
|
||||
Collections.swap(itemList, i, i + 1)
|
||||
}
|
||||
} else {
|
||||
for (i in fromPosition downTo toPosition + 1) {
|
||||
Collections.swap(itemList, i, i - 1)
|
||||
}
|
||||
}
|
||||
notifyItemMoved(fromPosition, toPosition)
|
||||
}
|
||||
|
||||
override fun onDragFinished() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
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.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import java.util.Collections
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class SenderRecyclerAdapter(
|
||||
var itemList: MutableList<Sender>,
|
||||
private var removeClickListener: ((Int) -> Unit)? = null,
|
||||
private var editClickListener: ((Int) -> Unit)? = null,
|
||||
) : RecyclerView.Adapter<SenderRecyclerAdapter.ViewHolder>(), 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_sender_list_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@SenderRecyclerAdapter.touchHelper = touchHelper
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
|
||||
private val image: ImageView = itemView.findViewById(R.id.iv_image)
|
||||
private val status: ImageView = itemView.findViewById(R.id.iv_status)
|
||||
private val title: TextView = itemView.findViewById(R.id.tv_title)
|
||||
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 {
|
||||
if (removeClickListener == null) {
|
||||
removeIcon.visibility = View.GONE
|
||||
} else {
|
||||
removeIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
if (editClickListener == null) {
|
||||
editIcon.visibility = View.GONE
|
||||
} else {
|
||||
editIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
dragIcon.setOnTouchListener { _, event ->
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
touchHelper.startDrag(this)
|
||||
}
|
||||
return@setOnTouchListener false
|
||||
}
|
||||
}
|
||||
|
||||
fun bind(sender: Sender) {
|
||||
image.setImageResource(sender.imageId)
|
||||
status.setImageResource(sender.statusImageId)
|
||||
title.text = sender.name
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
val position = adapterPosition
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
when (v?.id) {
|
||||
R.id.iv_edit -> editClickListener?.let { it(position) }
|
||||
R.id.iv_remove -> removeClickListener?.let { it(position) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
if (fromPosition < toPosition) {
|
||||
for (i in fromPosition until toPosition) {
|
||||
Collections.swap(itemList, i, i + 1)
|
||||
}
|
||||
} else {
|
||||
for (i in fromPosition downTo toPosition + 1) {
|
||||
Collections.swap(itemList, i, i - 1)
|
||||
}
|
||||
}
|
||||
notifyItemMoved(fromPosition, toPosition)
|
||||
}
|
||||
|
||||
override fun onDragFinished() {}
|
||||
}
|
||||
|
|
@ -10,20 +10,21 @@ 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.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.entity.TaskSetting
|
||||
import java.util.Collections
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class TaskSettingAdapter(
|
||||
val itemList: MutableList<TaskSetting>,
|
||||
private val editClickListener: (Int) -> Unit,
|
||||
private val removeClickListener: (Int) -> Unit
|
||||
var itemList: MutableList<TaskSetting>,
|
||||
private var removeClickListener: ((Int) -> Unit)? = null,
|
||||
private var editClickListener: ((Int) -> Unit)? = null,
|
||||
) : RecyclerView.Adapter<TaskSettingAdapter.ViewHolder>(), 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)
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.adapter_task_setting_item, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
|
@ -48,8 +49,17 @@ class TaskSettingAdapter(
|
|||
private val dragIcon: ImageView = itemView.findViewById(R.id.iv_drag)
|
||||
|
||||
init {
|
||||
editIcon.setOnClickListener(this)
|
||||
removeIcon.setOnClickListener(this)
|
||||
if (removeClickListener == null) {
|
||||
removeIcon.visibility = View.GONE
|
||||
} else {
|
||||
removeIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
if (editClickListener == null) {
|
||||
editIcon.visibility = View.GONE
|
||||
} else {
|
||||
editIcon.setOnClickListener(this)
|
||||
}
|
||||
|
||||
dragIcon.setOnTouchListener { _, event ->
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
|
@ -69,8 +79,8 @@ class TaskSettingAdapter(
|
|||
val position = adapterPosition
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
when (v?.id) {
|
||||
R.id.iv_edit -> editClickListener(position)
|
||||
R.id.iv_remove -> removeClickListener(position)
|
||||
R.id.iv_edit -> editClickListener?.let { it(position) }
|
||||
R.id.iv_remove -> removeClickListener?.let { it(position) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,11 +89,11 @@ class TaskSettingAdapter(
|
|||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
if (fromPosition < toPosition) {
|
||||
for (i in fromPosition until toPosition) {
|
||||
itemList[i] = itemList.set(i + 1, itemList[i])
|
||||
Collections.swap(itemList, i, i + 1)
|
||||
}
|
||||
} else {
|
||||
for (i in fromPosition downTo toPosition + 1) {
|
||||
itemList[i] = itemList.set(i - 1, itemList[i])
|
||||
Collections.swap(itemList, i, i - 1)
|
||||
}
|
||||
}
|
||||
notifyItemMoved(fromPosition, toPosition)
|
||||
|
@ -91,40 +101,3 @@ class TaskSettingAdapter(
|
|||
|
||||
override fun onDragFinished() {}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.idormy.sms.forwarder.adapter.base
|
||||
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,7 +71,7 @@ class FrpcSpinnerAdapter<T> : BaseEditSpinnerAdapter<T>, EditSpinnerFilter {
|
|||
} else {
|
||||
holder = convertView.tag as ViewHolder
|
||||
}
|
||||
val item = CollectionUtils.getListItem(mDataSource, mIndexs[position]) as FrpcAdapterItem
|
||||
val item = CollectionUtils.getListItem(mDataSource, mIndexs[position]) as FrpcSpinnerItem
|
||||
holder.iconView.setImageDrawable(item.icon)
|
||||
holder.statusView.setImageDrawable(
|
||||
getDrawable(
|
||||
|
|
|
@ -3,29 +3,29 @@ package com.idormy.sms.forwarder.adapter.spinner
|
|||
import android.graphics.drawable.Drawable
|
||||
|
||||
@Suppress("unused")
|
||||
class FrpcAdapterItem(
|
||||
class FrpcSpinnerItem(
|
||||
var title: CharSequence,
|
||||
var icon: Drawable? = null,
|
||||
var uid: String = "",
|
||||
var autorun: Int? = 1
|
||||
) {
|
||||
|
||||
fun setTitle(title: CharSequence): FrpcAdapterItem {
|
||||
fun setTitle(title: CharSequence): FrpcSpinnerItem {
|
||||
this.title = title
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIcon(icon: Drawable?): FrpcAdapterItem {
|
||||
fun setIcon(icon: Drawable?): FrpcSpinnerItem {
|
||||
this.icon = icon
|
||||
return this
|
||||
}
|
||||
|
||||
fun setUid(uid: String): FrpcAdapterItem {
|
||||
fun setUid(uid: String): FrpcSpinnerItem {
|
||||
this.uid = uid
|
||||
return this
|
||||
}
|
||||
|
||||
fun setAutorun(autorun: Int): FrpcAdapterItem {
|
||||
fun setAutorun(autorun: Int): FrpcSpinnerItem {
|
||||
this.autorun = autorun
|
||||
return this
|
||||
}
|
||||
|
@ -37,13 +37,13 @@ class FrpcAdapterItem(
|
|||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun of(title: CharSequence): FrpcAdapterItem {
|
||||
return FrpcAdapterItem(title)
|
||||
fun of(title: CharSequence): FrpcSpinnerItem {
|
||||
return FrpcSpinnerItem(title)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun arrayOf(vararg titles: CharSequence): Array<FrpcAdapterItem> {
|
||||
return titles.map { FrpcAdapterItem(it) }.toTypedArray()
|
||||
fun arrayOf(vararg titles: CharSequence): Array<FrpcSpinnerItem> {
|
||||
return titles.map { FrpcSpinnerItem(it) }.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,7 +71,7 @@ class RuleSpinnerAdapter<T> : BaseEditSpinnerAdapter<T>, EditSpinnerFilter {
|
|||
} else {
|
||||
holder = convertView.tag as ViewHolder
|
||||
}
|
||||
val item = CollectionUtils.getListItem(mDataSource, mIndexs[position]) as RuleAdapterItem
|
||||
val item = CollectionUtils.getListItem(mDataSource, mIndexs[position]) as RuleSpinnerItem
|
||||
holder.iconView.setImageDrawable(item.icon)
|
||||
holder.statusView.setImageDrawable(
|
||||
getDrawable(
|
||||
|
|
|
@ -3,29 +3,29 @@ package com.idormy.sms.forwarder.adapter.spinner
|
|||
import android.graphics.drawable.Drawable
|
||||
|
||||
@Suppress("unused")
|
||||
class RuleAdapterItem(
|
||||
class RuleSpinnerItem(
|
||||
var title: CharSequence,
|
||||
var icon: Drawable? = null,
|
||||
var id: Long? = 0L,
|
||||
var status: Int? = 1
|
||||
) {
|
||||
|
||||
fun setTitle(title: CharSequence): RuleAdapterItem {
|
||||
fun setTitle(title: CharSequence): RuleSpinnerItem {
|
||||
this.title = title
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIcon(icon: Drawable?): RuleAdapterItem {
|
||||
fun setIcon(icon: Drawable?): RuleSpinnerItem {
|
||||
this.icon = icon
|
||||
return this
|
||||
}
|
||||
|
||||
fun setId(id: Long): RuleAdapterItem {
|
||||
fun setId(id: Long): RuleSpinnerItem {
|
||||
this.id = id
|
||||
return this
|
||||
}
|
||||
|
||||
fun setStatus(status: Int): RuleAdapterItem {
|
||||
fun setStatus(status: Int): RuleSpinnerItem {
|
||||
this.status = status
|
||||
return this
|
||||
}
|
||||
|
@ -37,13 +37,13 @@ class RuleAdapterItem(
|
|||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun of(title: CharSequence): RuleAdapterItem {
|
||||
return RuleAdapterItem(title)
|
||||
fun of(title: CharSequence): RuleSpinnerItem {
|
||||
return RuleSpinnerItem(title)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun arrayOf(vararg titles: CharSequence): Array<RuleAdapterItem> {
|
||||
return titles.map { RuleAdapterItem(it) }.toTypedArray()
|
||||
fun arrayOf(vararg titles: CharSequence): Array<RuleSpinnerItem> {
|
||||
return titles.map { RuleSpinnerItem(it) }.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,7 +71,7 @@ class SenderSpinnerAdapter<T> : BaseEditSpinnerAdapter<T>, EditSpinnerFilter {
|
|||
} else {
|
||||
holder = convertView.tag as ViewHolder
|
||||
}
|
||||
val item = CollectionUtils.getListItem(mDataSource, mIndexs[position]) as SenderAdapterItem
|
||||
val item = CollectionUtils.getListItem(mDataSource, mIndexs[position]) as SenderSpinnerItem
|
||||
holder.iconView.setImageDrawable(item.icon)
|
||||
holder.statusView.setImageDrawable(
|
||||
getDrawable(
|
||||
|
|
|
@ -3,29 +3,29 @@ package com.idormy.sms.forwarder.adapter.spinner
|
|||
import android.graphics.drawable.Drawable
|
||||
|
||||
@Suppress("unused")
|
||||
class SenderAdapterItem(
|
||||
class SenderSpinnerItem(
|
||||
var title: CharSequence,
|
||||
var icon: Drawable? = null,
|
||||
var id: Long? = 0L,
|
||||
var status: Int? = 1
|
||||
) {
|
||||
|
||||
fun setTitle(title: CharSequence): SenderAdapterItem {
|
||||
fun setTitle(title: CharSequence): SenderSpinnerItem {
|
||||
this.title = title
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIcon(icon: Drawable?): SenderAdapterItem {
|
||||
fun setIcon(icon: Drawable?): SenderSpinnerItem {
|
||||
this.icon = icon
|
||||
return this
|
||||
}
|
||||
|
||||
fun setId(id: Long): SenderAdapterItem {
|
||||
fun setId(id: Long): SenderSpinnerItem {
|
||||
this.id = id
|
||||
return this
|
||||
}
|
||||
|
||||
fun setStatus(status: Int): SenderAdapterItem {
|
||||
fun setStatus(status: Int): SenderSpinnerItem {
|
||||
this.status = status
|
||||
return this
|
||||
}
|
||||
|
@ -37,13 +37,13 @@ class SenderAdapterItem(
|
|||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun of(title: CharSequence): SenderAdapterItem {
|
||||
return SenderAdapterItem(title)
|
||||
fun of(title: CharSequence): SenderSpinnerItem {
|
||||
return SenderSpinnerItem(title)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun arrayOf(vararg titles: CharSequence): Array<SenderAdapterItem> {
|
||||
return titles.map { SenderAdapterItem(it) }.toTypedArray()
|
||||
fun arrayOf(vararg titles: CharSequence): Array<SenderSpinnerItem> {
|
||||
return titles.map { SenderSpinnerItem(it) }.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,8 +40,9 @@ interface FrpcDao {
|
|||
@Query("SELECT * FROM Frpc where autorun=1")
|
||||
fun getAutorun(): List<Frpc>
|
||||
|
||||
@Query("SELECT * FROM Frpc WHERE uid IN (:uids)")
|
||||
fun getByUids(uids: List<String>): List<Frpc>
|
||||
//使用 ORDER BY 子句和 instr() 函数按照列表中 uid 的顺序返回结果
|
||||
@Query("SELECT * FROM Frpc WHERE uid IN (:uids) ORDER BY instr(:instr, uid)")
|
||||
fun getByUids(uids: List<String>, instr: String): List<Frpc>
|
||||
|
||||
@Query("SELECT * FROM Frpc ORDER BY time DESC")
|
||||
fun pagingSource(): PagingSource<Int, Frpc>
|
||||
|
|
|
@ -41,8 +41,9 @@ interface SenderDao {
|
|||
@Query("SELECT * FROM Sender where id=:id")
|
||||
fun getOne(id: Long): Sender
|
||||
|
||||
@Query("SELECT * FROM Sender WHERE id IN (:ids)")
|
||||
fun getByIds(ids: List<Long>): List<Sender>
|
||||
//使用 ORDER BY 子句和 instr() 函数按照列表中 ID 的顺序返回结果
|
||||
@Query("SELECT * FROM Sender WHERE id IN (:ids) ORDER BY instr(:instr, id)")
|
||||
fun getByIds(ids: List<Long>, instr: String): List<Sender>
|
||||
|
||||
@Query("SELECT count(*) FROM Sender where type=:type and status=:status")
|
||||
fun count(type: String, status: Int): Single<Int>
|
||||
|
|
|
@ -8,7 +8,7 @@ class ConvertersSenderList {
|
|||
|
||||
@TypeConverter
|
||||
fun stringToObject(value: String): List<Sender> {
|
||||
return Core.sender.getByIds(value.split(",").map { it.trim().toLong() })
|
||||
return Core.sender.getByIds(value.split(",").map { it.trim().toLong() }, value)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
|
|
|
@ -31,6 +31,6 @@ class FrpcRepository(private val frpcDao: FrpcDao) {
|
|||
|
||||
fun getAutorun(): List<Frpc> = frpcDao.getAutorun()
|
||||
|
||||
fun getByUids(uids: List<String>): List<Frpc> = frpcDao.getByUids(uids)
|
||||
fun getByUids(uids: List<String>, instr: String): List<Frpc> = frpcDao.getByUids(uids, instr)
|
||||
|
||||
}
|
|
@ -30,7 +30,7 @@ class SenderRepository(private val senderDao: SenderDao) {
|
|||
|
||||
fun getOne(id: Long) = senderDao.getOne(id)
|
||||
|
||||
fun getByIds(ids: List<Long>) = senderDao.getByIds(ids)
|
||||
fun getByIds(ids: List<Long>, instr: String) = senderDao.getByIds(ids, instr)
|
||||
|
||||
fun getAllNonCache(): List<Sender> {
|
||||
val query = SimpleSQLiteQuery("SELECT * FROM Sender ORDER BY id ASC")
|
||||
|
|
|
@ -7,14 +7,19 @@ import android.view.ViewGroup
|
|||
import android.widget.*
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import com.idormy.sms.forwarder.App
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.adapter.SenderRecyclerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.adapter.spinner.AppListAdapterItem
|
||||
import com.idormy.sms.forwarder.adapter.spinner.AppListSpinnerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderAdapterItem
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderSpinnerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderSpinnerItem
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.core.Core
|
||||
import com.idormy.sms.forwarder.database.entity.Rule
|
||||
|
@ -74,16 +79,17 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
|||
private var silentPeriodStart = 0
|
||||
private var silentPeriodEnd = 0
|
||||
|
||||
//当前发送通道
|
||||
private var senderId = 0L
|
||||
private var senderListSelected: MutableList<Sender> = mutableListOf()
|
||||
private var senderItemMap = HashMap<Long, LinearLayout>(2)
|
||||
|
||||
//发送通道列表
|
||||
private var senderListAll: MutableList<Sender> = mutableListOf()
|
||||
private val senderSpinnerList = ArrayList<SenderAdapterItem>()
|
||||
//所有发送通道下拉框
|
||||
private var senderListAll = mutableListOf<Sender>()
|
||||
private val senderSpinnerList = mutableListOf<SenderSpinnerItem>()
|
||||
private lateinit var senderSpinnerAdapter: SenderSpinnerAdapter<*>
|
||||
|
||||
//已选发送通道列表
|
||||
private var senderId = 0L
|
||||
private var senderListSelected = mutableListOf<Sender>()
|
||||
private lateinit var senderRecyclerView: RecyclerView
|
||||
private lateinit var senderRecyclerAdapter: SenderRecyclerAdapter
|
||||
|
||||
//已安装App信息列表
|
||||
private val appListSpinnerList = ArrayList<AppListAdapterItem>()
|
||||
private lateinit var appListSpinnerAdapter: AppListSpinnerAdapter<*>
|
||||
|
@ -400,49 +406,16 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
|||
}
|
||||
|
||||
//初始化发送通道下拉框
|
||||
@SuppressLint("SetTextI18n")
|
||||
@SuppressLint("SetTextI18n", "NotifyDataSetChanged")
|
||||
private fun initSenderSpinner() {
|
||||
//免打扰(禁用转发)时间段
|
||||
binding!!.tvSilentPeriod.text = mTimeOption[silentPeriodStart] + " ~ " + mTimeOption[silentPeriodEnd]
|
||||
|
||||
Core.sender.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Sender>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, e.toString())
|
||||
}
|
||||
|
||||
override fun onSuccess(senderList: List<Sender>) {
|
||||
if (senderList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_sender_first)
|
||||
return
|
||||
}
|
||||
|
||||
senderListAll = senderList as MutableList<Sender>
|
||||
for (sender in senderList) {
|
||||
val name = if (sender.name.length > 20) sender.name.substring(0, 19) else sender.name
|
||||
senderSpinnerList.add(SenderAdapterItem(name, getDrawable(sender.imageId), sender.id, sender.status))
|
||||
}
|
||||
senderSpinnerAdapter = SenderSpinnerAdapter(senderSpinnerList)
|
||||
.setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spSender.setAdapter(senderSpinnerAdapter)
|
||||
|
||||
if (senderListSelected.isNotEmpty()) {
|
||||
for (sender in senderListSelected) {
|
||||
for (senderItem in senderSpinnerList) {
|
||||
if (sender.id == senderItem.id) {
|
||||
addSenderItemLinearLayout(senderItemMap, binding!!.layoutSenders, senderItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
//初始化发送通道下拉框
|
||||
binding!!.spSender.setOnItemClickListener { _: AdapterView<*>, _: View, position: Int, _: Long ->
|
||||
try {
|
||||
val sender = senderSpinnerAdapter.getItemSource(position) as SenderAdapterItem
|
||||
senderId = sender.id!!
|
||||
val item = senderSpinnerAdapter.getItemSource(position) as SenderSpinnerItem
|
||||
senderId = item.id!!
|
||||
if (senderId > 0L) {
|
||||
senderListSelected.forEach {
|
||||
if (senderId == it.id) {
|
||||
|
@ -453,11 +426,14 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
|||
senderListAll.forEach {
|
||||
if (senderId == it.id) {
|
||||
senderListSelected.add(it)
|
||||
addSenderItemLinearLayout(senderItemMap, binding!!.layoutSenders, sender)
|
||||
}
|
||||
}
|
||||
|
||||
if (STATUS_OFF == sender.status) {
|
||||
checkSenderLogicShow()
|
||||
|
||||
senderRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
if (STATUS_OFF == item.status) {
|
||||
XToastUtils.warning(getString(R.string.sender_disabled_tips))
|
||||
}
|
||||
}
|
||||
|
@ -465,60 +441,80 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
|||
XToastUtils.error(e.message.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化已选发送通道列表 RecyclerView 和 Adapter
|
||||
senderRecyclerView = binding!!.recyclerSenders
|
||||
senderRecyclerAdapter = SenderRecyclerAdapter(senderListSelected, { position ->
|
||||
senderListSelected.removeAt(position)
|
||||
senderRecyclerAdapter.notifyItemRemoved(position)
|
||||
senderRecyclerAdapter.notifyItemRangeChanged(position, senderListSelected.size) // 更新索引
|
||||
checkSenderLogicShow()
|
||||
})
|
||||
senderRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = senderRecyclerAdapter
|
||||
}
|
||||
val senderMoveCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
Log.d(TAG, "onItemMove: $fromPosition $toPosition")
|
||||
senderRecyclerAdapter.onItemMove(fromPosition, toPosition)
|
||||
senderListSelected = senderRecyclerAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
senderListSelected = senderRecyclerAdapter.itemList
|
||||
//senderRecyclerAdapter.notifyDataSetChanged()
|
||||
Log.d(TAG, "onDragFinished: $senderListSelected")
|
||||
}
|
||||
})
|
||||
val senderTouchHelper = ItemTouchHelper(senderMoveCallback)
|
||||
senderTouchHelper.attachToRecyclerView(senderRecyclerView)
|
||||
senderRecyclerAdapter.setTouchHelper(senderTouchHelper)
|
||||
|
||||
//获取发送通道列表
|
||||
getSenderList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态增删Sender
|
||||
*
|
||||
* @param senderItemMap 管理item的map,用于删除指定header
|
||||
* @param layoutSenders 需要挂载item的LinearLayout
|
||||
* @param sender SenderAdapterItem
|
||||
*/
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun addSenderItemLinearLayout(
|
||||
senderItemMap: MutableMap<Long, LinearLayout>, layoutSenders: LinearLayout, sender: SenderAdapterItem
|
||||
) {
|
||||
val layoutSenderItem = View.inflate(requireContext(), R.layout.item_add_sender, null) as LinearLayout
|
||||
val ivRemoveSender = layoutSenderItem.findViewById<ImageView>(R.id.iv_remove_sender)
|
||||
val ivSenderImage = layoutSenderItem.findViewById<ImageView>(R.id.iv_sender_image)
|
||||
val ivSenderStatus = layoutSenderItem.findViewById<ImageView>(R.id.iv_sender_status)
|
||||
val tvSenderName = layoutSenderItem.findViewById<TextView>(R.id.tv_sender_name)
|
||||
//获取发送通道列表
|
||||
private fun getSenderList() {
|
||||
Core.sender.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Sender>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
ivSenderImage.setImageDrawable(sender.icon)
|
||||
ivSenderStatus.setImageDrawable(getDrawable(if (STATUS_OFF == sender.status) R.drawable.ic_stop else R.drawable.ic_start))
|
||||
val senderItemId = sender.id as Long
|
||||
tvSenderName.text = "ID-$senderItemId:${sender.title}"
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "getSenderList error: ${e.message}")
|
||||
}
|
||||
|
||||
ivRemoveSender.tag = senderItemId
|
||||
ivRemoveSender.setOnClickListener { view2: View ->
|
||||
val tagId = view2.tag as Long
|
||||
layoutSenders.removeView(senderItemMap[tagId])
|
||||
senderItemMap.remove(tagId)
|
||||
//senderListSelected.removeIf { it.id == tagId }
|
||||
for (it in senderListSelected) {
|
||||
if (it.id == tagId) {
|
||||
senderListSelected -= it
|
||||
break
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onSuccess(senderList: List<Sender>) {
|
||||
if (senderList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_sender_first)
|
||||
return
|
||||
}
|
||||
|
||||
senderSpinnerList.clear()
|
||||
senderListAll = senderList as MutableList<Sender>
|
||||
for (sender in senderList) {
|
||||
val name = if (sender.name.length > 20) sender.name.substring(0, 19) else sender.name
|
||||
senderSpinnerList.add(SenderSpinnerItem(name, getDrawable(sender.imageId), sender.id, sender.status))
|
||||
}
|
||||
senderSpinnerAdapter = SenderSpinnerAdapter(senderSpinnerList).setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spSender.setAdapter(senderSpinnerAdapter)
|
||||
//senderSpinnerAdapter.notifyDataSetChanged()
|
||||
|
||||
//更新senderListSelected的状态与名称
|
||||
senderListSelected.forEach {
|
||||
senderListAll.forEach { sender ->
|
||||
if (it.id == sender.id) {
|
||||
it.name = sender.name
|
||||
it.status = sender.status
|
||||
}
|
||||
}
|
||||
}
|
||||
senderRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
}
|
||||
Log.d(TAG, senderListSelected.count().toString())
|
||||
Log.d(TAG, senderListSelected.toString())
|
||||
if (senderListSelected.isEmpty()) senderId = 0L
|
||||
if (senderListSelected.count() > 1) {
|
||||
binding!!.layoutSenderLogic.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding!!.layoutSenderLogic.visibility = View.GONE
|
||||
binding!!.rgSenderLogic.check(R.id.rb_sender_logic_all)
|
||||
}
|
||||
}
|
||||
layoutSenders.addView(layoutSenderItem)
|
||||
senderItemMap[senderItemId] = layoutSenderItem
|
||||
if (senderListSelected.count() > 1) {
|
||||
binding!!.layoutSenderLogic.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding!!.layoutSenderLogic.visibility = View.GONE
|
||||
binding!!.rgSenderLogic.check(R.id.rb_sender_logic_all)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//初始化APP下拉列表
|
||||
|
@ -581,6 +577,7 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
|||
rule.senderList.forEach {
|
||||
senderId = it.id
|
||||
senderListSelected.add(it)
|
||||
Log.d(TAG, it.toString())
|
||||
}
|
||||
|
||||
if (isClone) {
|
||||
|
@ -591,6 +588,7 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
|||
}
|
||||
Log.d(TAG, rule.toString())
|
||||
|
||||
checkSenderLogicShow()
|
||||
binding!!.rgSenderLogic.check(rule.getSenderLogicCheckId())
|
||||
binding!!.rgSimSlot.check(rule.getSimSlotCheckId())
|
||||
binding!!.rgFiled.check(rule.getFiledCheckId())
|
||||
|
@ -619,6 +617,15 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
|||
})
|
||||
}
|
||||
|
||||
private fun checkSenderLogicShow() {
|
||||
if (senderListSelected.size > 1) {
|
||||
binding!!.layoutSenderLogic.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding!!.layoutSenderLogic.visibility = View.GONE
|
||||
binding!!.rgSenderLogic.check(R.id.rb_sender_logic_all)
|
||||
}
|
||||
}
|
||||
|
||||
//提交前检查表单
|
||||
private fun checkForm(): Rule {
|
||||
if (senderListSelected.isEmpty() || senderId == 0L) {
|
||||
|
@ -677,9 +684,7 @@ class RulesEditFragment : BaseFragment<FragmentRulesEditBinding?>(), View.OnClic
|
|||
else -> CHECK_SIM_SLOT_ALL
|
||||
}
|
||||
val status = if (binding!!.sbStatus.isChecked) STATUS_ON else STATUS_OFF
|
||||
//if (status == STATUS_OFF) {
|
||||
// throw Exception(getString(R.string.invalid_rule_status))
|
||||
//}
|
||||
|
||||
return Rule(
|
||||
ruleId,
|
||||
ruleType,
|
||||
|
|
|
@ -13,9 +13,9 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
|||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.App
|
||||
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.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.core.Core
|
||||
import com.idormy.sms.forwarder.database.entity.Task
|
||||
|
@ -50,7 +50,7 @@ import java.util.*
|
|||
|
||||
|
||||
@Page(name = "自动任务·编辑器")
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION", "UNUSED_PARAMETER", "EmptyMethod")
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION", "UNUSED_PARAMETER", "EmptyMethod", "NotifyDataSetChanged")
|
||||
class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClickListener, RecyclerViewHolder.OnItemClickListener<PageInfo> {
|
||||
|
||||
private val TAG: String = TasksEditFragment::class.java.simpleName
|
||||
|
@ -70,14 +70,13 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
@AutoWired(name = KEY_TASK_CLONE)
|
||||
var isClone: Boolean = false
|
||||
|
||||
private lateinit var recyclerConditions: RecyclerView
|
||||
private lateinit var recyclerActions: RecyclerView
|
||||
|
||||
private lateinit var conditionsRecyclerView: RecyclerView
|
||||
private lateinit var conditionsAdapter: TaskSettingAdapter
|
||||
private lateinit var actionsAdapter: TaskSettingAdapter
|
||||
private var conditionsList = mutableListOf<TaskSetting>()
|
||||
|
||||
private var itemListConditions = mutableListOf<TaskSetting>()
|
||||
private var itemListActions = mutableListOf<TaskSetting>()
|
||||
private lateinit var actionsRecyclerView: RecyclerView
|
||||
private lateinit var actionsAdapter: TaskSettingAdapter
|
||||
private var actionsList = mutableListOf<TaskSetting>()
|
||||
|
||||
private var TASK_CONDITION_FRAGMENT_LIST = listOf(
|
||||
PageInfo(
|
||||
|
@ -218,8 +217,8 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
recyclerConditions = findViewById(R.id.recycler_conditions)
|
||||
recyclerActions = findViewById(R.id.recycler_actions)
|
||||
conditionsRecyclerView = findViewById(R.id.recycler_conditions)
|
||||
actionsRecyclerView = findViewById(R.id.recycler_actions)
|
||||
|
||||
// 初始化 RecyclerView 和 Adapter
|
||||
initRecyclerViews()
|
||||
|
@ -229,34 +228,38 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
Log.d(TAG, "onItemMove: $fromPosition $toPosition")
|
||||
conditionsAdapter.onItemMove(fromPosition, toPosition)
|
||||
conditionsList = conditionsAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
//itemListConditions保持与adapter一致
|
||||
itemListConditions = conditionsAdapter.itemList.toMutableList()
|
||||
Log.d(TAG, "onItemMove: $itemListConditions")
|
||||
//conditionsList保持与adapter一致
|
||||
conditionsList = conditionsAdapter.itemList
|
||||
Log.d(TAG, "onDragFinished: $conditionsList")
|
||||
//conditionsAdapter.notifyDataSetChanged()
|
||||
}
|
||||
})
|
||||
|
||||
val itemTouchHelperConditions = ItemTouchHelper(conditionsCallback)
|
||||
itemTouchHelperConditions.attachToRecyclerView(recyclerConditions)
|
||||
itemTouchHelperConditions.attachToRecyclerView(conditionsRecyclerView)
|
||||
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)
|
||||
actionsList = actionsAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
//itemListActions保持与adapter一致
|
||||
itemListActions = actionsAdapter.itemList.toMutableList()
|
||||
Log.d(TAG, "onItemMove: $itemListActions")
|
||||
//actionsList保持与adapter一致
|
||||
actionsList = actionsAdapter.itemList
|
||||
Log.d(TAG, "onDragFinished: $actionsList")
|
||||
//actionsAdapter.notifyDataSetChanged()
|
||||
}
|
||||
})
|
||||
|
||||
val itemTouchHelperActions = ItemTouchHelper(actionsCallback)
|
||||
itemTouchHelperActions.attachToRecyclerView(recyclerActions)
|
||||
itemTouchHelperActions.attachToRecyclerView(actionsRecyclerView)
|
||||
actionsAdapter.setTouchHelper(itemTouchHelperActions)
|
||||
|
||||
if (taskId <= 0) { //新增
|
||||
|
@ -284,7 +287,7 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
R.id.layout_add_condition -> {
|
||||
val bottomSheet: View = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_task_condition_bottom_sheet, null)
|
||||
val tvTitle: TextView = bottomSheet.findViewById(R.id.tv_title)
|
||||
tvTitle.text = if (itemListConditions.isEmpty()) getString(R.string.select_task_trigger) else getString(R.string.select_task_condition)
|
||||
tvTitle.text = if (conditionsList.isEmpty()) getString(R.string.select_task_trigger) else getString(R.string.select_task_condition)
|
||||
|
||||
val recyclerView: RecyclerView = bottomSheet.findViewById(R.id.recyclerView)
|
||||
WidgetUtils.initGridRecyclerView(recyclerView, 4, DensityUtils.dp2px(1f))
|
||||
|
@ -386,20 +389,20 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
if (task.conditions.isNotEmpty()) {
|
||||
val conditionList = Gson().fromJson(task.conditions, Array<TaskSetting>::class.java).toMutableList()
|
||||
for (condition in conditionList) {
|
||||
itemListConditions.add(condition)
|
||||
this@TasksEditFragment.conditionsList.add(condition)
|
||||
}
|
||||
Log.d(TAG, "itemListConditions: $itemListConditions")
|
||||
Log.d(TAG, "conditionsList: ${this@TasksEditFragment.conditionsList}")
|
||||
conditionsAdapter.notifyDataSetChanged()
|
||||
binding!!.layoutAddCondition.visibility = if (itemListConditions.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
binding!!.layoutAddCondition.visibility = if (this@TasksEditFragment.conditionsList.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
}
|
||||
if (task.actions.isNotEmpty()) {
|
||||
val actionList = Gson().fromJson(task.actions, Array<TaskSetting>::class.java).toMutableList()
|
||||
for (action in actionList) {
|
||||
itemListActions.add(action)
|
||||
this@TasksEditFragment.actionsList.add(action)
|
||||
}
|
||||
Log.d(TAG, "itemListActions: $itemListActions")
|
||||
Log.d(TAG, "actionsList: ${this@TasksEditFragment.actionsList}")
|
||||
actionsAdapter.notifyDataSetChanged()
|
||||
binding!!.layoutAddAction.visibility = if (itemListActions.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
binding!!.layoutAddAction.visibility = if (this@TasksEditFragment.actionsList.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
@ -416,10 +419,10 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
if (taskName.isEmpty()) {
|
||||
throw Exception("请输入任务名称")
|
||||
}
|
||||
if (itemListConditions.size <= 0) {
|
||||
if (conditionsList.size <= 0) {
|
||||
throw Exception("请添加触发条件")
|
||||
}
|
||||
if (itemListActions.size <= 0) {
|
||||
if (actionsList.size <= 0) {
|
||||
throw Exception("请添加执行动作")
|
||||
}
|
||||
|
||||
|
@ -427,7 +430,7 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
// 将毫秒部分设置为 0,避免因为毫秒部分不同导致的任务重复执行
|
||||
lastExecTime.time = lastExecTime.time / 1000 * 1000
|
||||
var nextExecTime = lastExecTime
|
||||
val firstCondition = itemListConditions[0]
|
||||
val firstCondition = conditionsList[0]
|
||||
taskType = firstCondition.type
|
||||
|
||||
when (taskType) {
|
||||
|
@ -445,13 +448,13 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
//拼接任务描述
|
||||
val description = StringBuilder()
|
||||
description.append(getString(R.string.task_conditions)).append(" ")
|
||||
description.append(itemListConditions.map { it.description }.toTypedArray().joinToString(","))
|
||||
description.append(conditionsList.map { it.description }.toTypedArray().joinToString(","))
|
||||
description.append(" ").append(getString(R.string.task_actions)).append(" ")
|
||||
description.append(itemListActions.map { it.description }.toTypedArray().joinToString(","))
|
||||
description.append(actionsList.map { it.description }.toTypedArray().joinToString(","))
|
||||
|
||||
val status = if (binding!!.sbStatus.isChecked) STATUS_ON else STATUS_OFF
|
||||
return Task(
|
||||
taskId, taskType, taskName, description.toString(), Gson().toJson(itemListConditions), Gson().toJson(itemListActions), status, lastExecTime, nextExecTime
|
||||
taskId, taskType, taskName, description.toString(), Gson().toJson(conditionsList), Gson().toJson(actionsList), status, lastExecTime, nextExecTime
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -481,7 +484,7 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
if (widgetInfo.classPath.contains(".condition.")) {
|
||||
val typeCondition = pos + KEY_BACK_CODE_CONDITION
|
||||
//判断是否已经添加过该类型条件
|
||||
for (item in itemListConditions) {
|
||||
for (item in conditionsList) {
|
||||
//注意:TASK_CONDITION_XXX 枚举值 等于 TASK_CONDITION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_CONDITION,不可改变
|
||||
if (item.type == typeCondition) {
|
||||
XToastUtils.error(getString(R.string.condition_already_exists))
|
||||
|
@ -514,7 +517,7 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
} else {
|
||||
val typeAction = pos + KEY_BACK_CODE_ACTION
|
||||
//判断是否已经添加过该类型动作
|
||||
for (item in itemListActions) {
|
||||
for (item in actionsList) {
|
||||
//注意:TASK_ACTION_XXX 枚举值 等于 TASK_ACTION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_ACTION,不可改变
|
||||
if (item.type == typeAction) {
|
||||
XToastUtils.error(getString(R.string.action_already_exists))
|
||||
|
@ -549,15 +552,17 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
val widgetInfo = TASK_CONDITION_FRAGMENT_LIST[widgetInfoIndex]
|
||||
description = extras.getString(KEY_BACK_DESCRIPTION_CONDITION) ?: widgetInfo.name.toString()
|
||||
val taskSetting = TaskSetting(resultCode, widgetInfo.name, description, setting, requestCode)
|
||||
//requestCode: 等于 itemListConditions 的索引加1
|
||||
//requestCode: 等于 conditionsList 的索引加1
|
||||
if (requestCode == 0) {
|
||||
taskSetting.position = itemListConditions.size
|
||||
itemListConditions.add(taskSetting)
|
||||
taskSetting.position = conditionsList.size
|
||||
conditionsList.add(taskSetting)
|
||||
conditionsAdapter.notifyItemInserted(conditionsList.size - 1)
|
||||
} else {
|
||||
itemListConditions[requestCode - 1] = taskSetting
|
||||
conditionsList[requestCode - 1] = taskSetting
|
||||
conditionsAdapter.notifyItemChanged(requestCode - 1)
|
||||
}
|
||||
conditionsAdapter.notifyDataSetChanged()
|
||||
binding!!.layoutAddCondition.visibility = if (itemListConditions.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
//conditionsAdapter.notifyDataSetChanged()
|
||||
binding!!.layoutAddCondition.visibility = if (conditionsList.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
} else if (resultCode in KEY_BACK_CODE_ACTION..KEY_BACK_CODE_ACTION + 999) {
|
||||
setting = extras.getString(KEY_BACK_DATA_ACTION) ?: return
|
||||
//注意:TASK_ACTION_XXX 枚举值 等于 TASK_ACTION_FRAGMENT_LIST 索引加上 KEY_BACK_CODE_ACTION,不可改变
|
||||
|
@ -566,31 +571,33 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
val widgetInfo = TASK_ACTION_FRAGMENT_LIST[widgetInfoIndex]
|
||||
description = extras.getString(KEY_BACK_DESCRIPTION_ACTION) ?: widgetInfo.name.toString()
|
||||
val taskSetting = TaskSetting(resultCode, widgetInfo.name, description, setting, requestCode)
|
||||
//requestCode: 等于 itemListActions 的索引加1
|
||||
//requestCode: 等于 actionsList 的索引加1
|
||||
if (requestCode == 0) {
|
||||
taskSetting.position = itemListActions.size
|
||||
itemListActions.add(taskSetting)
|
||||
taskSetting.position = actionsList.size
|
||||
actionsList.add(taskSetting)
|
||||
actionsAdapter.notifyItemInserted(actionsList.size - 1)
|
||||
} else {
|
||||
itemListActions[requestCode - 1] = taskSetting
|
||||
actionsList[requestCode - 1] = taskSetting
|
||||
actionsAdapter.notifyItemChanged(requestCode - 1)
|
||||
}
|
||||
actionsAdapter.notifyDataSetChanged()
|
||||
binding!!.layoutAddAction.visibility = if (itemListActions.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
//actionsAdapter.notifyDataSetChanged()
|
||||
binding!!.layoutAddAction.visibility = if (actionsList.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
}
|
||||
Log.d(TAG, "requestCode:$requestCode resultCode:$resultCode setting:$setting")
|
||||
}
|
||||
}
|
||||
|
||||
private fun initRecyclerViews() {
|
||||
conditionsAdapter = TaskSettingAdapter(itemListConditions, { position -> editCondition(position) }, { position -> removeCondition(position) })
|
||||
conditionsAdapter = TaskSettingAdapter(conditionsList, { position -> removeCondition(position) }, { position -> editCondition(position) })
|
||||
|
||||
actionsAdapter = TaskSettingAdapter(itemListActions, { position -> editAction(position) }, { position -> removeAction(position) })
|
||||
actionsAdapter = TaskSettingAdapter(actionsList, { position -> removeAction(position) }, { position -> editAction(position) })
|
||||
|
||||
recyclerConditions.apply {
|
||||
conditionsRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = conditionsAdapter
|
||||
}
|
||||
|
||||
recyclerActions.apply {
|
||||
actionsRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = actionsAdapter
|
||||
}
|
||||
|
@ -599,42 +606,48 @@ class TasksEditFragment : BaseFragment<FragmentTasksEditBinding?>(), View.OnClic
|
|||
private fun editCondition(position: Int) {
|
||||
// 实现编辑条件项目的逻辑
|
||||
// 根据 position 对特定项目进行编辑
|
||||
val condition = itemListConditions[position]
|
||||
val condition = conditionsList[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<XPageFragment>) //跳转的fragment
|
||||
.setRequestCode(position + 1) //requestCode: 0 新增 、>0 编辑(itemListConditions 的索引加1)
|
||||
.putString(KEY_EVENT_DATA_CONDITION, condition.setting).open(this)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
PageOption.to(Class.forName(widgetInfo.classPath) as Class<XPageFragment>) //跳转的fragment
|
||||
.setRequestCode(position + 1) //requestCode: 0 新增 、>0 编辑(conditionsList 的索引加1)
|
||||
.putString(KEY_EVENT_DATA_CONDITION, condition.setting)
|
||||
.open(this)
|
||||
}
|
||||
|
||||
private fun removeCondition(position: Int) {
|
||||
itemListConditions.removeAt(position)
|
||||
conditionsList.removeAt(position)
|
||||
conditionsAdapter.notifyItemRemoved(position)
|
||||
binding!!.layoutAddCondition.visibility = if (itemListConditions.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
conditionsAdapter.notifyItemRangeChanged(position, conditionsList.size) // 更新索引
|
||||
binding!!.layoutAddCondition.visibility = if (conditionsList.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
private fun editAction(position: Int) {
|
||||
// 实现编辑操作项目的逻辑
|
||||
// 根据 position 对特定项目进行编辑
|
||||
val action = itemListActions[position]
|
||||
val action = actionsList[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<XPageFragment>) //跳转的fragment
|
||||
.setRequestCode(position + 1) //requestCode: 0 新增 、>0 编辑(itemListActions 的索引加1)
|
||||
.putString(KEY_EVENT_DATA_ACTION, action.setting).open(this)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
PageOption.to(Class.forName(widgetInfo.classPath) as Class<XPageFragment>) //跳转的fragment
|
||||
.setRequestCode(position + 1) //requestCode: 0 新增 、>0 编辑(actionsList 的索引加1)
|
||||
.putString(KEY_EVENT_DATA_ACTION, action.setting)
|
||||
.open(this)
|
||||
}
|
||||
|
||||
private fun removeAction(position: Int) {
|
||||
itemListActions.removeAt(position)
|
||||
actionsList.removeAt(position)
|
||||
actionsAdapter.notifyItemRemoved(position)
|
||||
binding!!.layoutAddAction.visibility = if (itemListActions.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
actionsAdapter.notifyItemRangeChanged(position, actionsList.size) // 更新索引
|
||||
binding!!.layoutAddAction.visibility = if (actionsList.size >= MAX_SETTING_NUM) View.GONE else View.VISIBLE
|
||||
}
|
||||
}
|
|
@ -6,13 +6,15 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.adapter.spinner.FrpcAdapterItem
|
||||
import com.idormy.sms.forwarder.adapter.FrpcRecyclerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.adapter.spinner.FrpcSpinnerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.spinner.FrpcSpinnerItem
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.core.Core
|
||||
import com.idormy.sms.forwarder.database.entity.Frpc
|
||||
|
@ -23,7 +25,6 @@ import com.idormy.sms.forwarder.utils.KEY_BACK_DESCRIPTION_ACTION
|
|||
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_TEST_ACTION
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.idormy.sms.forwarder.utils.STATUS_ON
|
||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_FRPC
|
||||
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
|
@ -47,16 +48,17 @@ class FrpcFragment : BaseFragment<FragmentTasksActionFrpcBinding?>(), View.OnCli
|
|||
private var titleBar: TitleBar? = null
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
//当前发送通道
|
||||
private var frpcUid = ""
|
||||
private var frpcListSelected: MutableList<Frpc> = mutableListOf()
|
||||
private var frpcItemMap = HashMap<String, LinearLayout>(2)
|
||||
|
||||
//发送通道列表
|
||||
private var frpcListAll: MutableList<Frpc> = mutableListOf()
|
||||
private val frpcSpinnerList = ArrayList<FrpcAdapterItem>()
|
||||
//所有Frpc下拉框
|
||||
private var frpcListAll = mutableListOf<Frpc>()
|
||||
private val frpcSpinnerList = mutableListOf<FrpcSpinnerItem>()
|
||||
private lateinit var frpcSpinnerAdapter: FrpcSpinnerAdapter<*>
|
||||
|
||||
//已选Frpc列表
|
||||
private var frpcUid = ""
|
||||
private var frpcListSelected = mutableListOf<Frpc>()
|
||||
private lateinit var frpcRecyclerView: RecyclerView
|
||||
private lateinit var frpcRecyclerAdapter: FrpcRecyclerAdapter
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_EVENT_DATA_ACTION)
|
||||
var eventData: String? = null
|
||||
|
@ -101,7 +103,7 @@ class FrpcFragment : BaseFragment<FragmentTasksActionFrpcBinding?>(), View.OnCli
|
|||
}
|
||||
|
||||
//初始化发送通道下拉框
|
||||
initFrpcSpinner()
|
||||
initFrpc()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
@ -162,47 +164,14 @@ class FrpcFragment : BaseFragment<FragmentTasksActionFrpcBinding?>(), View.OnCli
|
|||
}
|
||||
}
|
||||
|
||||
//初始化发送通道下拉框
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun initFrpcSpinner() {
|
||||
Core.frpc.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Frpc>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "initFrpcSpinner error: ${e.message}")
|
||||
}
|
||||
|
||||
override fun onSuccess(frpcList: List<Frpc>) {
|
||||
if (frpcList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_frpc_first)
|
||||
return
|
||||
}
|
||||
|
||||
frpcListAll = frpcList as MutableList<Frpc>
|
||||
for (frpc in frpcList) {
|
||||
val name = if (frpc.name.length > 20) frpc.name.substring(0, 19) else frpc.name
|
||||
frpcSpinnerList.add(FrpcAdapterItem(name, getDrawable(R.drawable.auto_task_icon_frpc), frpc.uid, frpc.autorun))
|
||||
}
|
||||
frpcSpinnerAdapter = FrpcSpinnerAdapter(frpcSpinnerList)
|
||||
.setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spFrpc.setAdapter(frpcSpinnerAdapter)
|
||||
|
||||
if (frpcListSelected.isNotEmpty()) {
|
||||
for (frpc in frpcListSelected) {
|
||||
for (frpcItem in frpcSpinnerList) {
|
||||
if (frpc.uid == frpcItem.uid) {
|
||||
addFrpcItemLinearLayout(frpcItemMap, binding!!.layoutFrpcs, frpcItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
//初始化Frpc
|
||||
@SuppressLint("SetTextI18n", "NotifyDataSetChanged")
|
||||
private fun initFrpc() {
|
||||
//初始化Frpc下拉框
|
||||
binding!!.spFrpc.setOnItemClickListener { _: AdapterView<*>, _: View, position: Int, _: Long ->
|
||||
try {
|
||||
val frpc = frpcSpinnerAdapter.getItemSource(position) as FrpcAdapterItem
|
||||
frpcUid = frpc.uid
|
||||
val item = frpcSpinnerAdapter.getItemSource(position) as FrpcSpinnerItem
|
||||
frpcUid = item.uid
|
||||
if (frpcUid.isNotEmpty()) {
|
||||
frpcListSelected.forEach {
|
||||
if (frpcUid == it.uid) {
|
||||
|
@ -213,60 +182,87 @@ class FrpcFragment : BaseFragment<FragmentTasksActionFrpcBinding?>(), View.OnCli
|
|||
frpcListAll.forEach {
|
||||
if (frpcUid == it.uid) {
|
||||
frpcListSelected.add(it)
|
||||
addFrpcItemLinearLayout(frpcItemMap, binding!!.layoutFrpcs, frpc)
|
||||
}
|
||||
}
|
||||
|
||||
/*if (STATUS_OFF == frpc.status) {
|
||||
XToastUtils.warning(getString(R.string.frpc_disabled_tips))
|
||||
}*/
|
||||
frpcRecyclerAdapter.notifyDataSetChanged()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化已选Frpc列表 RecyclerView 和 Adapter
|
||||
frpcRecyclerView = binding!!.recyclerFrpcs
|
||||
frpcRecyclerAdapter = FrpcRecyclerAdapter(frpcListSelected, { position ->
|
||||
frpcListSelected.removeAt(position)
|
||||
frpcRecyclerAdapter.notifyItemRemoved(position)
|
||||
frpcRecyclerAdapter.notifyItemRangeChanged(position, frpcListSelected.size) // 更新索引
|
||||
})
|
||||
frpcRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = frpcRecyclerAdapter
|
||||
}
|
||||
val frpcMoveCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
Log.d(TAG, "onItemMove: $fromPosition $toPosition")
|
||||
frpcRecyclerAdapter.onItemMove(fromPosition, toPosition)
|
||||
frpcListSelected = frpcRecyclerAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
frpcListSelected = frpcRecyclerAdapter.itemList
|
||||
//frpcRecyclerAdapter.notifyDataSetChanged()
|
||||
Log.d(TAG, "onDragFinished: $frpcListSelected")
|
||||
}
|
||||
})
|
||||
val frpcTouchHelper = ItemTouchHelper(frpcMoveCallback)
|
||||
frpcTouchHelper.attachToRecyclerView(frpcRecyclerView)
|
||||
frpcRecyclerAdapter.setTouchHelper(frpcTouchHelper)
|
||||
|
||||
//获取Frpc列表
|
||||
getFrpcList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态增删Frpc
|
||||
*
|
||||
* @param frpcItemMap 管理item的map,用于删除指定header
|
||||
* @param layoutFrpcs 需要挂载item的LinearLayout
|
||||
* @param frpc FrpcAdapterItem
|
||||
*/
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun addFrpcItemLinearLayout(
|
||||
frpcItemMap: MutableMap<String, LinearLayout>, layoutFrpcs: LinearLayout, frpc: FrpcAdapterItem
|
||||
) {
|
||||
val layoutFrpcItem = View.inflate(requireContext(), R.layout.item_add_frpc, null) as LinearLayout
|
||||
val ivRemoveFrpc = layoutFrpcItem.findViewById<ImageView>(R.id.iv_remove_frpc)
|
||||
val ivFrpcImage = layoutFrpcItem.findViewById<ImageView>(R.id.iv_frpc_image)
|
||||
val ivFrpcStatus = layoutFrpcItem.findViewById<ImageView>(R.id.iv_frpc_status)
|
||||
val tvFrpcName = layoutFrpcItem.findViewById<TextView>(R.id.tv_frpc_name)
|
||||
//获取Frpc列表
|
||||
private fun getFrpcList() {
|
||||
Core.frpc.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Frpc>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
ivFrpcImage.setImageDrawable(frpc.icon)
|
||||
ivFrpcStatus.setImageDrawable(getDrawable(if (STATUS_ON == frpc.autorun) R.drawable.ic_autorun else R.drawable.ic_manual))
|
||||
val frpcItemId = frpc.uid
|
||||
tvFrpcName.text = frpc.title
|
||||
|
||||
ivRemoveFrpc.tag = frpcItemId
|
||||
ivRemoveFrpc.setOnClickListener { view2: View ->
|
||||
val tagId = view2.tag
|
||||
layoutFrpcs.removeView(frpcItemMap[tagId])
|
||||
frpcItemMap.remove(tagId)
|
||||
//frpcListSelected.removeIf { it.uid == tagId }
|
||||
for (it in frpcListSelected) {
|
||||
if (it.uid == tagId) {
|
||||
frpcListSelected -= it
|
||||
break
|
||||
}
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "getFrpcList error: ${e.message}")
|
||||
}
|
||||
Log.d(TAG, frpcListSelected.count().toString())
|
||||
Log.d(TAG, frpcListSelected.toString())
|
||||
if (frpcListSelected.isEmpty()) frpcUid = ""
|
||||
}
|
||||
layoutFrpcs.addView(layoutFrpcItem)
|
||||
frpcItemMap[frpcItemId] = layoutFrpcItem
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onSuccess(frpcList: List<Frpc>) {
|
||||
if (frpcList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_frpc_first)
|
||||
return
|
||||
}
|
||||
|
||||
frpcSpinnerList.clear()
|
||||
frpcListAll = frpcList as MutableList<Frpc>
|
||||
for (frpc in frpcList) {
|
||||
val name = if (frpc.name.length > 20) frpc.name.substring(0, 19) else frpc.name
|
||||
frpcSpinnerList.add(FrpcSpinnerItem(name, getDrawable(R.drawable.auto_task_icon_frpc), frpc.uid, frpc.autorun))
|
||||
}
|
||||
frpcSpinnerAdapter = FrpcSpinnerAdapter(frpcSpinnerList).setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spFrpc.setAdapter(frpcSpinnerAdapter)
|
||||
//frpcSpinnerAdapter.notifyDataSetChanged()
|
||||
|
||||
//更新frpcListSelected的状态与名称
|
||||
frpcListSelected.forEach {
|
||||
frpcListAll.forEach { frpc ->
|
||||
if (it.uid == frpc.uid) {
|
||||
it.name = frpc.name
|
||||
it.autorun = frpc.autorun
|
||||
}
|
||||
}
|
||||
}
|
||||
frpcRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//检查设置
|
||||
|
|
|
@ -6,10 +6,15 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderAdapterItem
|
||||
import com.idormy.sms.forwarder.adapter.SenderRecyclerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderSpinnerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderSpinnerItem
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.core.Core
|
||||
import com.idormy.sms.forwarder.database.entity.Rule
|
||||
|
@ -52,16 +57,17 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
|||
private var silentPeriodStart = 0
|
||||
private var silentPeriodEnd = 0
|
||||
|
||||
//当前发送通道
|
||||
var senderId = 0L
|
||||
var senderListSelected: MutableList<Sender> = mutableListOf()
|
||||
private var senderItemMap = HashMap<Long, LinearLayout>(2)
|
||||
|
||||
//发送通道列表
|
||||
var senderListAll: MutableList<Sender> = mutableListOf()
|
||||
private val senderSpinnerList = ArrayList<SenderAdapterItem>()
|
||||
//所有发送通道下拉框
|
||||
private var senderListAll = mutableListOf<Sender>()
|
||||
private val senderSpinnerList = mutableListOf<SenderSpinnerItem>()
|
||||
private lateinit var senderSpinnerAdapter: SenderSpinnerAdapter<*>
|
||||
|
||||
//已选发送通道列表
|
||||
private var senderId = 0L
|
||||
private var senderListSelected = mutableListOf<Sender>()
|
||||
private lateinit var sendersRecyclerView: RecyclerView
|
||||
private lateinit var senderRecyclerAdapter: SenderRecyclerAdapter
|
||||
|
||||
private var ruleId: Long = 0
|
||||
private var ruleType: String = "app"
|
||||
|
||||
|
@ -109,6 +115,7 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
|||
senderListSelected.add(it)
|
||||
}
|
||||
|
||||
checkSenderLogicShow()
|
||||
binding!!.rgSenderLogic.check(settingVo.getSenderLogicCheckId())
|
||||
if (!TextUtils.isEmpty(settingVo.smsTemplate.trim())) {
|
||||
binding!!.sbSmsTemplate.isChecked = true
|
||||
|
@ -293,49 +300,16 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
|||
}
|
||||
|
||||
//初始化发送通道下拉框
|
||||
@SuppressLint("SetTextI18n")
|
||||
@SuppressLint("SetTextI18n", "NotifyDataSetChanged")
|
||||
private fun initSenderSpinner() {
|
||||
//免打扰(禁用转发)时间段
|
||||
binding!!.tvSilentPeriod.text = mTimeOption[silentPeriodStart] + " ~ " + mTimeOption[silentPeriodEnd]
|
||||
|
||||
Core.sender.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Sender>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "initSenderSpinner error: ${e.message}")
|
||||
}
|
||||
|
||||
override fun onSuccess(senderList: List<Sender>) {
|
||||
if (senderList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_sender_first)
|
||||
return
|
||||
}
|
||||
|
||||
senderListAll = senderList as MutableList<Sender>
|
||||
for (sender in senderList) {
|
||||
val name = if (sender.name.length > 20) sender.name.substring(0, 19) else sender.name
|
||||
senderSpinnerList.add(SenderAdapterItem(name, getDrawable(sender.imageId), sender.id, sender.status))
|
||||
}
|
||||
senderSpinnerAdapter = SenderSpinnerAdapter(senderSpinnerList)
|
||||
.setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spSender.setAdapter(senderSpinnerAdapter)
|
||||
|
||||
if (senderListSelected.isNotEmpty()) {
|
||||
for (sender in senderListSelected) {
|
||||
for (senderItem in senderSpinnerList) {
|
||||
if (sender.id == senderItem.id) {
|
||||
addSenderItemLinearLayout(senderItemMap, binding!!.layoutSenders, senderItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
//初始化发送通道下拉框
|
||||
binding!!.spSender.setOnItemClickListener { _: AdapterView<*>, _: View, position: Int, _: Long ->
|
||||
try {
|
||||
val sender = senderSpinnerAdapter.getItemSource(position) as SenderAdapterItem
|
||||
senderId = sender.id!!
|
||||
val item = senderSpinnerAdapter.getItemSource(position) as SenderSpinnerItem
|
||||
senderId = item.id!!
|
||||
if (senderId > 0L) {
|
||||
senderListSelected.forEach {
|
||||
if (senderId == it.id) {
|
||||
|
@ -346,11 +320,14 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
|||
senderListAll.forEach {
|
||||
if (senderId == it.id) {
|
||||
senderListSelected.add(it)
|
||||
addSenderItemLinearLayout(senderItemMap, binding!!.layoutSenders, sender)
|
||||
}
|
||||
}
|
||||
|
||||
if (STATUS_OFF == sender.status) {
|
||||
checkSenderLogicShow()
|
||||
|
||||
senderRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
if (STATUS_OFF == item.status) {
|
||||
XToastUtils.warning(getString(R.string.sender_disabled_tips))
|
||||
}
|
||||
}
|
||||
|
@ -358,55 +335,84 @@ class NotificationFragment : BaseFragment<FragmentTasksActionNotificationBinding
|
|||
XToastUtils.error(e.message.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化已选发送通道列表 RecyclerView 和 Adapter
|
||||
sendersRecyclerView = binding!!.recyclerSenders
|
||||
senderRecyclerAdapter = SenderRecyclerAdapter(senderListSelected, { position ->
|
||||
senderListSelected.removeAt(position)
|
||||
senderRecyclerAdapter.notifyItemRemoved(position)
|
||||
senderRecyclerAdapter.notifyItemRangeChanged(position, senderListSelected.size) // 更新索引
|
||||
checkSenderLogicShow()
|
||||
})
|
||||
sendersRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = senderRecyclerAdapter
|
||||
}
|
||||
val senderMoveCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
Log.d(TAG, "onItemMove: $fromPosition $toPosition")
|
||||
senderRecyclerAdapter.onItemMove(fromPosition, toPosition)
|
||||
senderListSelected = senderRecyclerAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
senderListSelected = senderRecyclerAdapter.itemList
|
||||
//senderRecyclerAdapter.notifyDataSetChanged()
|
||||
Log.d(TAG, "onDragFinished: $senderListSelected")
|
||||
}
|
||||
})
|
||||
val senderTouchHelper = ItemTouchHelper(senderMoveCallback)
|
||||
senderTouchHelper.attachToRecyclerView(sendersRecyclerView)
|
||||
senderRecyclerAdapter.setTouchHelper(senderTouchHelper)
|
||||
|
||||
//获取发送通道列表
|
||||
getSenderList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态增删Sender
|
||||
*
|
||||
* @param senderItemMap 管理item的map,用于删除指定header
|
||||
* @param layoutSenders 需要挂载item的LinearLayout
|
||||
* @param sender SenderAdapterItem
|
||||
*/
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun addSenderItemLinearLayout(
|
||||
senderItemMap: MutableMap<Long, LinearLayout>, layoutSenders: LinearLayout, sender: SenderAdapterItem
|
||||
) {
|
||||
val layoutSenderItem = View.inflate(requireContext(), R.layout.item_add_sender, null) as LinearLayout
|
||||
val ivRemoveSender = layoutSenderItem.findViewById<ImageView>(R.id.iv_remove_sender)
|
||||
val ivSenderImage = layoutSenderItem.findViewById<ImageView>(R.id.iv_sender_image)
|
||||
val ivSenderStatus = layoutSenderItem.findViewById<ImageView>(R.id.iv_sender_status)
|
||||
val tvSenderName = layoutSenderItem.findViewById<TextView>(R.id.tv_sender_name)
|
||||
//获取发送通道列表
|
||||
private fun getSenderList() {
|
||||
Core.sender.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Sender>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
ivSenderImage.setImageDrawable(sender.icon)
|
||||
ivSenderStatus.setImageDrawable(getDrawable(if (STATUS_OFF == sender.status) R.drawable.ic_stop else R.drawable.ic_start))
|
||||
val senderItemId = sender.id as Long
|
||||
tvSenderName.text = "ID-$senderItemId:${sender.title}"
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "getSenderList error: ${e.message}")
|
||||
}
|
||||
|
||||
ivRemoveSender.tag = senderItemId
|
||||
ivRemoveSender.setOnClickListener { view2: View ->
|
||||
val tagId = view2.tag as Long
|
||||
layoutSenders.removeView(senderItemMap[tagId])
|
||||
senderItemMap.remove(tagId)
|
||||
//senderListSelected.removeIf { it.id == tagId }
|
||||
for (it in senderListSelected) {
|
||||
if (it.id == tagId) {
|
||||
senderListSelected -= it
|
||||
break
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onSuccess(senderList: List<Sender>) {
|
||||
if (senderList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_sender_first)
|
||||
return
|
||||
}
|
||||
|
||||
senderSpinnerList.clear()
|
||||
senderListAll = senderList as MutableList<Sender>
|
||||
for (sender in senderList) {
|
||||
val name = if (sender.name.length > 20) sender.name.substring(0, 19) else sender.name
|
||||
senderSpinnerList.add(SenderSpinnerItem(name, getDrawable(sender.imageId), sender.id, sender.status))
|
||||
}
|
||||
senderSpinnerAdapter = SenderSpinnerAdapter(senderSpinnerList).setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spSender.setAdapter(senderSpinnerAdapter)
|
||||
//senderSpinnerAdapter.notifyDataSetChanged()
|
||||
|
||||
//更新senderListSelected的状态与名称
|
||||
senderListSelected.forEach {
|
||||
senderListAll.forEach { sender ->
|
||||
if (it.id == sender.id) {
|
||||
it.name = sender.name
|
||||
it.status = sender.status
|
||||
}
|
||||
}
|
||||
}
|
||||
senderRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
}
|
||||
Log.d(TAG, senderListSelected.count().toString())
|
||||
Log.d(TAG, senderListSelected.toString())
|
||||
if (senderListSelected.isEmpty()) senderId = 0L
|
||||
if (senderListSelected.count() > 1) {
|
||||
binding!!.layoutSenderLogic.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding!!.layoutSenderLogic.visibility = View.GONE
|
||||
binding!!.rgSenderLogic.check(R.id.rb_sender_logic_all)
|
||||
}
|
||||
}
|
||||
layoutSenders.addView(layoutSenderItem)
|
||||
senderItemMap[senderItemId] = layoutSenderItem
|
||||
if (senderListSelected.count() > 1) {
|
||||
})
|
||||
}
|
||||
|
||||
private fun checkSenderLogicShow() {
|
||||
if (senderListSelected.size > 1) {
|
||||
binding!!.layoutSenderLogic.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding!!.layoutSenderLogic.visibility = View.GONE
|
||||
|
|
|
@ -6,27 +6,33 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.work.Data
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.adapter.spinner.RuleAdapterItem
|
||||
import com.idormy.sms.forwarder.adapter.RuleRecyclerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.adapter.spinner.RuleSpinnerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.spinner.RuleSpinnerItem
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.core.Core
|
||||
import com.idormy.sms.forwarder.database.entity.Rule
|
||||
import com.idormy.sms.forwarder.databinding.FragmentTasksActionRuleBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.TaskSetting
|
||||
import com.idormy.sms.forwarder.entity.action.RuleSetting
|
||||
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_BACK_DESCRIPTION_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_TEST_ACTION
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.idormy.sms.forwarder.utils.STATUS_OFF
|
||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_RULE
|
||||
import com.idormy.sms.forwarder.utils.TaskWorker
|
||||
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.idormy.sms.forwarder.workers.ActionWorker
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
|
@ -38,25 +44,27 @@ import io.reactivex.SingleObserver
|
|||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.Date
|
||||
|
||||
@Page(name = "Rule")
|
||||
@Suppress("PrivatePropertyName")
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||
class RuleFragment : BaseFragment<FragmentTasksActionRuleBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = RuleFragment::class.java.simpleName
|
||||
private var titleBar: TitleBar? = null
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
//当前转发规则
|
||||
private var ruleId = 0L
|
||||
private var ruleListSelected: MutableList<Rule> = mutableListOf()
|
||||
private var ruleItemMap = HashMap<Long, LinearLayout>(2)
|
||||
|
||||
//转发规则列表
|
||||
private var ruleListAll: MutableList<Rule> = mutableListOf()
|
||||
private val ruleSpinnerList = ArrayList<RuleAdapterItem>()
|
||||
//所有转发规则下拉框
|
||||
private var ruleListAll = mutableListOf<Rule>()
|
||||
private val ruleSpinnerList = mutableListOf<RuleSpinnerItem>()
|
||||
private lateinit var ruleSpinnerAdapter: RuleSpinnerAdapter<*>
|
||||
|
||||
//已选转发规则列表
|
||||
private var ruleId = 0L
|
||||
private var ruleListSelected = mutableListOf<Rule>()
|
||||
private lateinit var ruleRecyclerView: RecyclerView
|
||||
private lateinit var ruleRecyclerAdapter: RuleRecyclerAdapter
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_EVENT_DATA_ACTION)
|
||||
var eventData: String? = null
|
||||
|
@ -82,7 +90,7 @@ class RuleFragment : BaseFragment<FragmentTasksActionRuleBinding?>(), View.OnCli
|
|||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, 3)
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, 1)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
|
@ -90,6 +98,8 @@ class RuleFragment : BaseFragment<FragmentTasksActionRuleBinding?>(), View.OnCli
|
|||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
//获取转发规则列表
|
||||
getRuleList()
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -106,7 +116,7 @@ class RuleFragment : BaseFragment<FragmentTasksActionRuleBinding?>(), View.OnCli
|
|||
}
|
||||
|
||||
//初始化转发规则下拉框
|
||||
initRuleSpinner()
|
||||
initRule()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
@ -114,15 +124,6 @@ class RuleFragment : BaseFragment<FragmentTasksActionRuleBinding?>(), View.OnCli
|
|||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).observe(this) {
|
||||
mCountDownHelper?.finish()
|
||||
|
||||
if (it == "success") {
|
||||
XToastUtils.success("测试通过", 30000)
|
||||
} else {
|
||||
XToastUtils.error(it, 30000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
|
@ -131,17 +132,21 @@ class RuleFragment : BaseFragment<FragmentTasksActionRuleBinding?>(), View.OnCli
|
|||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).post("success")
|
||||
} catch (e: Exception) {
|
||||
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).post(e.message.toString())
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "onClick error: ${e.message}")
|
||||
}
|
||||
}.start()
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val taskAction = TaskSetting(TASK_ACTION_RULE, getString(R.string.task_rule), settingVo.description, Gson().toJson(settingVo), requestCode)
|
||||
val taskActionsJson = Gson().toJson(arrayListOf(taskAction))
|
||||
val msgInfo = MsgInfo("task", getString(R.string.task_rule), settingVo.description, Date(), getString(R.string.task_rule))
|
||||
val actionData = Data.Builder().putLong(TaskWorker.taskId, 0).putString(TaskWorker.taskActions, taskActionsJson).putString(TaskWorker.msgInfo, Gson().toJson(msgInfo)).build()
|
||||
val actionRequest = OneTimeWorkRequestBuilder<ActionWorker>().setInputData(actionData).build()
|
||||
WorkManager.getInstance().enqueue(actionRequest)
|
||||
} catch (e: Exception) {
|
||||
mCountDownHelper?.finish()
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "onClick error: ${e.message}")
|
||||
XToastUtils.error(e.message.toString(), 30000)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -167,53 +172,14 @@ class RuleFragment : BaseFragment<FragmentTasksActionRuleBinding?>(), View.OnCli
|
|||
}
|
||||
}
|
||||
|
||||
//初始化转发规则下拉框
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun initRuleSpinner() {
|
||||
Core.rule.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Rule>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "initRuleSpinner error: ${e.message}")
|
||||
}
|
||||
|
||||
override fun onSuccess(ruleList: List<Rule>) {
|
||||
if (ruleList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_rule_first)
|
||||
return
|
||||
}
|
||||
|
||||
ruleListAll = ruleList as MutableList<Rule>
|
||||
for (rule in ruleList) {
|
||||
val name = if (rule.name.length > 20) rule.name.substring(0, 19) else rule.name
|
||||
val icon = when (rule.type) {
|
||||
"sms" -> R.drawable.auto_task_icon_sms
|
||||
"call" -> R.drawable.auto_task_icon_incall
|
||||
"app" -> R.drawable.auto_task_icon_start_activity
|
||||
else -> R.drawable.auto_task_icon_sms
|
||||
}
|
||||
ruleSpinnerList.add(RuleAdapterItem(name, getDrawable(icon), rule.id, rule.status))
|
||||
}
|
||||
ruleSpinnerAdapter = RuleSpinnerAdapter(ruleSpinnerList)
|
||||
.setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spRule.setAdapter(ruleSpinnerAdapter)
|
||||
|
||||
if (ruleListSelected.isNotEmpty()) {
|
||||
for (rule in ruleListSelected) {
|
||||
for (ruleItem in ruleSpinnerList) {
|
||||
if (rule.id == ruleItem.id) {
|
||||
addRuleItemLinearLayout(ruleItemMap, binding!!.layoutRules, ruleItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
//初始化转发规则
|
||||
@SuppressLint("SetTextI18n", "NotifyDataSetChanged")
|
||||
private fun initRule() {
|
||||
//初始化转发规则下拉框
|
||||
binding!!.spRule.setOnItemClickListener { _: AdapterView<*>, _: View, position: Int, _: Long ->
|
||||
try {
|
||||
val rule = ruleSpinnerAdapter.getItemSource(position) as RuleAdapterItem
|
||||
ruleId = rule.id!!
|
||||
val item = ruleSpinnerAdapter.getItemSource(position) as RuleSpinnerItem
|
||||
ruleId = item.id!!
|
||||
if (ruleId > 0L) {
|
||||
ruleListSelected.forEach {
|
||||
if (ruleId == it.id) {
|
||||
|
@ -224,67 +190,100 @@ class RuleFragment : BaseFragment<FragmentTasksActionRuleBinding?>(), View.OnCli
|
|||
ruleListAll.forEach {
|
||||
if (ruleId == it.id) {
|
||||
ruleListSelected.add(it)
|
||||
addRuleItemLinearLayout(ruleItemMap, binding!!.layoutRules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
/*if (STATUS_OFF == rule.status) {
|
||||
XToastUtils.warning(getString(R.string.rule_disabled_tips))
|
||||
}*/
|
||||
ruleRecyclerAdapter.notifyDataSetChanged()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化已选转发规则列表 RecyclerView 和 Adapter
|
||||
ruleRecyclerView = binding!!.recyclerRules
|
||||
ruleRecyclerAdapter = RuleRecyclerAdapter(ruleListSelected, { position ->
|
||||
ruleListSelected.removeAt(position)
|
||||
ruleRecyclerAdapter.notifyItemRemoved(position)
|
||||
ruleRecyclerAdapter.notifyItemRangeChanged(position, ruleListSelected.size) // 更新索引
|
||||
})
|
||||
ruleRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = ruleRecyclerAdapter
|
||||
}
|
||||
val ruleMoveCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
Log.d(TAG, "onItemMove: $fromPosition $toPosition")
|
||||
ruleRecyclerAdapter.onItemMove(fromPosition, toPosition)
|
||||
ruleListSelected = ruleRecyclerAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
ruleListSelected = ruleRecyclerAdapter.itemList
|
||||
//ruleRecyclerAdapter.notifyDataSetChanged()
|
||||
Log.d(TAG, "onDragFinished: $ruleListSelected")
|
||||
}
|
||||
})
|
||||
val ruleTouchHelper = ItemTouchHelper(ruleMoveCallback)
|
||||
ruleTouchHelper.attachToRecyclerView(ruleRecyclerView)
|
||||
ruleRecyclerAdapter.setTouchHelper(ruleTouchHelper)
|
||||
|
||||
//获取转发规则列表
|
||||
getRuleList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态增删Rule
|
||||
*
|
||||
* @param ruleItemMap 管理item的map,用于删除指定header
|
||||
* @param layoutRules 需要挂载item的LinearLayout
|
||||
* @param rule RuleAdapterItem
|
||||
*/
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun addRuleItemLinearLayout(
|
||||
ruleItemMap: MutableMap<Long, LinearLayout>, layoutRules: LinearLayout, rule: RuleAdapterItem
|
||||
) {
|
||||
val layoutRuleItem = View.inflate(requireContext(), R.layout.item_add_rule, null) as LinearLayout
|
||||
val ivRemoveRule = layoutRuleItem.findViewById<ImageView>(R.id.iv_remove_rule)
|
||||
val ivRuleImage = layoutRuleItem.findViewById<ImageView>(R.id.iv_rule_image)
|
||||
val ivRuleStatus = layoutRuleItem.findViewById<ImageView>(R.id.iv_rule_status)
|
||||
val tvRuleName = layoutRuleItem.findViewById<TextView>(R.id.tv_rule_name)
|
||||
//获取转发规则列表
|
||||
private fun getRuleList() {
|
||||
Core.rule.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Rule>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
ivRuleImage.setImageDrawable(rule.icon)
|
||||
ivRuleStatus.setImageDrawable(getDrawable(if (STATUS_OFF == rule.status) R.drawable.ic_stop else R.drawable.ic_start))
|
||||
val ruleItemId = rule.id as Long
|
||||
tvRuleName.text = "ID-$ruleItemId:${rule.title}"
|
||||
|
||||
ivRemoveRule.tag = ruleItemId
|
||||
ivRemoveRule.setOnClickListener { view2: View ->
|
||||
val tagId = view2.tag as Long
|
||||
layoutRules.removeView(ruleItemMap[tagId])
|
||||
ruleItemMap.remove(tagId)
|
||||
//ruleListSelected.removeIf { it.id == tagId }
|
||||
for (it in ruleListSelected) {
|
||||
if (it.id == tagId) {
|
||||
ruleListSelected -= it
|
||||
break
|
||||
}
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "getRuleList error: ${e.message}")
|
||||
}
|
||||
Log.d(TAG, ruleListSelected.count().toString())
|
||||
Log.d(TAG, ruleListSelected.toString())
|
||||
if (ruleListSelected.isEmpty()) ruleId = 0L
|
||||
}
|
||||
layoutRules.addView(layoutRuleItem)
|
||||
ruleItemMap[ruleItemId] = layoutRuleItem
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onSuccess(ruleList: List<Rule>) {
|
||||
if (ruleList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_rule_first)
|
||||
return
|
||||
}
|
||||
|
||||
ruleSpinnerList.clear()
|
||||
ruleListAll = ruleList as MutableList<Rule>
|
||||
for (rule in ruleList) {
|
||||
val name = if (rule.name.length > 20) rule.name.substring(0, 19) else rule.name
|
||||
val icon = when (rule.type) {
|
||||
"sms" -> R.drawable.auto_task_icon_sms
|
||||
"call" -> R.drawable.auto_task_icon_incall
|
||||
"app" -> R.drawable.auto_task_icon_start_activity
|
||||
else -> R.drawable.auto_task_icon_sms
|
||||
}
|
||||
ruleSpinnerList.add(RuleSpinnerItem(name, getDrawable(icon), rule.id, rule.status))
|
||||
}
|
||||
ruleSpinnerAdapter = RuleSpinnerAdapter(ruleSpinnerList).setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spRule.setAdapter(ruleSpinnerAdapter)
|
||||
//ruleSpinnerAdapter.notifyDataSetChanged()
|
||||
|
||||
//更新ruleListSelected的状态与名称
|
||||
ruleListSelected.forEach {
|
||||
ruleListAll.forEach { rule ->
|
||||
if (it.id == rule.id) {
|
||||
//it.name = rule.name
|
||||
it.status = rule.status
|
||||
}
|
||||
}
|
||||
}
|
||||
ruleRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//检查设置
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun checkSetting(): RuleSetting {
|
||||
if (ruleListSelected.isEmpty() || ruleId == 0L) {
|
||||
throw Exception(getString(R.string.new_sender_first))
|
||||
throw Exception(getString(R.string.new_rule_first))
|
||||
}
|
||||
|
||||
val description = StringBuilder()
|
||||
|
|
|
@ -6,27 +6,33 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.work.Data
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import com.google.gson.Gson
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderAdapterItem
|
||||
import com.idormy.sms.forwarder.adapter.SenderRecyclerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderSpinnerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.spinner.SenderSpinnerItem
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.core.Core
|
||||
import com.idormy.sms.forwarder.database.entity.Sender
|
||||
import com.idormy.sms.forwarder.databinding.FragmentTasksActionSenderBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.TaskSetting
|
||||
import com.idormy.sms.forwarder.entity.action.SenderSetting
|
||||
import com.idormy.sms.forwarder.utils.KEY_BACK_DATA_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_BACK_DESCRIPTION_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_EVENT_DATA_ACTION
|
||||
import com.idormy.sms.forwarder.utils.KEY_TEST_ACTION
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.idormy.sms.forwarder.utils.STATUS_OFF
|
||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_SENDER
|
||||
import com.idormy.sms.forwarder.utils.TaskWorker
|
||||
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||
import com.jeremyliao.liveeventbus.LiveEventBus
|
||||
import com.idormy.sms.forwarder.workers.ActionWorker
|
||||
import com.xuexiang.xaop.annotation.SingleClick
|
||||
import com.xuexiang.xpage.annotation.Page
|
||||
import com.xuexiang.xrouter.annotation.AutoWired
|
||||
|
@ -38,25 +44,27 @@ import io.reactivex.SingleObserver
|
|||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.Date
|
||||
|
||||
@Page(name = "Sender")
|
||||
@Suppress("PrivatePropertyName")
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||
class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = SenderFragment::class.java.simpleName
|
||||
private var titleBar: TitleBar? = null
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
//当前发送通道
|
||||
private var senderId = 0L
|
||||
private var senderListSelected: MutableList<Sender> = mutableListOf()
|
||||
private var senderItemMap = HashMap<Long, LinearLayout>(2)
|
||||
|
||||
//发送通道列表
|
||||
private var senderListAll: MutableList<Sender> = mutableListOf()
|
||||
private val senderSpinnerList = ArrayList<SenderAdapterItem>()
|
||||
//所有发送通道下拉框
|
||||
private var senderListAll = mutableListOf<Sender>()
|
||||
private val senderSpinnerList = mutableListOf<SenderSpinnerItem>()
|
||||
private lateinit var senderSpinnerAdapter: SenderSpinnerAdapter<*>
|
||||
|
||||
//已选发送通道列表
|
||||
private var senderId = 0L
|
||||
private var senderListSelected = mutableListOf<Sender>()
|
||||
private lateinit var senderRecyclerView: RecyclerView
|
||||
private lateinit var senderRecyclerAdapter: SenderRecyclerAdapter
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_EVENT_DATA_ACTION)
|
||||
var eventData: String? = null
|
||||
|
@ -80,9 +88,10 @@ class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.O
|
|||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, 3)
|
||||
mCountDownHelper = CountDownButtonHelper(binding!!.btnTest, 1)
|
||||
mCountDownHelper!!.setOnCountDownListener(object : CountDownButtonHelper.OnCountDownListener {
|
||||
override fun onCountDown(time: Int) {
|
||||
binding!!.btnTest.text = String.format(getString(R.string.seconds_n), time)
|
||||
|
@ -90,6 +99,8 @@ class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.O
|
|||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
//获取发送通道列表
|
||||
getSenderList()
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -106,7 +117,7 @@ class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.O
|
|||
}
|
||||
|
||||
//初始化发送通道下拉框
|
||||
initSenderSpinner()
|
||||
initSender()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
@ -114,15 +125,6 @@ class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.O
|
|||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).observe(this) {
|
||||
mCountDownHelper?.finish()
|
||||
|
||||
if (it == "success") {
|
||||
XToastUtils.success("测试通过", 30000)
|
||||
} else {
|
||||
XToastUtils.error(it, 30000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
|
@ -131,17 +133,21 @@ class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.O
|
|||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
Thread {
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).post("success")
|
||||
} catch (e: Exception) {
|
||||
LiveEventBus.get(KEY_TEST_ACTION, String::class.java).post(e.message.toString())
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "onClick error: ${e.message}")
|
||||
}
|
||||
}.start()
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val taskAction = TaskSetting(TASK_ACTION_SENDER, getString(R.string.task_sender), settingVo.description, Gson().toJson(settingVo), requestCode)
|
||||
val taskActionsJson = Gson().toJson(arrayListOf(taskAction))
|
||||
val msgInfo = MsgInfo("task", getString(R.string.task_sender), settingVo.description, Date(), getString(R.string.task_sender))
|
||||
val actionData = Data.Builder().putLong(TaskWorker.taskId, 0).putString(TaskWorker.taskActions, taskActionsJson).putString(TaskWorker.msgInfo, Gson().toJson(msgInfo)).build()
|
||||
val actionRequest = OneTimeWorkRequestBuilder<ActionWorker>().setInputData(actionData).build()
|
||||
WorkManager.getInstance().enqueue(actionRequest)
|
||||
} catch (e: Exception) {
|
||||
mCountDownHelper?.finish()
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "onClick error: ${e.message}")
|
||||
XToastUtils.error(e.message.toString(), 30000)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -167,47 +173,14 @@ class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.O
|
|||
}
|
||||
}
|
||||
|
||||
//初始化发送通道下拉框
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun initSenderSpinner() {
|
||||
Core.sender.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Sender>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "initSenderSpinner error: ${e.message}")
|
||||
}
|
||||
|
||||
override fun onSuccess(senderList: List<Sender>) {
|
||||
if (senderList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_sender_first)
|
||||
return
|
||||
}
|
||||
|
||||
senderListAll = senderList as MutableList<Sender>
|
||||
for (sender in senderList) {
|
||||
val name = if (sender.name.length > 20) sender.name.substring(0, 19) else sender.name
|
||||
senderSpinnerList.add(SenderAdapterItem(name, getDrawable(sender.imageId), sender.id, sender.status))
|
||||
}
|
||||
senderSpinnerAdapter = SenderSpinnerAdapter(senderSpinnerList)
|
||||
.setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spSender.setAdapter(senderSpinnerAdapter)
|
||||
|
||||
if (senderListSelected.isNotEmpty()) {
|
||||
for (sender in senderListSelected) {
|
||||
for (senderItem in senderSpinnerList) {
|
||||
if (sender.id == senderItem.id) {
|
||||
addSenderItemLinearLayout(senderItemMap, binding!!.layoutSenders, senderItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
//初始化发送通道
|
||||
@SuppressLint("SetTextI18n", "NotifyDataSetChanged")
|
||||
private fun initSender() {
|
||||
//初始化发送通道下拉框
|
||||
binding!!.spSender.setOnItemClickListener { _: AdapterView<*>, _: View, position: Int, _: Long ->
|
||||
try {
|
||||
val sender = senderSpinnerAdapter.getItemSource(position) as SenderAdapterItem
|
||||
senderId = sender.id!!
|
||||
val item = senderSpinnerAdapter.getItemSource(position) as SenderSpinnerItem
|
||||
senderId = item.id!!
|
||||
if (senderId > 0L) {
|
||||
senderListSelected.forEach {
|
||||
if (senderId == it.id) {
|
||||
|
@ -218,60 +191,87 @@ class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.O
|
|||
senderListAll.forEach {
|
||||
if (senderId == it.id) {
|
||||
senderListSelected.add(it)
|
||||
addSenderItemLinearLayout(senderItemMap, binding!!.layoutSenders, sender)
|
||||
}
|
||||
}
|
||||
|
||||
/*if (STATUS_OFF == sender.status) {
|
||||
XToastUtils.warning(getString(R.string.sender_disabled_tips))
|
||||
}*/
|
||||
senderRecyclerAdapter.notifyDataSetChanged()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化已选发送通道列表 RecyclerView 和 Adapter
|
||||
senderRecyclerView = binding!!.recyclerSenders
|
||||
senderRecyclerAdapter = SenderRecyclerAdapter(senderListSelected, { position ->
|
||||
senderListSelected.removeAt(position)
|
||||
senderRecyclerAdapter.notifyItemRemoved(position)
|
||||
senderRecyclerAdapter.notifyItemRangeChanged(position, senderListSelected.size) // 更新索引
|
||||
})
|
||||
senderRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = senderRecyclerAdapter
|
||||
}
|
||||
val senderMoveCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
Log.d(TAG, "onItemMove: $fromPosition $toPosition")
|
||||
senderRecyclerAdapter.onItemMove(fromPosition, toPosition)
|
||||
senderListSelected = senderRecyclerAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
senderListSelected = senderRecyclerAdapter.itemList
|
||||
//senderRecyclerAdapter.notifyDataSetChanged()
|
||||
Log.d(TAG, "onDragFinished: $senderListSelected")
|
||||
}
|
||||
})
|
||||
val senderTouchHelper = ItemTouchHelper(senderMoveCallback)
|
||||
senderTouchHelper.attachToRecyclerView(senderRecyclerView)
|
||||
senderRecyclerAdapter.setTouchHelper(senderTouchHelper)
|
||||
|
||||
//获取发送通道列表
|
||||
getSenderList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态增删Sender
|
||||
*
|
||||
* @param senderItemMap 管理item的map,用于删除指定header
|
||||
* @param layoutSenders 需要挂载item的LinearLayout
|
||||
* @param sender SenderAdapterItem
|
||||
*/
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun addSenderItemLinearLayout(
|
||||
senderItemMap: MutableMap<Long, LinearLayout>, layoutSenders: LinearLayout, sender: SenderAdapterItem
|
||||
) {
|
||||
val layoutSenderItem = View.inflate(requireContext(), R.layout.item_add_sender, null) as LinearLayout
|
||||
val ivRemoveSender = layoutSenderItem.findViewById<ImageView>(R.id.iv_remove_sender)
|
||||
val ivSenderImage = layoutSenderItem.findViewById<ImageView>(R.id.iv_sender_image)
|
||||
val ivSenderStatus = layoutSenderItem.findViewById<ImageView>(R.id.iv_sender_status)
|
||||
val tvSenderName = layoutSenderItem.findViewById<TextView>(R.id.tv_sender_name)
|
||||
//获取发送通道列表
|
||||
private fun getSenderList() {
|
||||
Core.sender.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Sender>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
ivSenderImage.setImageDrawable(sender.icon)
|
||||
ivSenderStatus.setImageDrawable(getDrawable(if (STATUS_OFF == sender.status) R.drawable.ic_stop else R.drawable.ic_start))
|
||||
val senderItemId = sender.id as Long
|
||||
tvSenderName.text = "ID-$senderItemId:${sender.title}"
|
||||
|
||||
ivRemoveSender.tag = senderItemId
|
||||
ivRemoveSender.setOnClickListener { view2: View ->
|
||||
val tagId = view2.tag as Long
|
||||
layoutSenders.removeView(senderItemMap[tagId])
|
||||
senderItemMap.remove(tagId)
|
||||
//senderListSelected.removeIf { it.id == tagId }
|
||||
for (it in senderListSelected) {
|
||||
if (it.id == tagId) {
|
||||
senderListSelected -= it
|
||||
break
|
||||
}
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "getSenderList error: ${e.message}")
|
||||
}
|
||||
Log.d(TAG, senderListSelected.count().toString())
|
||||
Log.d(TAG, senderListSelected.toString())
|
||||
if (senderListSelected.isEmpty()) senderId = 0L
|
||||
}
|
||||
layoutSenders.addView(layoutSenderItem)
|
||||
senderItemMap[senderItemId] = layoutSenderItem
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onSuccess(senderList: List<Sender>) {
|
||||
if (senderList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_sender_first)
|
||||
return
|
||||
}
|
||||
|
||||
senderSpinnerList.clear()
|
||||
senderListAll = senderList as MutableList<Sender>
|
||||
for (sender in senderList) {
|
||||
val name = if (sender.name.length > 20) sender.name.substring(0, 19) else sender.name
|
||||
senderSpinnerList.add(SenderSpinnerItem(name, getDrawable(sender.imageId), sender.id, sender.status))
|
||||
}
|
||||
senderSpinnerAdapter = SenderSpinnerAdapter(senderSpinnerList).setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spSender.setAdapter(senderSpinnerAdapter)
|
||||
//senderSpinnerAdapter.notifyDataSetChanged()
|
||||
|
||||
//更新senderListSelected的状态与名称
|
||||
senderListSelected.forEach {
|
||||
senderListAll.forEach { sender ->
|
||||
if (it.id == sender.id) {
|
||||
it.name = sender.name
|
||||
it.status = sender.status
|
||||
}
|
||||
}
|
||||
}
|
||||
senderRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//检查设置
|
||||
|
@ -295,4 +295,5 @@ class SenderFragment : BaseFragment<FragmentTasksActionSenderBinding?>(), View.O
|
|||
|
||||
return SenderSetting(description.toString(), status, senderListSelected)
|
||||
}
|
||||
|
||||
}
|
|
@ -53,7 +53,7 @@ class SmsCommandUtils {
|
|||
Core.frpc.getAutorun()
|
||||
} else {
|
||||
val uids = param.split(",")
|
||||
Core.frpc.getByUids(uids)
|
||||
Core.frpc.getByUids(uids, param)
|
||||
}
|
||||
|
||||
if (frpcList.isEmpty()) {
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/xui_config_color_white"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/config_padding_5dp"
|
||||
android:paddingBottom="@dimen/config_padding_5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_image"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/icon_dingtalk"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginTop="-10dp"
|
||||
android:src="@drawable/ic_stop"
|
||||
tools:ignore="ContentDescription,VisualLintBounds" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/dingtalk_robot"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_edit"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:src="@drawable/ic_edit"
|
||||
app:tint="@color/toast_info_color"
|
||||
tools:ignore="ContentDescription,PrivateResource,ImageContrastCheck" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_remove"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="@color/toast_error_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_drag"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:src="@drawable/ic_drag"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription,ImageContrastCheck" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/xui_config_color_white"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/config_padding_5dp"
|
||||
android:paddingBottom="@dimen/config_padding_5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_image"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/icon_dingtalk"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginTop="-10dp"
|
||||
android:src="@drawable/ic_stop"
|
||||
tools:ignore="ContentDescription,VisualLintBounds" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/dingtalk_robot"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_edit"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:src="@drawable/ic_edit"
|
||||
app:tint="@color/toast_info_color"
|
||||
tools:ignore="ContentDescription,PrivateResource,ImageContrastCheck" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_remove"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="@color/toast_error_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_drag"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:src="@drawable/ic_drag"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription,ImageContrastCheck" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/xui_config_color_white"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/config_padding_5dp"
|
||||
android:paddingBottom="@dimen/config_padding_5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_image"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/icon_dingtalk"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginTop="-10dp"
|
||||
android:src="@drawable/ic_stop"
|
||||
tools:ignore="ContentDescription,VisualLintBounds" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/dingtalk_robot"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_edit"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:src="@drawable/ic_edit"
|
||||
app:tint="@color/toast_info_color"
|
||||
tools:ignore="ContentDescription,PrivateResource,ImageContrastCheck" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_remove"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="@color/toast_error_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_drag"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:src="@drawable/ic_drag"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription,ImageContrastCheck" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -107,44 +107,22 @@
|
|||
android:gravity="start"
|
||||
android:maxEms="10"
|
||||
android:maxLines="1"
|
||||
android:text="@string/task_cron"
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_copy"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_copy"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription,ImageContrastCheck" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_edit"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_edit"
|
||||
app:tint="@color/toast_info_color"
|
||||
tools:ignore="ContentDescription,PrivateResource,ImageContrastCheck" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_delete"
|
||||
android:layout_width="@dimen/card_view_image_size"
|
||||
android:layout_height="@dimen/card_view_image_size"
|
||||
android:padding="@dimen/card_view_image_padding"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="@color/toast_error_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
<TextView
|
||||
android:id="@+id/tv_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/text_size_small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="bottom"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
|
@ -155,16 +133,38 @@
|
|||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:maxLines="2"
|
||||
android:paddingEnd="@dimen/config_padding_10dp"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
android:text="@string/task_cron_tips"
|
||||
android:textSize="@dimen/text_size_mini" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:textSize="@dimen/text_size_small" />
|
||||
<ImageView
|
||||
android:id="@+id/iv_copy"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_copy"
|
||||
app:tint="@color/colorStart"
|
||||
tools:ignore="ContentDescription,ImageContrastCheck" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_edit"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_edit"
|
||||
app:tint="@color/toast_info_color"
|
||||
tools:ignore="ContentDescription,PrivateResource,ImageContrastCheck" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_delete"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="@color/toast_error_color"
|
||||
tools:ignore="ContentDescription,PrivateResource" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -50,11 +50,10 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_Senders"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_senders"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_sender_logic"
|
||||
|
|
|
@ -18,13 +18,8 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
style="@style/BarTitleStyle"
|
||||
android:layout_marginTop="@dimen/config_margin_5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -331,14 +326,7 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout style="@style/BarTitleStyle">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -873,14 +861,7 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout style="@style/BarTitleStyle">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -1237,14 +1218,7 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout style="@style/BarTitleStyle">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -101,12 +101,11 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_frpcs"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_frpcs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/config_margin_5dp"
|
||||
android:orientation="vertical" />
|
||||
android:layout_marginTop="@dimen/config_margin_5dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -59,11 +59,10 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_senders"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_senders"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_sender_logic"
|
||||
|
|
|
@ -103,12 +103,11 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_rules"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_rules"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/config_margin_5dp"
|
||||
android:orientation="vertical" />
|
||||
android:layout_marginTop="@dimen/config_margin_5dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -103,12 +103,11 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_senders"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_senders"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/config_margin_5dp"
|
||||
android:orientation="vertical" />
|
||||
android:layout_marginTop="@dimen/config_margin_5dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -28,14 +28,7 @@
|
|||
app:srcCompat="@drawable/auto_task_icon_settings"
|
||||
tools:ignore="ImageContrastCheck" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout style="@style/BarTitleStyle">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -344,14 +337,7 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout style="@style/BarTitleStyle">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -187,7 +187,8 @@
|
|||
android:layout_marginStart="@dimen/config_margin_10dp"
|
||||
android:layout_marginEnd="@dimen/config_margin_10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -187,7 +187,8 @@
|
|||
android:layout_marginStart="@dimen/config_margin_10dp"
|
||||
android:layout_marginEnd="@dimen/config_margin_10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -51,14 +51,7 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout style="@style/BarTitleStyle.Task">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -69,7 +62,7 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:text="@string/task_conditions_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp" />
|
||||
|
@ -137,14 +130,7 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout style="@style/BarTitleStyle.Task">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/xui_config_color_white"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_frpc_image"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
tools:ignore="ContentDescription,UseAppTint" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_frpc_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginTop="-10dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_frpc_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:minHeight="?attr/ms_item_height_size"
|
||||
android:paddingStart="?attr/ms_padding_left_size"
|
||||
android:paddingTop="?attr/ms_padding_top_size"
|
||||
android:paddingEnd="?attr/ms_padding_left_size"
|
||||
android:paddingBottom="?attr/ms_padding_top_size"
|
||||
android:singleLine="true"
|
||||
tools:ignore="PrivateResource" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_remove_frpc"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:contentDescription="@string/frpc_del"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="#F15C58" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,68 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/xui_config_color_white"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_rule_image"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
tools:ignore="ContentDescription,UseAppTint" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_rule_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginTop="-10dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_rule_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:minHeight="?attr/ms_item_height_size"
|
||||
android:paddingStart="?attr/ms_padding_left_size"
|
||||
android:paddingTop="?attr/ms_padding_top_size"
|
||||
android:paddingEnd="?attr/ms_padding_left_size"
|
||||
android:paddingBottom="?attr/ms_padding_top_size"
|
||||
android:singleLine="true"
|
||||
tools:ignore="PrivateResource" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_remove_rule"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:contentDescription="@string/rule_del"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="#F15C58" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,68 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/xui_config_color_white"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_sender_image"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_sender_status"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginTop="-10dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_sender_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:minHeight="?attr/ms_item_height_size"
|
||||
android:paddingStart="?attr/ms_padding_left_size"
|
||||
android:paddingTop="?attr/ms_padding_top_size"
|
||||
android:paddingEnd="?attr/ms_padding_left_size"
|
||||
android:paddingBottom="?attr/ms_padding_top_size"
|
||||
android:singleLine="true"
|
||||
tools:ignore="PrivateResource" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_remove_sender"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:contentDescription="@string/sender_del"
|
||||
android:src="@drawable/ic_delete"
|
||||
app:tint="#F15C58" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,200 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!--放一些组件的样式-->
|
||||
<style name="WindowAnimStyle" parent="@android:style/Animation">
|
||||
<item name="android:activityOpenEnterAnimation">@anim/xpage_slide_in_right</item>
|
||||
<item name="android:activityOpenExitAnimation">@anim/xpage_slide_out_left</item>
|
||||
<item name="android:activityCloseEnterAnimation">@anim/xpage_slide_in_left</item>
|
||||
<item name="android:activityCloseExitAnimation">@anim/xpage_slide_out_right</item>
|
||||
</style>
|
||||
|
||||
<style name="Container">
|
||||
<item name="android:paddingStart">?attr/xui_config_content_spacing_horizontal</item>
|
||||
<item name="android:paddingEnd">?attr/xui_config_content_spacing_horizontal</item>
|
||||
</style>
|
||||
|
||||
<style name="InfoItem" parent="Container">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">50dp</item>
|
||||
<item name="sLeftViewMarginLeft">10dp</item>
|
||||
<item name="sRightViewMarginRight">0dp</item>
|
||||
<item name="sRightIconMarginRight">0dp</item>
|
||||
<item name="sLeftIconMarginLeft">0dp</item>
|
||||
<item name="sLeftTextSize">?attr/xui_config_size_content_text</item>
|
||||
<item name="sLeftTextColor">@color/xui_config_color_title_text</item>
|
||||
<item name="sCenterTextColor">@color/xui_config_color_black</item>
|
||||
<item name="sRightTextColor">@color/xui_config_color_explain_text</item>
|
||||
<item name="sRightTextSize">?attr/xui_config_size_content_text</item>
|
||||
</style>
|
||||
|
||||
<style name="InfoItem.About">
|
||||
<item name="sLeftViewWidth">110dp</item>
|
||||
<item name="sLeftViewGravity">left_center</item>
|
||||
<item name="sCenterViewGravity">left_center</item>
|
||||
<item name="sCenterViewMarginLeft">25dp</item>
|
||||
<item name="sRightTextSize">?attr/xui_config_size_content_text</item>
|
||||
<item name="sRightViewMarginRight">10dp</item>
|
||||
<item name="sRightIconRes">@drawable/icon_arrow_right_grey</item>
|
||||
</style>
|
||||
|
||||
<style name="InfoItem.AboutWithBtn">
|
||||
<item name="sLeftViewGravity">left_center</item>
|
||||
<item name="sCenterViewGravity">left_center</item>
|
||||
<item name="sCenterViewMarginLeft">25dp</item>
|
||||
<item name="sRightTextSize">?attr/xui_config_size_content_text</item>
|
||||
<item name="sRightViewMarginRight">10dp</item>
|
||||
<!--<item name="sRightIconRes">@drawable/icon_arrow_right_grey</item>-->
|
||||
</style>
|
||||
|
||||
<style name="PullDownStyle">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="srlEnableOverScrollDrag">true</item>
|
||||
<item name="srlEnablePureScrollMode">true</item>
|
||||
</style>
|
||||
|
||||
<style name="ScrollViewStyle">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="android:overScrollMode">never</item>
|
||||
</style>
|
||||
|
||||
<style name="XUILayout">
|
||||
<item name="xui_borderWidth">0dp</item>
|
||||
<item name="xui_radius">8dp</item>
|
||||
<item name="xui_shadowElevation">6dp</item>
|
||||
<item name="android:background">@color/xui_config_color_white</item>
|
||||
</style>
|
||||
|
||||
<!-- SwitchButton -->
|
||||
<style name="SwitchButtonStyle">
|
||||
<item name="android:paddingStart">5dp</item>
|
||||
<item name="android:paddingEnd">5dp</item>
|
||||
<item name="android:paddingTop">0dp</item>
|
||||
<item name="android:paddingBottom">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="BarStyle">
|
||||
<item name="android:layout_marginTop">5dp</item>
|
||||
<item name="android:layout_marginStart">5dp</item>
|
||||
<item name="android:layout_marginEnd">5dp</item>
|
||||
<item name="android:padding">10dp</item>
|
||||
<item name="android:background">@drawable/rounded_background</item>
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<!--<item name="android:orientation">horizontal</item>-->
|
||||
</style>
|
||||
|
||||
<style name="BarStyle.Switch">
|
||||
<item name="android:layout_marginTop">5dp</item>
|
||||
<item name="android:layout_marginStart">5dp</item>
|
||||
<item name="android:layout_marginEnd">5dp</item>
|
||||
<item name="android:paddingStart">10dp</item>
|
||||
<item name="android:paddingEnd">5dp</item>
|
||||
<item name="android:paddingTop">10dp</item>
|
||||
<item name="android:paddingBottom">10dp</item>
|
||||
<item name="android:background">@drawable/rounded_background</item>
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
</style>
|
||||
|
||||
<style name="BarStyle.NoMT">
|
||||
<item name="android:layout_marginStart">5dp</item>
|
||||
<item name="android:layout_marginEnd">5dp</item>
|
||||
<item name="android:padding">10dp</item>
|
||||
<item name="android:background">@drawable/rounded_background</item>
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
</style>
|
||||
|
||||
<style name="BarTitleStyle">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_marginStart">5dp</item>
|
||||
<item name="android:layout_marginTop">5dp</item>
|
||||
<item name="android:layout_marginEnd">5dp</item>
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="android:orientation">horizontal</item>
|
||||
</style>
|
||||
|
||||
<style name="BarTitleStyle.Task">
|
||||
<item name="android:layout_marginTop">20dp</item>
|
||||
</style>
|
||||
|
||||
<style name="insertButtonStyle">
|
||||
<item name="android:layout_width">0dp</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:paddingTop">3dp</item>
|
||||
<item name="android:paddingBottom">3dp</item>
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:background">@color/colorBlueGrey</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:minWidth">0dp</item>
|
||||
<item name="android:minHeight">0dp</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:textSize">@dimen/text_size_small</item>
|
||||
</style>
|
||||
|
||||
<style name="rg_style">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
</style>
|
||||
|
||||
<style name="rg_rb_style">
|
||||
<item name="android:layout_width">0dp</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_gravity">center_vertical</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:padding">0dp</item>
|
||||
<item name="android:layout_margin">0dp</item>
|
||||
<item name="android:drawablePadding">5dp</item>S
|
||||
<item name="android:minHeight">30dp</item>
|
||||
<item name="android:minWidth">30dp</item>
|
||||
<item name="android:textSize">@dimen/text_size_small</item>
|
||||
<item name="android:button">@drawable/custom_radio_button</item>
|
||||
</style>
|
||||
|
||||
<style name="rg_rb_style_wrap">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_gravity">center_vertical</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:padding">0dp</item>
|
||||
<item name="android:drawablePadding">5dp</item>
|
||||
<item name="android:minHeight">30dp</item>
|
||||
<item name="android:minWidth">30dp</item>
|
||||
<item name="android:textSize">@dimen/text_size_small</item>
|
||||
<item name="android:layout_marginEnd">5dp</item>
|
||||
<item name="android:button">@drawable/custom_radio_button</item>
|
||||
</style>
|
||||
|
||||
<style name="rg_rb_style_match">
|
||||
<item name="android:layout_marginTop">5dp</item>
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<!--<item name="android:textSize">@dimen/text_size_small</item>-->
|
||||
<item name="android:button">@drawable/custom_radio_button</item>
|
||||
</style>
|
||||
|
||||
<style name="TabLayoutStyle" parent="Base.Widget.Design.TabLayout">
|
||||
<item name="tabIndicatorColor">?attr/colorAccent</item>
|
||||
<item name="tabIndicatorHeight">2dp</item>
|
||||
<item name="tabPaddingStart">12dp</item>
|
||||
<item name="tabPaddingEnd">12dp</item>
|
||||
<item name="tabTextAppearance">@style/TabText</item>
|
||||
<item name="tabSelectedTextColor">?attr/colorAccent</item>
|
||||
<item name="tabTextColor">@color/xui_config_color_gray_6</item>
|
||||
</style>
|
||||
|
||||
<style name="TabText" parent="TextAppearance.Design.Tab">
|
||||
<item name="android:textColor">@color/selector_tab_text_color</item>
|
||||
<item name="android:textSize">?attr/xui_config_size_content_text</item>
|
||||
</style>
|
||||
|
||||
<style name="TabText.Explain">
|
||||
<item name="android:textColor">@color/selector_tab_text_color</item>
|
||||
<item name="android:textSize">?attr/xui_config_size_explain_text</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -590,7 +590,7 @@
|
|||
<string name="timeout">超时</string>
|
||||
<string name="timeout_label">单次超时</string>
|
||||
<string name="seconds">秒</string>
|
||||
<string name="seconds_n">%s 秒</string>
|
||||
<string name="seconds_n">%s秒</string>
|
||||
<string name="retry">重试</string>
|
||||
<string name="retry_label">最多重试</string>
|
||||
<string name="test_sender_sms">【%s】恭喜您,该发送通道测试成功,请继续添加转发规则!</string>
|
||||
|
|
|
@ -590,7 +590,7 @@
|
|||
<string name="timeout">超時</string>
|
||||
<string name="timeout_label">單次超時</string>
|
||||
<string name="seconds">秒</string>
|
||||
<string name="seconds_n">%s 秒</string>
|
||||
<string name="seconds_n">%s秒</string>
|
||||
<string name="retry">重試</string>
|
||||
<string name="retry_label">最多重試</string>
|
||||
<string name="test_sender_sms">【%s】恭喜您,該發送通道測試成功,請繼續添加轉發規則!</string>
|
||||
|
|
|
@ -590,7 +590,7 @@
|
|||
<string name="timeout">超时</string>
|
||||
<string name="timeout_label">单次超时</string>
|
||||
<string name="seconds">秒</string>
|
||||
<string name="seconds_n">%s 秒</string>
|
||||
<string name="seconds_n">%s秒</string>
|
||||
<string name="retry">重试</string>
|
||||
<string name="retry_label">最多重试</string>
|
||||
<string name="test_sender_sms">【%s】恭喜您,该发送通道测试成功,请继续添加转发规则!</string>
|
||||
|
|
|
@ -105,6 +105,20 @@
|
|||
<item name="android:gravity">center_vertical</item>
|
||||
</style>
|
||||
|
||||
<style name="BarTitleStyle">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_marginStart">5dp</item>
|
||||
<item name="android:layout_marginTop">10dp</item>
|
||||
<item name="android:layout_marginEnd">5dp</item>
|
||||
<item name="android:gravity">bottom</item>
|
||||
<item name="android:orientation">horizontal</item>
|
||||
</style>
|
||||
|
||||
<style name="BarTitleStyle.Task">
|
||||
<item name="android:layout_marginTop">20dp</item>
|
||||
</style>
|
||||
|
||||
<style name="insertButtonStyle">
|
||||
<item name="android:layout_width">0dp</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
|
|
Loading…
Reference in New Issue