Refactor rulesets management to ViewModel

This commit is contained in:
2dust
2026-01-13 17:29:40 +08:00
parent c3a8ee59dc
commit ab4af6bd82
3 changed files with 48 additions and 11 deletions
@@ -8,6 +8,7 @@ import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.ItemTouchHelper
@@ -15,7 +16,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.v2ray.ang.AppConfig
import com.v2ray.ang.R
import com.v2ray.ang.databinding.ActivityRoutingSettingBinding
import com.v2ray.ang.dto.RulesetItem
import com.v2ray.ang.extension.toast
import com.v2ray.ang.extension.toastError
import com.v2ray.ang.extension.toastSuccess
@@ -24,6 +24,7 @@ import com.v2ray.ang.handler.SettingsManager
import com.v2ray.ang.helper.SimpleItemTouchHelperCallback
import com.v2ray.ang.util.JsonUtil
import com.v2ray.ang.util.Utils
import com.v2ray.ang.viewmodel.RoutingSettingsViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -31,8 +32,8 @@ import kotlinx.coroutines.withContext
class RoutingSettingActivity : BaseActivity() {
private val binding by lazy { ActivityRoutingSettingBinding.inflate(layoutInflater) }
var rulesets: MutableList<RulesetItem> = mutableListOf()
private val adapter by lazy { RoutingSettingRecyclerAdapter(this) }
private val viewModel: RoutingSettingsViewModel by viewModels()
private lateinit var adapter: RoutingSettingRecyclerAdapter
private var mItemTouchHelper: ItemTouchHelper? = null
private val routing_domain_strategy: Array<out String> by lazy {
resources.getStringArray(R.array.routing_domain_strategy)
@@ -56,6 +57,8 @@ class RoutingSettingActivity : BaseActivity() {
//setContentView(binding.root)
setContentViewWithToolbar(binding.root, showHomeAsUp = true, title = getString(R.string.routing_settings_title))
adapter = RoutingSettingRecyclerAdapter(this, viewModel)
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.layoutManager = LinearLayoutManager(this)
addCustomDividerToRecyclerView(binding.recyclerView, this, R.drawable.custom_divider)
@@ -196,8 +199,7 @@ class RoutingSettingActivity : BaseActivity() {
@SuppressLint("NotifyDataSetChanged")
fun refreshData() {
rulesets.clear()
rulesets.addAll(MmkvManager.decodeRoutingRulesets() ?: mutableListOf())
viewModel.reload()
adapter.notifyDataSetChanged()
}
}
@@ -8,18 +8,22 @@ import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.v2ray.ang.databinding.ItemRecyclerRoutingSettingBinding
import com.v2ray.ang.handler.SettingsManager
import com.v2ray.ang.helper.ItemTouchHelperAdapter
import com.v2ray.ang.helper.ItemTouchHelperViewHolder
import com.v2ray.ang.viewmodel.RoutingSettingsViewModel
class RoutingSettingRecyclerAdapter(val activity: RoutingSettingActivity) : RecyclerView.Adapter<RoutingSettingRecyclerAdapter.MainViewHolder>(),
class RoutingSettingRecyclerAdapter(
val activity: RoutingSettingActivity,
private val viewModel: RoutingSettingsViewModel
) : RecyclerView.Adapter<RoutingSettingRecyclerAdapter.MainViewHolder>(),
ItemTouchHelperAdapter {
private var mActivity: RoutingSettingActivity = activity
override fun getItemCount() = mActivity.rulesets.size
override fun getItemCount() = viewModel.getAll().size
override fun onBindViewHolder(holder: MainViewHolder, position: Int) {
val ruleset = mActivity.rulesets[position]
val rulesets = viewModel.getAll()
val ruleset = rulesets[position]
holder.itemRoutingSettingBinding.remarks.text = ruleset.remarks
holder.itemRoutingSettingBinding.domainIp.text = (ruleset.domain ?: ruleset.ip ?: ruleset.port)?.toString()
@@ -38,7 +42,7 @@ class RoutingSettingRecyclerAdapter(val activity: RoutingSettingActivity) : Recy
holder.itemRoutingSettingBinding.chkEnable.setOnCheckedChangeListener { it, isChecked ->
if (!it.isPressed) return@setOnCheckedChangeListener
ruleset.enabled = isChecked
SettingsManager.saveRoutingRuleset(position, ruleset)
viewModel.update(position, ruleset)
}
}
@@ -66,7 +70,7 @@ class RoutingSettingRecyclerAdapter(val activity: RoutingSettingActivity) : Recy
}
override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
SettingsManager.swapRoutingRuleset(fromPosition, toPosition)
viewModel.swap(fromPosition, toPosition)
notifyItemMoved(fromPosition, toPosition)
return true
}
@@ -0,0 +1,31 @@
package com.v2ray.ang.viewmodel
import androidx.lifecycle.ViewModel
import com.v2ray.ang.dto.RulesetItem
import com.v2ray.ang.handler.MmkvManager
import com.v2ray.ang.handler.SettingsManager
class RoutingSettingsViewModel : ViewModel() {
private val rulesets: MutableList<RulesetItem> = mutableListOf()
fun getAll(): List<RulesetItem> = rulesets.toList()
fun reload() {
rulesets.clear()
rulesets.addAll(MmkvManager.decodeRoutingRulesets() ?: mutableListOf())
}
fun update(position: Int, item: RulesetItem) {
if (position in rulesets.indices) {
rulesets[position] = item
SettingsManager.saveRoutingRuleset(position, item)
}
}
fun swap(fromPosition: Int, toPosition: Int) {
if (fromPosition in rulesets.indices && toPosition in rulesets.indices) {
SettingsManager.swapRoutingRuleset(fromPosition, toPosition)
}
}
}