RadioGroup- dynamiczna zmiana kolorów
Można powiedzieć: How do I use radio buttons in Kotlin?RadioGroup klasa, która służy do tworzenia grup wielokrotnego wykluczenia dla zestawu przycisków opcji. Zaznaczenie jednego przycisku opcji (RadioButton) należącego do jednej grupy powoduje odznaczenie wszystkich wcześniej zaznaczonych przycisków opcji (RadioButton) w tej samej grupie.
Początkowo wszystkie przyciski opcji RadioButton są niezaznaczone/ niewybrane. Grupę opcji przycisków RadioButton można wyczyścić z zaznaczonego stanu. Wybór konkretnego przycisku RadioButton jest identyfikowany poprzez unikalny identyfikator tego przycisku zdefiniowany w pliku układu XML.
Cel
Tworzymy aplikację przy pomocy, której zmienimy wartości kolorów w formacie ARGB przez wybór danej składowej za pomocą kontrolek RadioButton. Aplikacja jest innym sposobem rozwiązani problemu z tematu pasek postępu
Obsługę przycisków RadioButton zrealizujemy na dwa sposoby. Pierwszym sposobem będzie wykorzystanie obsługi pojedynczego przycisku RadioButton poprzez metodę setOnClickListener, która zostaje wywołana w momencie kliknięcia lub dotknięcia przycisku. Drugi sposób, to wykorzystanie jednej wspólnej funkcji podpiętej do zdarzenia android:onClick.
W obu sposobach zapamiętamy wybór klikniętego przycisku. Obsługę wyboru zrealizujemy jednym suwakiem- kontrolką SeekBar
Układ widoku dla sposobu pierwszego
Przypisujemy unikalny identyfikator dla kontrolki RadioGroup
Enumerator wyboru
Możliwe opcje wybory składowej koloru zdefiniujemy jako zbiór opcji enumertora. Przechodzimy do pliku MojeFunkcje.kt i wprowadzamy poniższy kod.
Wskazówka:
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
class MojeFunkcje {
enum class OPCJA {
BRAK,CZERWONY,ZIELONY,NIEBIESKI,ALFA
}
var opcja=OPCJA.BRAK
var a=255//kanał alpha
var r=0//składowa czerwona
var g=0//składowa zielona
var b=0//składowa niebieska
var kolor=Color.argb(a,r,g,b)
public fun DajKolor():Int{
kolor=Color.argb(a,r,g,b)
return kolor
}
public fun Zamknij(aktywnosc:AppCompatActivity){
aktywnosc.finish();
System.exit(0);
}
}
Obsługa RadioButton?ów
W głównym pliku aktywności dopisujemy odpowiednie biblioteki. Zbiór importowanych bibliotek przedstawiam poniżej
Wskazówka:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.graphics.Color
import android.widget.Button
import android.widget.RadioButton
import android.widget.TextView
import android.view.View
import android.widget.SeekBar
Aby obsłużyć pojedynczy przycisk RadioButton należy wykorzystać metodę setOnClickListner. Piszemy funkcję, w której zrealizujemy powyższe
Wskazówka:
//wersja I- osobna obsługa RadioButton'ów
fun obslugaRadioButonow(){
//przypisz kontrolki RadioButton do zmiennych
val radioButton1 = findViewById<RadioButton>(R.id.radioButton1)
val radioButton2 = findViewById<RadioButton>(R.id.radioButton2)
val radioButton3 = findViewById<RadioButton>(R.id.radioButton3)
val radioButton4 = findViewById<RadioButton>(R.id.radioButton4)
//przypisz kontrolke do zmiany tekstu wybor
val txt = findViewById<TextView>(R.id.textView2)
val pasek=findViewById<SeekBar>(R.id.seekBar1)
//rejestruj słuchaczy kliknięć
radioButton1.setOnClickListener {
mojeFunkcje.opcja=MojeFunkcje.OPCJA.CZERWONY
txt.setText(radioButton1.text)
txt.setBackgroundColor(Color.argb(255, mojeFunkcje.r, 0, 0))
pasek.setProgress(mojeFunkcje.r)
}
radioButton2.setOnClickListener {
mojeFunkcje.opcja=MojeFunkcje.OPCJA.ZIELONY
txt.setText(radioButton2.text)
txt.setBackgroundColor(Color.argb(255, 0,mojeFunkcje.g, 0))
pasek.setProgress(mojeFunkcje.g)
}
radioButton3.setOnClickListener {
mojeFunkcje.opcja=MojeFunkcje.OPCJA.NIEBIESKI
txt.setText(radioButton3.text)
txt.setBackgroundColor(Color.argb(255, 0,0,mojeFunkcje.b))
pasek.setProgress(mojeFunkcje.b)
}
radioButton4.setOnClickListener {
mojeFunkcje.opcja=MojeFunkcje.OPCJA.ALFA
txt.setText(radioButton4.text)
txt.setBackgroundColor(Color.argb(mojeFunkcje.a, 127,127, 127))
pasek.setProgress(mojeFunkcje.a)
}
}
Funkcję wywołamy w funkcji onCreate
Wskazówka:
class OknoGlowne : AppCompatActivity() {
var mojeFunkcje=MojeFunkcje()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_okno_glowne)
//kod słuchacza dla przycisku Button1
val button1 = findViewById<Button>(R.id.button1)
button1.setOnClickListener {
mojeFunkcje.Zamknij(this)
}
val txtHello=findViewById<TextView>(R.id.textHelloWorld)
txtHello.setBackgroundColor(mojeFunkcje.DajKolor())
//wywołanie I wersji obsługi RadioButton'ów
obslugaRadioButonow()
}
Skompiluj program i sprawdź efekt działania. Na tym etapie aplikacja reaguje na wybór przycisku RadioButton
Obsługa paska postępu SeekBar
Wykorzystamy słuchacza zmian paska postępu setOnSeekBarChangeListener, metodę dopiszemy w funkcji onCreate, której kod po zmianach wygląda jak poniżej. W kodzie znajduje się funkcja wielokrotnego wyboru when (odpowiednik funkcji switch)
Wskazówka:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_okno_glowne)
//kod słuchacza dla przycisku Button1
val button1 = findViewById<Button>(R.id.button1)
button1.setOnClickListener {
mojeFunkcje.Zamknij(this)
}
val txtHello=findViewById<TextView>(R.id.textHelloWorld)
txtHello.setBackgroundColor(mojeFunkcje.DajKolor())
//wywołanie I wersji obsługi RadioButton'ów
obslugaRadioButonow()
//obsluga paska SeekBar
val pasek=findViewById<SeekBar>(R.id.seekBar1)
pasek.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener{
val txt=findViewById<TextView>(R.id.textView2)
override fun onProgressChanged(seekBar: SeekBar?, p1: Int, fromUser: Boolean) {
when (mojeFunkcje.opcja) {
MojeFunkcje.OPCJA.CZERWONY -> {
txt.setBackgroundColor(Color.argb(255, p1, 0, 0))
mojeFunkcje.r = p1
}
MojeFunkcje.OPCJA.ZIELONY -> {
txt.setBackgroundColor(Color.argb(255, 0, p1, 0))
mojeFunkcje.g = p1
}
MojeFunkcje.OPCJA.NIEBIESKI -> {
txt.setBackgroundColor(Color.argb(255, 0, 0, p1))
mojeFunkcje.b = p1
}
MojeFunkcje.OPCJA.ALFA -> {
txt.setBackgroundColor(Color.argb(p1, 127, 127, 127))
mojeFunkcje.a = p1
}
else -> {}
}
val txtHelloWorld = findViewById<TextView>(R.id.textHelloWorld)
txtHelloWorld.setBackgroundColor(mojeFunkcje.DajKolor())
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
}
Po skompilowaniu aplikacji można już zmienić kolor tła kontrolki TextView
Metoda wspólnej funkcji onClick
Ta metoda jest w kodowaniu dużo krótsza. W metodzie wykorzystamy wspólny kod dla każdej kontrolki RadioButton. Wybraną aktywną kontrolkę przycisku RadioButton rozpoznamy poprzez jej identyfikator.
Do układu dodajemy kolejną kontrolkę RadioGroup oraz cztery kontrolki RadioButton
Piszemy własną funkcję o jednym argumencie typu View. Klasa View reprezentuje podstawowy element konstrukcyjny komponentów interfejsu użytkownika.View zajmuje prostokątny obszar na ekranie i odpowiada za rysowanie oraz obsługę zdarzeń. View to klasa bazowa dlawidżetów, które służą do tworzenia interaktywnych komponentów interfejsu użytkownika (przyciski, pola tekstowe itp.) W naszej funkcji będziemy rzutować typ View na kontrolkę RadioButton
Wskazówka:
fun onRadioButtonClicked(rb: View) {
if (rb is RadioButton && rb.isChecked) {
val txt = findViewById<TextView>(R.id.textView2)
txt.setText(rb.text)
val pasek=findViewById<SeekBar>(R.id.seekBar1)
when (rb.id){
R.id.radioButton5->{
mojeFunkcje.opcja=MojeFunkcje.OPCJA.CZERWONY
txt.setBackgroundColor(Color.argb(255, mojeFunkcje.r, 0, 0))
pasek.setProgress(mojeFunkcje.r)
}
R.id.radioButton6->{
mojeFunkcje.opcja=MojeFunkcje.OPCJA.ZIELONY
txt.setBackgroundColor(Color.argb(255, 0,mojeFunkcje.g, 0))
pasek.setProgress(mojeFunkcje.g)
}
R.id.radioButton7->{
mojeFunkcje.opcja=MojeFunkcje.OPCJA.NIEBIESKI
txt.setBackgroundColor(Color.argb(255, 0,0,mojeFunkcje.b))
pasek.setProgress(mojeFunkcje.b)
}
R.id.radioButton8->{
mojeFunkcje.opcja=MojeFunkcje.OPCJA.ALFA
txt.setBackgroundColor(Color.argb(mojeFunkcje.a, 127,127, 127))
pasek.setProgress(mojeFunkcje.a)
}
}
}
}
Przechodzimy do widoku projektu układu. Zaznaczamy wybrane przyciski RadioButton i odszukujemy pola metody zdarzenia onClick. Do pola podpinamy naszą funkcję. Patrz poniższa ilustracja
Prawidłowe podpięcie funkcji zostanie zapisane w pliku XML tworzonego układu. Poniżej fragment kodu
Wskazówka:
<RadioButton
android:id="@+id/radioButton5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onRadioButtonClicked"
android:text="Składowa czerwona" />
Skompiluj aplikację i sprawdź działanie nowej grupy przycisków RadioButton
Pełny kod głównego pliku aplikacji
Wskazówka:
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.graphics.Color
import android.widget.Button
import android.widget.RadioButton
import android.widget.TextView
import android.view.View
import android.widget.SeekBar
class OknoGlowne : AppCompatActivity() {
var mojeFunkcje=MojeFunkcje()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_okno_glowne)
//kod słuchacza dla przycisku Button1
val button1 = findViewById<Button>(R.id.button1)
button1.setOnClickListener {
mojeFunkcje.Zamknij(this)
}
val txtHello=findViewById<TextView>(R.id.textHelloWorld)
txtHello.setBackgroundColor(mojeFunkcje.DajKolor())
//wywołanie I wersji obsługi RadioButton'ów
obslugaRadioButonow()
//obsluga paska SeekBar
val pasek=findViewById<SeekBar>(R.id.seekBar1)
pasek.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener{
val txt=findViewById<TextView>(R.id.textView2)
override fun onProgressChanged(seekBar: SeekBar?, p1: Int, fromUser: Boolean) {
when (mojeFunkcje.opcja) {
MojeFunkcje.OPCJA.CZERWONY -> {
txt.setBackgroundColor(Color.argb(255, p1, 0, 0))
mojeFunkcje.r = p1
}
MojeFunkcje.OPCJA.ZIELONY -> {
txt.setBackgroundColor(Color.argb(255, 0, p1, 0))
mojeFunkcje.g = p1
}
MojeFunkcje.OPCJA.NIEBIESKI -> {
txt.setBackgroundColor(Color.argb(255, 0, 0, p1))
mojeFunkcje.b = p1
}
MojeFunkcje.OPCJA.ALFA -> {
txt.setBackgroundColor(Color.argb(p1, 127, 127, 127))
mojeFunkcje.a = p1
}
else -> {}
}
val txtHelloWorld = findViewById<TextView>(R.id.textHelloWorld)
txtHelloWorld.setBackgroundColor(mojeFunkcje.DajKolor())
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
}
//wersja I- osobna obsługa RadioButton'ów
fun obslugaRadioButonow(){
//przypisz kontrolki RadioButton do zmiennych
val radioButton1 = findViewById<RadioButton>(R.id.radioButton1)
val radioButton2 = findViewById<RadioButton>(R.id.radioButton2)
val radioButton3 = findViewById<RadioButton>(R.id.radioButton3)
val radioButton4 = findViewById<RadioButton>(R.id.radioButton4)
//przypisz kontrolke do zmiany tekstu wybor
val txt = findViewById<TextView>(R.id.textView2)
val pasek=findViewById<SeekBar>(R.id.seekBar1)
//rejestruj słuchaczy kliknięć
radioButton1.setOnClickListener {
mojeFunkcje.opcja=MojeFunkcje.OPCJA.CZERWONY
txt.setText(radioButton1.text)
txt.setBackgroundColor(Color.argb(255, mojeFunkcje.r, 0, 0))
pasek.setProgress(mojeFunkcje.r)
}
radioButton2.setOnClickListener {
mojeFunkcje.opcja=MojeFunkcje.OPCJA.ZIELONY
txt.setText(radioButton2.text)
txt.setBackgroundColor(Color.argb(255, 0,mojeFunkcje.g, 0))
pasek.setProgress(mojeFunkcje.g)
}
radioButton3.setOnClickListener {
mojeFunkcje.opcja=MojeFunkcje.OPCJA.NIEBIESKI
txt.setText(radioButton3.text)
txt.setBackgroundColor(Color.argb(255, 0,0,mojeFunkcje.b))
pasek.setProgress(mojeFunkcje.b)
}
radioButton4.setOnClickListener {
mojeFunkcje.opcja=MojeFunkcje.OPCJA.ALFA
txt.setText(radioButton4.text)
txt.setBackgroundColor(Color.argb(mojeFunkcje.a, 127,127, 127))
pasek.setProgress(mojeFunkcje.a)
}
}
//wersja II- z wspólnego klikniecia w przycisk
fun onRadioButtonClicked(rb: View) {
if (rb is RadioButton && rb.isChecked) {
val txt = findViewById<TextView>(R.id.textView2)
txt.setText(rb.text)
val pasek=findViewById<SeekBar>(R.id.seekBar1)
when (rb.id){
R.id.radioButton5->{
mojeFunkcje.opcja=MojeFunkcje.OPCJA.CZERWONY
txt.setBackgroundColor(Color.argb(255, mojeFunkcje.r, 0, 0))
pasek.setProgress(mojeFunkcje.r)
}
R.id.radioButton6->{
mojeFunkcje.opcja=MojeFunkcje.OPCJA.ZIELONY
txt.setBackgroundColor(Color.argb(255, 0,mojeFunkcje.g, 0))
pasek.setProgress(mojeFunkcje.g)
}
R.id.radioButton7->{
mojeFunkcje.opcja=MojeFunkcje.OPCJA.NIEBIESKI
txt.setBackgroundColor(Color.argb(255, 0,0,mojeFunkcje.b))
pasek.setProgress(mojeFunkcje.b)
}
R.id.radioButton8->{
mojeFunkcje.opcja=MojeFunkcje.OPCJA.ALFA
txt.setBackgroundColor(Color.argb(mojeFunkcje.a, 127,127, 127))
pasek.setProgress(mojeFunkcje.a)
}
}
}
}
}
Pełny kod pliku MojeFunkcje.kt
Wskazówka:
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
class MojeFunkcje {
enum class OPCJA {
BRAK,CZERWONY,ZIELONY,NIEBIESKI,ALFA
}
var opcja=OPCJA.BRAK
var a=255//kanał alpha
var r=0//składowa czerwona
var g=0//składowa zielona
var b=0//składowa niebieska
var kolor=Color.argb(a,r,g,b)
public fun DajKolor():Int{
kolor=Color.argb(a,r,g,b)
return kolor
}
public fun Zamknij(aktywnosc:AppCompatActivity){
aktywnosc.finish();
System.exit(0);
}
}