新增:自动任务·快捷指令 —— 执行动作:启停任务 #389
parent
2b091bbefe
commit
65ea7bcf0c
@ -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.Task
|
||||
import java.util.Collections
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
class TaskRecyclerAdapter(
|
||||
var itemList: MutableList<Task>,
|
||||
private var removeClickListener: ((Int) -> Unit)? = null,
|
||||
private var editClickListener: ((Int) -> Unit)? = null,
|
||||
) : RecyclerView.Adapter<TaskRecyclerAdapter.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_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@TaskRecyclerAdapter.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(task: Task) {
|
||||
image.setImageResource(task.imageId)
|
||||
status.setImageResource(task.statusImageId)
|
||||
title.text = task.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,167 @@
|
||||
package com.idormy.sms.forwarder.adapter.spinner
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import android.text.Html
|
||||
import android.text.TextUtils
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.idormy.sms.forwarder.R
|
||||
import com.idormy.sms.forwarder.utils.Log
|
||||
import com.idormy.sms.forwarder.utils.STATUS_OFF
|
||||
import com.xuexiang.xui.utils.CollectionUtils
|
||||
import com.xuexiang.xui.widget.spinner.editspinner.BaseEditSpinnerAdapter
|
||||
import com.xuexiang.xui.widget.spinner.editspinner.EditSpinnerFilter
|
||||
import com.xuexiang.xutil.resource.ResUtils.getDrawable
|
||||
|
||||
@Suppress("unused", "NAME_SHADOWING", "DEPRECATION")
|
||||
class TaskSpinnerAdapter<T> : BaseEditSpinnerAdapter<T>, EditSpinnerFilter {
|
||||
/**
|
||||
* 选项的文字颜色
|
||||
*/
|
||||
private var mTextColor = 0
|
||||
|
||||
/**
|
||||
* 选项的文字大小
|
||||
*/
|
||||
private var mTextSize = 0f
|
||||
|
||||
/**
|
||||
* 背景颜色
|
||||
*/
|
||||
private var mBackgroundSelector = 0
|
||||
|
||||
/**
|
||||
* 过滤关键词的选中颜色
|
||||
*/
|
||||
private var mFilterColor = "#F15C58"
|
||||
private var mIsFilterKey = false
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param data 选项数据
|
||||
*/
|
||||
constructor(data: List<T>?) : super(data)
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param data 选项数据
|
||||
*/
|
||||
constructor(data: Array<T>?) : super(data)
|
||||
|
||||
override fun getEditSpinnerFilter(): EditSpinnerFilter {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View? {
|
||||
var convertView = convertView
|
||||
val holder: ViewHolder
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(parent.context).inflate(R.layout.item_spinner_with_icon, parent, false)
|
||||
holder = ViewHolder(convertView, mTextColor, mTextSize, mBackgroundSelector)
|
||||
convertView.tag = holder
|
||||
} else {
|
||||
holder = convertView.tag as ViewHolder
|
||||
}
|
||||
val item = CollectionUtils.getListItem(mDataSource, mIndexs[position]) as TaskSpinnerItem
|
||||
holder.iconView.setImageDrawable(item.icon)
|
||||
holder.statusView.setImageDrawable(
|
||||
getDrawable(
|
||||
when (item.status) {
|
||||
STATUS_OFF -> R.drawable.ic_stop
|
||||
else -> R.drawable.ic_start
|
||||
}
|
||||
)
|
||||
)
|
||||
//holder.titleView.text = Html.fromHtml(item.toString())
|
||||
holder.titleView.text = Html.fromHtml(getItem(position))
|
||||
return convertView
|
||||
}
|
||||
|
||||
override fun onFilter(keyword: String): Boolean {
|
||||
mDisplayData.clear()
|
||||
Log.d("TaskSpinnerAdapter", "keyword = $keyword")
|
||||
Log.d("TaskSpinnerAdapter", "mIndexs.indices = ${mIndexs.indices}")
|
||||
if (TextUtils.isEmpty(keyword)) {
|
||||
initDisplayData(mDataSource)
|
||||
for (i in mIndexs.indices) {
|
||||
mIndexs[i] = i
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
for (i in mDataSource.indices) {
|
||||
if (getDataSourceString(i).contains(keyword, ignoreCase = true)) {
|
||||
mIndexs[mDisplayData.size] = i
|
||||
if (mIsFilterKey) {
|
||||
mDisplayData.add(getDataSourceString(i).replaceFirst(keyword.toRegex(), "<font color=\"$mFilterColor\">$keyword</font>"))
|
||||
} else {
|
||||
mDisplayData.add(getDataSourceString(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Log.e("TaskSpinnerAdapter", "onFilter error: ${e.message}")
|
||||
}
|
||||
}
|
||||
Log.d("TaskSpinnerAdapter", "mDisplayData = $mDisplayData")
|
||||
notifyDataSetChanged()
|
||||
return mDisplayData.size > 0
|
||||
}
|
||||
|
||||
fun setTextColor(@ColorInt textColor: Int): TaskSpinnerAdapter<*> {
|
||||
mTextColor = textColor
|
||||
return this
|
||||
}
|
||||
|
||||
fun setTextSize(textSize: Float): TaskSpinnerAdapter<*> {
|
||||
mTextSize = textSize
|
||||
return this
|
||||
}
|
||||
|
||||
fun setBackgroundSelector(@DrawableRes backgroundSelector: Int): TaskSpinnerAdapter<*> {
|
||||
mBackgroundSelector = backgroundSelector
|
||||
return this
|
||||
}
|
||||
|
||||
fun setFilterColor(filterColor: String): TaskSpinnerAdapter<*> {
|
||||
mFilterColor = filterColor
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIsFilterKey(isFilterKey: Boolean): TaskSpinnerAdapter<*> {
|
||||
mIsFilterKey = isFilterKey
|
||||
return this
|
||||
}
|
||||
|
||||
@SuppressLint("ObsoleteSdkInt")
|
||||
private class ViewHolder(convertView: View, @ColorInt textColor: Int, textSize: Float, @DrawableRes backgroundSelector: Int) {
|
||||
val iconView: ImageView = convertView.findViewById(R.id.iv_icon)
|
||||
val statusView: ImageView = convertView.findViewById(R.id.iv_status)
|
||||
val titleView: TextView = convertView.findViewById(R.id.tv_title)
|
||||
|
||||
init {
|
||||
if (textColor > 0) titleView.setTextColor(textColor)
|
||||
if (textSize > 0F) titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
|
||||
if (backgroundSelector != 0) titleView.setBackgroundResource(backgroundSelector)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
val config = convertView.resources.configuration
|
||||
if (config.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
|
||||
titleView.textDirection = View.TEXT_DIRECTION_RTL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getItemSource(position: Int): T {
|
||||
return mDataSource[mIndexs[position]]
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.idormy.sms.forwarder.adapter.spinner
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
|
||||
@Suppress("unused")
|
||||
class TaskSpinnerItem(
|
||||
var title: CharSequence,
|
||||
var icon: Drawable? = null,
|
||||
var id: Long? = 0L,
|
||||
var status: Int? = 1
|
||||
) {
|
||||
|
||||
fun setTitle(title: CharSequence): TaskSpinnerItem {
|
||||
this.title = title
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIcon(icon: Drawable?): TaskSpinnerItem {
|
||||
this.icon = icon
|
||||
return this
|
||||
}
|
||||
|
||||
fun setId(id: Long): TaskSpinnerItem {
|
||||
this.id = id
|
||||
return this
|
||||
}
|
||||
|
||||
fun setStatus(status: Int): TaskSpinnerItem {
|
||||
this.status = status
|
||||
return this
|
||||
}
|
||||
|
||||
// 注意:自定义实体需要重写对象的 toString 方法
|
||||
override fun toString(): String {
|
||||
return title.toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun of(title: CharSequence): TaskSpinnerItem {
|
||||
return TaskSpinnerItem(title)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun arrayOf(vararg titles: CharSequence): Array<TaskSpinnerItem> {
|
||||
return titles.map { TaskSpinnerItem(it) }.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,303 @@
|
||||
package com.idormy.sms.forwarder.fragment.action
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
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.TaskRecyclerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.base.ItemMoveCallback
|
||||
import com.idormy.sms.forwarder.adapter.spinner.TaskSpinnerAdapter
|
||||
import com.idormy.sms.forwarder.adapter.spinner.TaskSpinnerItem
|
||||
import com.idormy.sms.forwarder.core.BaseFragment
|
||||
import com.idormy.sms.forwarder.core.Core
|
||||
import com.idormy.sms.forwarder.database.entity.Task
|
||||
import com.idormy.sms.forwarder.databinding.FragmentTasksActionTaskBinding
|
||||
import com.idormy.sms.forwarder.entity.MsgInfo
|
||||
import com.idormy.sms.forwarder.entity.TaskSetting
|
||||
import com.idormy.sms.forwarder.entity.action.TaskActionSetting
|
||||
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.Log
|
||||
import com.idormy.sms.forwarder.utils.STATUS_OFF
|
||||
import com.idormy.sms.forwarder.utils.TASK_ACTION_TASK
|
||||
import com.idormy.sms.forwarder.utils.TaskWorker
|
||||
import com.idormy.sms.forwarder.utils.XToastUtils
|
||||
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
|
||||
import com.xuexiang.xrouter.launcher.XRouter
|
||||
import com.xuexiang.xui.utils.CountDownButtonHelper
|
||||
import com.xuexiang.xui.widget.actionbar.TitleBar
|
||||
import com.xuexiang.xutil.resource.ResUtils.getDrawable
|
||||
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 = "Task")
|
||||
@Suppress("PrivatePropertyName", "DEPRECATION")
|
||||
class TaskActionFragment : BaseFragment<FragmentTasksActionTaskBinding?>(), View.OnClickListener {
|
||||
|
||||
private val TAG: String = TaskActionFragment::class.java.simpleName
|
||||
private var titleBar: TitleBar? = null
|
||||
private var mCountDownHelper: CountDownButtonHelper? = null
|
||||
|
||||
//所有自动任务下拉框
|
||||
private var taskListAll = mutableListOf<Task>()
|
||||
private val taskSpinnerList = mutableListOf<TaskSpinnerItem>()
|
||||
private lateinit var taskSpinnerAdapter: TaskSpinnerAdapter<*>
|
||||
|
||||
//已选自动任务列表
|
||||
private var taskId = 0L
|
||||
private var taskListSelected = mutableListOf<Task>()
|
||||
private lateinit var taskRecyclerView: RecyclerView
|
||||
private lateinit var taskRecyclerAdapter: TaskRecyclerAdapter
|
||||
|
||||
@JvmField
|
||||
@AutoWired(name = KEY_EVENT_DATA_ACTION)
|
||||
var eventData: String? = null
|
||||
|
||||
override fun initArgs() {
|
||||
XRouter.getInstance().inject(this)
|
||||
}
|
||||
|
||||
override fun viewBindingInflate(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup,
|
||||
): FragmentTasksActionTaskBinding {
|
||||
return FragmentTasksActionTaskBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun initTitle(): TitleBar? {
|
||||
titleBar = super.initTitle()!!.setImmersive(false).setTitle(R.string.task_task)
|
||||
return titleBar
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
override fun initViews() {
|
||||
//测试按钮增加倒计时,避免重复点击
|
||||
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)
|
||||
}
|
||||
|
||||
override fun onFinished() {
|
||||
binding!!.btnTest.text = getString(R.string.test)
|
||||
//获取自动任务列表
|
||||
getTaskList()
|
||||
}
|
||||
})
|
||||
|
||||
Log.d(TAG, "initViews eventData:$eventData")
|
||||
if (eventData != null) {
|
||||
val settingVo = Gson().fromJson(eventData, TaskActionSetting::class.java)
|
||||
binding!!.rgStatus.check(if (settingVo.status == 1) R.id.rb_status_enable else R.id.rb_status_disable)
|
||||
Log.d(TAG, settingVo.taskList.toString())
|
||||
settingVo.taskList.forEach {
|
||||
taskId = it.id
|
||||
taskListSelected.add(it)
|
||||
}
|
||||
Log.d(TAG, "initViews settingVo:$settingVo")
|
||||
}
|
||||
|
||||
//初始化自动任务下拉框
|
||||
initTask()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
if (mCountDownHelper != null) mCountDownHelper!!.recycle()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun initListeners() {
|
||||
binding!!.btnTest.setOnClickListener(this)
|
||||
binding!!.btnDel.setOnClickListener(this)
|
||||
binding!!.btnSave.setOnClickListener(this)
|
||||
}
|
||||
|
||||
@SingleClick
|
||||
override fun onClick(v: View) {
|
||||
try {
|
||||
when (v.id) {
|
||||
R.id.btn_test -> {
|
||||
mCountDownHelper?.start()
|
||||
try {
|
||||
val settingVo = checkSetting()
|
||||
Log.d(TAG, settingVo.toString())
|
||||
val taskAction = TaskSetting(TASK_ACTION_TASK, getString(R.string.task_task), settingVo.description, Gson().toJson(settingVo), requestCode)
|
||||
val taskActionsJson = Gson().toJson(arrayListOf(taskAction))
|
||||
val msgInfo = MsgInfo("task", getString(R.string.task_task), settingVo.description, Date(), getString(R.string.task_task))
|
||||
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
|
||||
}
|
||||
|
||||
R.id.btn_del -> {
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
|
||||
R.id.btn_save -> {
|
||||
val settingVo = checkSetting()
|
||||
val intent = Intent()
|
||||
intent.putExtra(KEY_BACK_DESCRIPTION_ACTION, settingVo.description)
|
||||
intent.putExtra(KEY_BACK_DATA_ACTION, Gson().toJson(settingVo))
|
||||
setFragmentResult(TASK_ACTION_TASK, intent)
|
||||
popToBack()
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString(), 30000)
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "onClick error: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
//初始化自动任务
|
||||
@SuppressLint("SetTextI18n", "NotifyDataSetChanged")
|
||||
private fun initTask() {
|
||||
//初始化自动任务下拉框
|
||||
binding!!.spTask.setOnItemClickListener { _: AdapterView<*>, _: View, position: Int, _: Long ->
|
||||
try {
|
||||
val item = taskSpinnerAdapter.getItemSource(position) as TaskSpinnerItem
|
||||
taskId = item.id!!
|
||||
if (taskId > 0L) {
|
||||
taskListSelected.forEach {
|
||||
if (taskId == it.id) {
|
||||
XToastUtils.warning(getString(R.string.task_contains_tips))
|
||||
return@setOnItemClickListener
|
||||
}
|
||||
}
|
||||
taskListAll.forEach {
|
||||
if (taskId == it.id) {
|
||||
taskListSelected.add(it)
|
||||
}
|
||||
}
|
||||
taskRecyclerAdapter.notifyDataSetChanged()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
XToastUtils.error(e.message.toString())
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化已选自动任务列表 RecyclerView 和 Adapter
|
||||
taskRecyclerView = binding!!.recyclerTasks
|
||||
taskRecyclerAdapter = TaskRecyclerAdapter(taskListSelected, { position ->
|
||||
taskListSelected.removeAt(position)
|
||||
taskRecyclerAdapter.notifyItemRemoved(position)
|
||||
taskRecyclerAdapter.notifyItemRangeChanged(position, taskListSelected.size) // 更新索引
|
||||
})
|
||||
taskRecyclerView.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
adapter = taskRecyclerAdapter
|
||||
}
|
||||
val taskMoveCallback = ItemMoveCallback(object : ItemMoveCallback.Listener {
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int) {
|
||||
Log.d(TAG, "onItemMove: $fromPosition $toPosition")
|
||||
taskRecyclerAdapter.onItemMove(fromPosition, toPosition)
|
||||
taskListSelected = taskRecyclerAdapter.itemList
|
||||
}
|
||||
|
||||
override fun onDragFinished() {
|
||||
taskListSelected = taskRecyclerAdapter.itemList
|
||||
//taskRecyclerAdapter.notifyDataSetChanged()
|
||||
Log.d(TAG, "onDragFinished: $taskListSelected")
|
||||
}
|
||||
})
|
||||
val taskTouchHelper = ItemTouchHelper(taskMoveCallback)
|
||||
taskTouchHelper.attachToRecyclerView(taskRecyclerView)
|
||||
taskRecyclerAdapter.setTouchHelper(taskTouchHelper)
|
||||
|
||||
//获取自动任务列表
|
||||
getTaskList()
|
||||
}
|
||||
|
||||
//获取自动任务列表
|
||||
private fun getTaskList() {
|
||||
Core.task.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : SingleObserver<List<Task>> {
|
||||
override fun onSubscribe(d: Disposable) {}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
Log.e(TAG, "getTaskList error: ${e.message}")
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun onSuccess(taskList: List<Task>) {
|
||||
if (taskList.isEmpty()) {
|
||||
XToastUtils.error(R.string.add_task_first)
|
||||
return
|
||||
}
|
||||
|
||||
taskSpinnerList.clear()
|
||||
taskListAll = taskList as MutableList<Task>
|
||||
for (task in taskList) {
|
||||
val name = if (task.name.length > 20) task.name.substring(0, 19) else task.name
|
||||
taskSpinnerList.add(TaskSpinnerItem(name, getDrawable(if (STATUS_OFF == task.status) task.greyImageId else task.imageId), task.id, task.status))
|
||||
}
|
||||
taskSpinnerAdapter = TaskSpinnerAdapter(taskSpinnerList).setIsFilterKey(true).setFilterColor("#EF5362").setBackgroundSelector(R.drawable.selector_custom_spinner_bg)
|
||||
binding!!.spTask.setAdapter(taskSpinnerAdapter)
|
||||
//taskSpinnerAdapter.notifyDataSetChanged()
|
||||
|
||||
//更新taskListSelected的状态与名称
|
||||
taskListSelected.forEach {
|
||||
taskListAll.forEach { task ->
|
||||
if (it.id == task.id) {
|
||||
//it.name = task.name
|
||||
it.status = task.status
|
||||
}
|
||||
}
|
||||
}
|
||||
taskRecyclerAdapter.notifyDataSetChanged()
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//检查设置
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun checkSetting(): TaskActionSetting {
|
||||
if (taskListSelected.isEmpty() || taskId == 0L) {
|
||||
throw Exception(getString(R.string.new_task_first))
|
||||
}
|
||||
|
||||
val description = StringBuilder()
|
||||
val status: Int
|
||||
if (binding!!.rgStatus.checkedRadioButtonId == R.id.rb_status_enable) {
|
||||
status = 1
|
||||
description.append(getString(R.string.enable))
|
||||
} else {
|
||||
status = 0
|
||||
description.append(getString(R.string.disable))
|
||||
}
|
||||
description.append(getString(R.string.menu_tasks)).append(", ").append(getString(R.string.specified_task)).append(": ")
|
||||
description.append(taskListSelected.joinToString(",") { "[${it.id}]${it.name}" })
|
||||
|
||||
return TaskActionSetting(description.toString(), status, taskListSelected)
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="25.0dip"
|
||||
android:height="25.0dip"
|
||||
android:autoMirrored="true"
|
||||
android:viewportWidth="25.0"
|
||||
android:viewportHeight="25.0">
|
||||
<path
|
||||
android:fillColor="#ff3482ff"
|
||||
android:pathData="M6.66,0.66L18.66,0.66A6,6 0,0 1,24.66 6.66L24.66,18.66A6,6 0,0 1,18.66 24.66L6.66,24.66A6,6 0,0 1,0.66 18.66L0.66,6.66A6,6 0,0 1,6.66 0.66z" />
|
||||
<group
|
||||
android:scaleX="0.017"
|
||||
android:scaleY="0.017"
|
||||
android:translateX="4.6"
|
||||
android:translateY="4.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M920.2,668.1c0,33.3 -14.8,64.6 -40.7,85.6l-290.7,236.2c-54.4,45.4 -139.1,45.4 -193.6,0l-290.7,-236.2c-54,-42.2 -54,-129 0,-171.3L191.2,512 104.5,441.6c-54,-42.2 -54,-129.1 0,-171.3L395.2,34.1c54.4,-45.4 139.1,-45.4 193.6,0l290.7,236.2c54,42.2 54,129 0,171.3 -42.6,31.8 -90.4,-27.1 -50.5,-62.1a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-290.6,236.2a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l0.4,-0.4 46.5,-36.5a40,40 0,0 1,49.5 62.8l-46.3,36.5c-54.4,45.3 -139,45.2 -193.3,-0.3L254.7,563.6 155,644.5a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l290.6,-236.2a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-0.4,0.4 -46.5,36.6a40,40 0,0 1,-49.5 -62.8l46.2,-36.5C450,300.8 534.5,300.8 588.9,346.4l290.7,236.2c25.9,21 40.7,52.2 40.7,85.6z" />
|
||||
</group>
|
||||
</vector>
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="25.0dip"
|
||||
android:height="25.0dip"
|
||||
android:autoMirrored="true"
|
||||
android:viewportWidth="25.0"
|
||||
android:viewportHeight="25.0">
|
||||
<path
|
||||
android:fillColor="#ffe6e6e6"
|
||||
android:pathData="M6.66,0.66L18.66,0.66A6,6 0,0 1,24.66 6.66L24.66,18.66A6,6 0,0 1,18.66 24.66L6.66,24.66A6,6 0,0 1,0.66 18.66L0.66,6.66A6,6 0,0 1,6.66 0.66z" />
|
||||
<group
|
||||
android:scaleX="0.017"
|
||||
android:scaleY="0.017"
|
||||
android:translateX="4.6"
|
||||
android:translateY="4.0">
|
||||
<path
|
||||
android:fillColor="#ffffffff"
|
||||
android:pathData="M920.2,668.1c0,33.3 -14.8,64.6 -40.7,85.6l-290.7,236.2c-54.4,45.4 -139.1,45.4 -193.6,0l-290.7,-236.2c-54,-42.2 -54,-129 0,-171.3L191.2,512 104.5,441.6c-54,-42.2 -54,-129.1 0,-171.3L395.2,34.1c54.4,-45.4 139.1,-45.4 193.6,0l290.7,236.2c54,42.2 54,129 0,171.3 -42.6,31.8 -90.4,-27.1 -50.5,-62.1a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-290.6,236.2a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l0.4,-0.4 46.5,-36.5a40,40 0,0 1,49.5 62.8l-46.3,36.5c-54.4,45.3 -139,45.2 -193.3,-0.3L254.7,563.6 155,644.5a30.3,30.3 0,0 0,0 47l290.6,236.2c26.9,21.8 65.9,21.8 92.7,0l290.6,-236.2a30.3,30.3 0,0 0,0 -47l-290.6,-236.2a73.8,73.8 0,0 0,-92.7 0l-0.4,0.4 -46.5,36.6a40,40 0,0 1,-49.5 -62.8l46.2,-36.5C450,300.8 534.5,300.8 588.9,346.4l290.7,236.2c25.9,21 40.7,52.2 40.7,85.6z" />
|
||||
</group>
|
||||
</vector>
|
@ -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,148 @@
|
||||
<?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="?attr/xui_config_color_background"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:overScrollMode="never">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_margin="10dp"
|
||||
android:contentDescription="@string/task_task"
|
||||
app:srcCompat="@drawable/auto_task_icon_task"
|
||||
tools:ignore="ImageContrastCheck" />
|
||||
|
||||
<LinearLayout
|
||||
style="@style/BarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/task_task"
|
||||
android:textSize="@dimen/text_size_big"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/task_task_tips"
|
||||
android:textSize="@dimen/text_size_mini"
|
||||
tools:ignore="SmallSp" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="?attr/xui_config_color_separator_light" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/rg_status"
|
||||
style="@style/rg_style"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/config_padding_5dp">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_status_enable"
|
||||
style="@style/rg_rb_style"
|
||||
android:checked="true"
|
||||
android:text="@string/enable"
|
||||
tools:ignore="TouchTargetSizeCheck" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_status_disable"
|
||||
style="@style/rg_rb_style"
|
||||
android:text="@string/disable"
|
||||
tools:ignore="TouchTargetSizeCheck" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/specified_task"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.xuexiang.xui.widget.spinner.editspinner.EditSpinner
|
||||
android:id="@+id/sp_task"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_weight="1"
|
||||
app:es_hint="@string/choose_task"
|
||||
app:es_maxLength="20"
|
||||
app:es_maxLine="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_tasks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/config_margin_5dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp">
|
||||
|
||||
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
|
||||
android:id="@+id/btn_del"
|
||||
style="@style/SuperButton.Gray.Icon.Spacing"
|
||||
android:drawableStart="@drawable/ic_delete"
|
||||
android:text="@string/discard"
|
||||
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
|
||||
android:id="@+id/btn_save"
|
||||
style="@style/SuperButton.Blue.Icon.Spacing"
|
||||
android:drawableStart="@drawable/ic_save"
|
||||
android:text="@string/submit"
|
||||
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
|
||||
|
||||
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
|
||||
android:id="@+id/btn_test"
|
||||
style="@style/SuperButton.Green.Icon.Spacing"
|
||||
android:drawableStart="@drawable/ic_test"
|
||||
android:text="@string/test"
|
||||
tools:ignore="RtlSymmetry,TextContrastCheck,TouchTargetSizeCheck" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
Loading…
Reference in New Issue