From 5a4ecce0cafda59901d15322190b52faf02a4413 Mon Sep 17 00:00:00 2001 From: Ganing Date: Fri, 26 Dec 2025 11:09:36 +0800 Subject: [PATCH 1/2] feat:add change TunnelStateMode button on main design --- .../com/github/kr328/clash/MainActivity.kt | 20 ++++ .../github/kr328/clash/design/MainDesign.kt | 10 ++ design/src/main/res/layout/design_main.xml | 99 +++++++++++++++++++ 3 files changed, 129 insertions(+) diff --git a/app/src/main/java/com/github/kr328/clash/MainActivity.kt b/app/src/main/java/com/github/kr328/clash/MainActivity.kt index c4237906b2..936d11ec14 100644 --- a/app/src/main/java/com/github/kr328/clash/MainActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/MainActivity.kt @@ -23,8 +23,16 @@ import kotlinx.coroutines.selects.select import kotlinx.coroutines.withContext import java.util.concurrent.TimeUnit import com.github.kr328.clash.design.R +import com.github.kr328.clash.core.model.TunnelState +import com.github.kr328.clash.core.Clash class MainActivity : BaseActivity() { + private val modeMap = mapOf( + MainDesign.Request.ToggleDirectMode to TunnelState.Mode.Direct, + MainDesign.Request.ToggleGlobalMode to TunnelState.Mode.Global, + MainDesign.Request.ToggleRuleMode to TunnelState.Mode.Rule + ) + override suspend fun main() { val design = MainDesign(this) @@ -53,6 +61,16 @@ class MainActivity : BaseActivity() { else design.startClash() } + in modeMap.keys -> { + design.showModeSwitchTips() + withClash { + val o = queryOverride(Clash.OverrideSlot.Session) + + o.mode = modeMap[it]!! + + patchOverride(Clash.OverrideSlot.Session, o) + } + } MainDesign.Request.OpenProxy -> startActivity(ProxyActivity::class.intent) MainDesign.Request.OpenProfiles -> @@ -72,6 +90,8 @@ class MainActivity : BaseActivity() { startActivity(HelpActivity::class.intent) MainDesign.Request.OpenAbout -> design.showAbout(queryAppVersionName()) + + else -> {} } } if (clashRunning) { diff --git a/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt b/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt index f418e488d9..5f95234f71 100644 --- a/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt +++ b/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt @@ -2,6 +2,7 @@ package com.github.kr328.clash.design import android.content.Context import android.view.View +import android.widget.Toast import androidx.appcompat.app.AlertDialog import com.github.kr328.clash.core.model.TunnelState import com.github.kr328.clash.core.util.trafficTotal @@ -16,6 +17,9 @@ import kotlinx.coroutines.withContext class MainDesign(context: Context) : Design(context) { enum class Request { ToggleStatus, + ToggleDirectMode, + ToggleGlobalMode, + ToggleRuleMode, OpenProxy, OpenProfiles, OpenProviders, @@ -78,6 +82,12 @@ class MainDesign(context: Context) : Design(context) { } } + suspend fun showModeSwitchTips() { + withContext(Dispatchers.Main) { + Toast.makeText(context, R.string.mode_switch_tips, Toast.LENGTH_LONG).show() + } + } + init { binding.self = this diff --git a/design/src/main/res/layout/design_main.xml b/design/src/main/res/layout/design_main.xml index 1d02d7b403..cec8a4b933 100644 --- a/design/src/main/res/layout/design_main.xml +++ b/design/src/main/res/layout/design_main.xml @@ -88,6 +88,105 @@ app:subtext="@{clashRunning ? @string/format_traffic_forwarded(forwarded) : @string/tap_to_start}" app:text="@{clashRunning ? @string/running : @string/stopped}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Fri, 26 Dec 2025 16:19:26 +0800 Subject: [PATCH 2/2] fix:improve ui --- .../github/kr328/clash/design/MainDesign.kt | 20 +++ design/src/main/res/layout/design_main.xml | 125 +++++------------- 2 files changed, 51 insertions(+), 94 deletions(-) diff --git a/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt b/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt index 5f95234f71..c14da24234 100644 --- a/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt +++ b/design/src/main/java/com/github/kr328/clash/design/MainDesign.kt @@ -61,6 +61,16 @@ class MainDesign(context: Context) : Design(context) { TunnelState.Mode.Rule -> context.getString(R.string.rule_mode) else -> context.getString(R.string.rule_mode) } + val viewId = when (mode) { + TunnelState.Mode.Direct -> R.id.btnDirect + TunnelState.Mode.Global -> R.id.btnGlobal + TunnelState.Mode.Rule -> R.id.btnRule + else -> View.NO_ID + } + // 避免重复设置导致死循环 + if (binding.toggleGroup.checkedButtonId != viewId) { + binding.toggleGroup.check(viewId) + } } } @@ -93,6 +103,16 @@ class MainDesign(context: Context) : Design(context) { binding.colorClashStarted = context.resolveThemedColor(com.google.android.material.R.attr.colorPrimary) binding.colorClashStopped = context.resolveThemedColor(R.attr.colorClashStopped) + binding.toggleGroup.addOnButtonCheckedListener { _, checkedId, isChecked -> + if (isChecked) { + when (checkedId) { + R.id.btnDirect -> requests.trySend(Request.ToggleDirectMode) + R.id.btnGlobal -> requests.trySend(Request.ToggleGlobalMode) + R.id.btnRule -> requests.trySend(Request.ToggleRuleMode) + } + } + } + } fun request(request: Request) { diff --git a/design/src/main/res/layout/design_main.xml b/design/src/main/res/layout/design_main.xml index cec8a4b933..54e43f8dd5 100644 --- a/design/src/main/res/layout/design_main.xml +++ b/design/src/main/res/layout/design_main.xml @@ -88,114 +88,51 @@ app:subtext="@{clashRunning ? @string/format_traffic_forwarded(forwarded) : @string/tap_to_start}" app:text="@{clashRunning ? @string/running : @string/stopped}" /> - + + + android:visibility="@{clashRunning ? View.VISIBLE : View.GONE}" + app:checkedButton="@+id/btnRule" + app:selectionRequired="true" + app:singleSelection="true"> - - - - - - - - - - - + + - - - - - - - - - + + - - - - - - - - + android:text="@string/direct_mode" /> - +