Add user-defined button labels with color change on press

- PrefsHelper: PREF_LABEL1, PREF_LABEL2 constants
- SettingsActivity: EditText fields with Done-keyboard action to save labels
- MainActivity: buttons show user label, colorAccent on press, textAllCaps disabled
- activity_main.xml: textAllCaps=false for case-sensitive labels
This commit is contained in:
eddy 2026-07-29 20:25:27 +02:00
commit a3142ea85b
6 changed files with 109 additions and 8 deletions

View file

@ -3,6 +3,7 @@ package com.eddy.atomrelay
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.ColorStateList
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@ -12,6 +13,7 @@ import android.widget.ImageButton
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity(), BleCallbacks {
@ -28,6 +30,8 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
private lateinit var relay1Button: Button
private lateinit var relay2Button: Button
private var lastTheme: String? = null
private var originalTint1: ColorStateList? = null
private var originalTint2: ColorStateList? = null
override fun onStatusChanged(status: BleStatus) {
when (status) {
@ -61,8 +65,8 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
relay2Button.setOnTouchListener(null)
relay1Button.setOnClickListener(null)
relay2Button.setOnClickListener(null)
relay1Button.text = getString(R.string.button_retry_scan)
relay2Button.text = getString(R.string.button_hold)
loadButtonLabel(relay1Button, PrefsHelper.PREF_LABEL1, R.string.button_retry_scan)
loadButtonLabel(relay2Button, PrefsHelper.PREF_LABEL2, R.string.button_hold)
relay2Button.isEnabled = false
relay1Button.isEnabled = true
relay1Button.setOnClickListener {
@ -113,6 +117,8 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
recreate()
return
}
loadButtonLabel(relay1Button, PrefsHelper.PREF_LABEL1, R.string.button_hold)
loadButtonLabel(relay2Button, PrefsHelper.PREF_LABEL2, R.string.button_hold)
if (!manager.hasPermissions()) {
requestPermissions()
return
@ -142,17 +148,20 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
private fun setupRelayButton() {
relay1Button.setOnClickListener(null)
relay1Button.text = getString(R.string.button_hold)
loadButtonLabel(relay1Button, PrefsHelper.PREF_LABEL1, R.string.button_hold)
originalTint1 = relay1Button.backgroundTintList
val accentColor = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.colorAccent))
relay1Button.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
manager.sendRelayCommand(0x01.toByte())
relay1Button.text = getString(R.string.button_on)
relay1Button.backgroundTintList = accentColor
true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
manager.sendRelayCommand(0x00.toByte())
relay1Button.text = getString(R.string.button_hold)
relay1Button.backgroundTintList = originalTint1
true
}
else -> false
@ -162,17 +171,20 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
private fun setupRelay2Button() {
relay2Button.setOnClickListener(null)
relay2Button.text = getString(R.string.button_hold)
loadButtonLabel(relay2Button, PrefsHelper.PREF_LABEL2, R.string.button_hold)
originalTint2 = relay2Button.backgroundTintList
val accentColor = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.colorAccent))
relay2Button.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
manager.sendRelayCommand(0x02.toByte())
relay2Button.text = getString(R.string.button_on)
relay2Button.backgroundTintList = accentColor
true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
manager.sendRelayCommand(0x03.toByte())
relay2Button.text = getString(R.string.button_hold)
relay2Button.backgroundTintList = originalTint2
true
}
else -> false
@ -180,6 +192,12 @@ class MainActivity : AppCompatActivity(), BleCallbacks {
}
}
private fun loadButtonLabel(button: Button, prefKey: String, fallbackResId: Int) {
val prefs = PrefsHelper.getPrefs(this)
val label = prefs.getString(prefKey, "")?.trim()
button.text = if (label.isNullOrEmpty()) getString(fallbackResId) else label
}
private fun requestPermissions() {
val perms = manager.getRequiredPermissions()
ActivityCompat.requestPermissions(this, perms, 1)

View file

@ -13,6 +13,8 @@ object PrefsHelper {
const val PREF_UUID = "device_uuid"
const val PREF_SEQ = "seq_counter"
const val PREF_THEME = "theme"
const val PREF_LABEL1 = "label_relay1"
const val PREF_LABEL2 = "label_relay2"
const val SEQ_MAX = 1_000_000
fun applyTheme(context: Context) {

View file

@ -17,8 +17,11 @@ import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.Button
import android.widget.CheckBox
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.RadioGroup
import android.widget.TextView
@ -136,6 +139,7 @@ class SettingsActivity : AppCompatActivity() {
registerReceiver(usbDetachedReceiver, IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED), Context.RECEIVER_EXPORTED)
setupThemeButtons()
setupLabelEditTexts()
}
override fun onResume() {
@ -200,6 +204,33 @@ class SettingsActivity : AppCompatActivity() {
return true
}
private fun setupLabelEditTexts() {
val prefs = PrefsHelper.getPrefs(this)
val label1 = findViewById<EditText>(R.id.labelRelay1)
val label2 = findViewById<EditText>(R.id.labelRelay2)
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
label1.setText(prefs.getString(PrefsHelper.PREF_LABEL1, ""))
label2.setText(prefs.getString(PrefsHelper.PREF_LABEL2, ""))
label1.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
prefs.edit().putString(PrefsHelper.PREF_LABEL1, label1.text.toString().trim()).apply()
imm.hideSoftInputFromWindow(label1.windowToken, 0)
label1.clearFocus()
}
false
}
label2.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
prefs.edit().putString(PrefsHelper.PREF_LABEL2, label2.text.toString().trim()).apply()
imm.hideSoftInputFromWindow(label2.windowToken, 0)
label2.clearFocus()
}
false
}
}
// === Key Exchange ===
private fun startKeyExchange() {

View file

@ -26,6 +26,7 @@
android:layout_height="200dp"
android:text="1"
android:textSize="24sp"
android:textAllCaps="false"
android:enabled="false" />
<Button
@ -35,6 +36,7 @@
android:layout_marginStart="16dp"
android:text="2"
android:textSize="24sp"
android:textAllCaps="false"
android:enabled="false" />
</LinearLayout>

View file

@ -45,6 +45,49 @@
android:layout_marginTop="24dp"
android:layout_marginBottom="16dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/section_labels"
android:textSize="14sp"
android:textStyle="bold"
android:layout_marginBottom="8dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="16dp">
<EditText
android:id="@+id/labelRelay1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/hint_label_relay1"
android:maxLines="1"
android:inputType="text"
android:imeOptions="actionDone"
android:gravity="center" />
<EditText
android:id="@+id/labelRelay2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/hint_label_relay2"
android:maxLines="1"
android:inputType="text"
android:imeOptions="actionDone"
android:gravity="center" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"
android:layout_marginBottom="16dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"

View file

@ -55,6 +55,11 @@
<string name="button_close">Sluiten</string>
<string name="button_cancel">Annuleren</string>
<!-- Label customization -->
<string name="section_labels">Knoptekst</string>
<string name="hint_label_relay1">Relay 1</string>
<string name="hint_label_relay2">Relay 2</string>
<!-- Theme -->
<string name="section_theme">Weergave</string>
<string name="theme_system">Systeem</string>