Skip to content

Commit 7b4a457

Browse files
committed
Enhance App Detail quick actions UI - Replace button grid with ChipGroup for cleaner look - Fix toggle background text (Allow/Restrict based on status) - Fix toggle enable text (Freeze/Unfreeze based on state) - Primary actions (Launch, Info) at top with tonal buttons - Control actions as chips with proper enable/disable states
1 parent e6b526b commit 7b4a457

File tree

2 files changed

+75
-83
lines changed

2 files changed

+75
-83
lines changed

app/src/main/java/com/appcontrolx/ui/AppDetailBottomSheet.kt

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.appcontrolx.service.BatteryPolicyManager
2121
import com.appcontrolx.service.PermissionBridge
2222
import com.appcontrolx.utils.SafetyValidator
2323
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
24+
import com.google.android.material.chip.Chip
2425
import kotlinx.coroutines.Dispatchers
2526
import kotlinx.coroutines.launch
2627
import kotlinx.coroutines.withContext
@@ -192,7 +193,7 @@ class AppDetailBottomSheet : BottomSheetDialogFragment() {
192193
binding.tvBatteryStatus.text = text
193194
binding.tvBatteryStatus.setTextColor(resources.getColor(color, null))
194195

195-
// Update button text
196+
// Update chip text based on current status
196197
binding.btnToggleBackground.text = if (currentBgStatus == BackgroundStatus.RESTRICTED) {
197198
getString(R.string.action_allow_bg)
198199
} else {
@@ -202,22 +203,24 @@ class AppDetailBottomSheet : BottomSheetDialogFragment() {
202203

203204
private fun setupButtons() {
204205
val packageName = arguments?.getString(ARG_PACKAGE_NAME) ?: return
206+
val isEnabled = arguments?.getBoolean(ARG_IS_ENABLED, true) ?: true
205207
val hasMode = executionMode !is ExecutionMode.None
206208

207209
val allowedActions = SafetyValidator.getAllowedActions(packageName)
208210
val isForceStopOnly = SafetyValidator.isForceStopOnly(packageName)
209211
val isCritical = SafetyValidator.isCritical(packageName)
210212

211-
binding.btnForceStop.isEnabled = hasMode && !isCritical
212-
binding.btnToggleEnable.isEnabled = hasMode && SafetyValidator.AllowedAction.FREEZE in allowedActions
213-
binding.btnToggleBackground.isEnabled = hasMode && SafetyValidator.AllowedAction.RESTRICT_BACKGROUND in allowedActions
214-
binding.btnUninstall.isEnabled = hasMode && SafetyValidator.AllowedAction.UNINSTALL in allowedActions
213+
// Update freeze/unfreeze chip text based on current state
214+
binding.btnToggleEnable.text = if (isEnabled) getString(R.string.action_freeze)
215+
else getString(R.string.action_unfreeze)
215216

216-
if (isForceStopOnly) {
217-
binding.btnToggleEnable.alpha = 0.5f
218-
binding.btnToggleBackground.alpha = 0.5f
219-
binding.btnUninstall.alpha = 0.5f
220-
}
217+
// Set chip enabled states
218+
setChipEnabled(binding.btnForceStop, hasMode && !isCritical)
219+
setChipEnabled(binding.btnToggleEnable, hasMode && SafetyValidator.AllowedAction.FREEZE in allowedActions)
220+
setChipEnabled(binding.btnToggleBackground, hasMode && SafetyValidator.AllowedAction.RESTRICT_BACKGROUND in allowedActions)
221+
setChipEnabled(binding.btnUninstall, hasMode && SafetyValidator.AllowedAction.UNINSTALL in allowedActions)
222+
setChipEnabled(binding.btnClearCache, hasMode && !isCritical)
223+
setChipEnabled(binding.btnClearData, hasMode && !isCritical)
221224

222225
binding.btnForceStop.setOnClickListener {
223226
if (isCritical) { showProtectedWarning(); return@setOnClickListener }
@@ -229,7 +232,7 @@ class AppDetailBottomSheet : BottomSheetDialogFragment() {
229232
binding.btnToggleEnable.setOnClickListener {
230233
if (isForceStopOnly || isCritical) { showProtectedWarning(); return@setOnClickListener }
231234
val app = appInfo ?: return@setOnClickListener
232-
val actionName = if (app.isEnabled) getString(R.string.action_disable) else getString(R.string.action_enable)
235+
val actionName = if (app.isEnabled) getString(R.string.action_freeze) else getString(R.string.action_unfreeze)
233236
executeActionWithLoading(actionName) {
234237
if (app.isEnabled) policyManager?.freezeApp(app.packageName)
235238
else policyManager?.unfreezeApp(app.packageName)
@@ -269,16 +272,8 @@ class AppDetailBottomSheet : BottomSheetDialogFragment() {
269272
}
270273
}
271274

272-
binding.btnLaunchApp.setOnClickListener {
273-
launchApp()
274-
}
275-
275+
binding.btnLaunchApp.setOnClickListener { launchApp() }
276276
binding.btnOpenSettings.setOnClickListener { openAppSettings() }
277-
278-
// Enable/disable buttons based on mode
279-
binding.btnClearCache.isEnabled = hasMode && !isCritical
280-
binding.btnClearData.isEnabled = hasMode && !isCritical
281-
binding.btnLaunchApp.isEnabled = true // Always enabled
282277
}
283278

284279
private fun launchApp() {
@@ -347,6 +342,11 @@ class AppDetailBottomSheet : BottomSheetDialogFragment() {
347342
binding.btnOpenSettings.isEnabled = enabled
348343
}
349344

345+
private fun setChipEnabled(chip: Chip, enabled: Boolean) {
346+
chip.isEnabled = enabled
347+
chip.alpha = if (enabled) 1.0f else 0.5f
348+
}
349+
350350
private fun openAppSettings() {
351351
val packageName = appInfo?.packageName ?: return
352352
try {

app/src/main/res/layout/bottom_sheet_app_detail.xml

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -283,97 +283,89 @@
283283
android:textStyle="bold"
284284
android:textSize="14sp" />
285285

286-
<!-- Row 1: Force Stop, Freeze/Unfreeze -->
286+
<!-- Primary Actions: Launch & Settings -->
287287
<LinearLayout
288288
android:layout_width="match_parent"
289289
android:layout_height="wrap_content"
290290
android:layout_marginTop="12dp"
291291
android:orientation="horizontal">
292292
<Button
293-
android:id="@+id/btnForceStop"
293+
android:id="@+id/btnLaunchApp"
294294
android:layout_width="0dp"
295295
android:layout_height="wrap_content"
296296
android:layout_weight="1"
297-
android:text="@string/action_force_stop"
298-
style="@style/Widget.Material3.Button.OutlinedButton" />
297+
android:text="@string/action_launch"
298+
style="@style/Widget.Material3.Button.TonalButton" />
299299
<Button
300-
android:id="@+id/btnToggleEnable"
300+
android:id="@+id/btnOpenSettings"
301301
android:layout_width="0dp"
302302
android:layout_height="wrap_content"
303303
android:layout_weight="1"
304304
android:layout_marginStart="8dp"
305-
android:text="@string/action_disable"
306-
style="@style/Widget.Material3.Button.OutlinedButton" />
305+
android:text="@string/btn_info"
306+
style="@style/Widget.Material3.Button.TonalButton" />
307307
</LinearLayout>
308308

309-
<!-- Row 2: Background, Uninstall -->
310-
<LinearLayout
309+
<!-- Control Actions -->
310+
<com.google.android.material.chip.ChipGroup
311311
android:layout_width="match_parent"
312312
android:layout_height="wrap_content"
313-
android:layout_marginTop="8dp"
314-
android:orientation="horizontal">
315-
<Button
313+
android:layout_marginTop="12dp"
314+
app:singleLine="false">
315+
316+
<com.google.android.material.chip.Chip
317+
android:id="@+id/btnForceStop"
318+
android:layout_width="wrap_content"
319+
android:layout_height="wrap_content"
320+
android:text="@string/action_force_stop"
321+
app:chipBackgroundColor="@color/surface_container"
322+
app:chipStrokeWidth="1dp"
323+
app:chipStrokeColor="@color/outline" />
324+
325+
<com.google.android.material.chip.Chip
326+
android:id="@+id/btnToggleEnable"
327+
android:layout_width="wrap_content"
328+
android:layout_height="wrap_content"
329+
android:text="@string/action_freeze"
330+
app:chipBackgroundColor="@color/surface_container"
331+
app:chipStrokeWidth="1dp"
332+
app:chipStrokeColor="@color/outline" />
333+
334+
<com.google.android.material.chip.Chip
316335
android:id="@+id/btnToggleBackground"
317-
android:layout_width="0dp"
336+
android:layout_width="wrap_content"
318337
android:layout_height="wrap_content"
319-
android:layout_weight="1"
320338
android:text="@string/action_restrict_bg"
321-
style="@style/Widget.Material3.Button.OutlinedButton" />
322-
<Button
323-
android:id="@+id/btnUninstall"
324-
android:layout_width="0dp"
325-
android:layout_height="wrap_content"
326-
android:layout_weight="1"
327-
android:layout_marginStart="8dp"
328-
android:text="@string/action_uninstall"
329-
android:textColor="@color/status_negative"
330-
style="@style/Widget.Material3.Button.OutlinedButton" />
331-
</LinearLayout>
339+
app:chipBackgroundColor="@color/surface_container"
340+
app:chipStrokeWidth="1dp"
341+
app:chipStrokeColor="@color/outline" />
332342

333-
<!-- Row 3: Clear Cache, Clear Data -->
334-
<LinearLayout
335-
android:layout_width="match_parent"
336-
android:layout_height="wrap_content"
337-
android:layout_marginTop="8dp"
338-
android:orientation="horizontal">
339-
<Button
343+
<com.google.android.material.chip.Chip
340344
android:id="@+id/btnClearCache"
341-
android:layout_width="0dp"
345+
android:layout_width="wrap_content"
342346
android:layout_height="wrap_content"
343-
android:layout_weight="1"
344347
android:text="@string/action_clear_cache"
345-
style="@style/Widget.Material3.Button.OutlinedButton" />
346-
<Button
348+
app:chipBackgroundColor="@color/surface_container"
349+
app:chipStrokeWidth="1dp"
350+
app:chipStrokeColor="@color/outline" />
351+
352+
<com.google.android.material.chip.Chip
347353
android:id="@+id/btnClearData"
348-
android:layout_width="0dp"
354+
android:layout_width="wrap_content"
349355
android:layout_height="wrap_content"
350-
android:layout_weight="1"
351-
android:layout_marginStart="8dp"
352356
android:text="@string/action_clear_data"
353-
android:textColor="@color/warning_color"
354-
style="@style/Widget.Material3.Button.OutlinedButton" />
355-
</LinearLayout>
357+
app:chipBackgroundColor="@color/surface_container"
358+
app:chipStrokeWidth="1dp"
359+
app:chipStrokeColor="@color/outline" />
356360

357-
<!-- Row 4: Launch, Open Settings -->
358-
<LinearLayout
359-
android:layout_width="match_parent"
360-
android:layout_height="wrap_content"
361-
android:layout_marginTop="8dp"
362-
android:orientation="horizontal">
363-
<Button
364-
android:id="@+id/btnLaunchApp"
365-
android:layout_width="0dp"
366-
android:layout_height="wrap_content"
367-
android:layout_weight="1"
368-
android:text="@string/action_launch"
369-
style="@style/Widget.Material3.Button.TonalButton" />
370-
<Button
371-
android:id="@+id/btnOpenSettings"
372-
android:layout_width="0dp"
361+
<com.google.android.material.chip.Chip
362+
android:id="@+id/btnUninstall"
363+
android:layout_width="wrap_content"
373364
android:layout_height="wrap_content"
374-
android:layout_weight="1"
375-
android:layout_marginStart="8dp"
376-
android:text="@string/detail_open_settings"
377-
style="@style/Widget.Material3.Button.TonalButton" />
378-
</LinearLayout>
365+
android:text="@string/action_uninstall"
366+
app:chipBackgroundColor="@color/surface_container"
367+
app:chipStrokeWidth="1dp"
368+
app:chipStrokeColor="@color/status_negative" />
369+
370+
</com.google.android.material.chip.ChipGroup>
379371
</LinearLayout>

0 commit comments

Comments
 (0)