Botón: cambia el color de fondo al hacer clic
-
21-12-2019 - |
Pregunta
Tengo 8 botones en mi actividad.Lo que estoy buscando es que los botones tengan un fondo predeterminado y cuando se hace clic en un botón, el color de fondo debería cambiar a otro color.Esta parte es bastante sencilla.Pero, cuando hago clic en cualquier otro botón, el color de fondo del primer botón debería volver al color predeterminado.Entiendo que esto se hará utilizando "estados selectores", pero no estoy muy seguro de cómo implementarlo.Cuanto más leo sobre esto, más confundida estoy.
Ahora mismo el xml que tengo es el siguiente:en carpeta dibujable
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/blue" android:state_pressed="true"/>
<item android:drawable="@color/dark_grey" android:state_focused="true"/>
<item android:drawable="@drawable/image_border"/>
</selector>
el dibujable/image_border en el xml se usa para definir la forma del botón.A continuación se muestra image_border.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="@color/dark_grey" />
<stroke
android:width="4dp"
android:color="@color/light_grey" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
</shape>
¿Alguien puede ayudarme a cambiar el xml para que se comporte como necesito?
[EDITAR 1]
Todas las respuestas a continuación apuntan hacia un tipo de solución similar.Aquí están los cambios que hice.Pero, aún así, cuando presiono el botón, cambia al color especificado pero inmediatamente vuelve al color predeterminado.
botón_fondo_azul.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/image_border_blue" android:state_pressed="true"/>
<item android:drawable="@color/dark_grey" android:state_focused="true"/>
<item android:drawable="@drawable/image_border"/>
</selector>
imagen_border_azul.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="@color/blue" />
<stroke
android:width="4dp"
android:color="@color/blue" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
</shape>
¿Alguna idea?
Solución
Crear una forma llamada button_pressed.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blue" />
<stroke
android:width="4dp"
android:color="@color/blue" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
</shape>
Supongamos, tiene dos botones cuyas ID son R.id.btn
y R.id.btn1
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:background="@drawable/button_pressed"
android:onClick="onClick"
android:text="Press Me 1" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp"
android:background="@drawable/button_pressed"
android:onClick="onClick"
android:text="Press Me 2" />
</LinearLayout>
Escriba el método onClick()
que le permitirá conservar el color cambiado hasta que se presione otro botón.
Button button;
public void onClick(View v) {
Drawable dr = getResources().getDrawable(R.drawable.button_pressed);
dr.setColorFilter(Color.parseColor("#FF0000"), PorterDuff.Mode.SRC_ATOP);
switch (v.getId()) {
case R.id.btn:
if (button == null) {
button = (Button) findViewById(v.getId());
} else {
button.setBackgroundResource(R.drawable.button_pressed);
button = (Button) findViewById(v.getId());
}
button.setBackgroundDrawable(dr);
break;
case R.id.btn2:
if (button == null) {
button = (Button) findViewById(v.getId());
} else {
button.setBackgroundResource(R.drawable.button_pressed);
button = (Button) findViewById(v.getId());
}
button.setBackgroundDrawable(dr);
break;
default:
break;
}
}
creo, ahora obtendrás lo que querías hacer.
Otros consejos
Use este selector y colóquelo en la carpeta Dibujable y ajuste el fondo del botón en este selector.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/blue" android:state_pressed="true"/>
<item android:drawable="@color/AliceBlue" android:state_focused="true"/>
<item android:drawable="@color/Azure"/>
</selector>
o Puedes usar color en lugar de fondo. Espero que ayude.
Te sugiero este selector.
Simplemente cree un archivo selector.xml simple en la carpeta dibujable y luego agregue el selector a su botón como android:background="@drawable/selector"
o por código como este: yourButton.setBackground(getResources().getDrawable(R.drawable.selector));
selector.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true"
android:state_pressed="true" android:drawable="@android:color/holo_blue_light" />
<item android:state_enabled="true"
android:state_focused="true" android:drawable="@android:color/holo_green_dark" />
<item android:state_enabled="true"
android:state_selected="true" android:drawable="@android:color/holo_purple" />
<item
android:drawable="@drawable/yourdrawable" />
</selector>
El primer elemento es para pressed
, el segundo para focused
y el ultimo es para selected
estado.
changing background color in layout when respective color button is clicked in android
main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#b056ff"
android:id="@+id/l1">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/b1"
android:layout_gravity="center"
android:text="RED"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/b2"
android:layout_gravity="center"
android:text="GREEN" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/b3"
android:layout_gravity="center"
android:text="BLUE"/>
MyActivity.java
package ram.android.com.cwp1;
import android.app.Activity;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;
/**
* Created by VENKATESH on 10-Jun-16.
*/
public class MyActivity extends Activity implements View.OnClickListener {
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
Button r, g, b;
LinearLayout ll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
ll = (LinearLayout) findViewById(R.id.l1);
r = (Button) findViewById(R.id.b1);
g = (Button) findViewById(R.id.b2);
b = (Button) findViewById(R.id.b3);
r.setOnClickListener(this);
g.setOnClickListener(this);
b.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.b1:
ll.setBackgroundColor(Color.RED);
break;
case R.id.b2:
ll.setBackgroundColor(Color.GREEN);
break;
case R.id.b3:
ll.setBackgroundColor(Color.BLUE);
break;
}
}
}
I know it is very late but I hope some one would find useful. I have very simple solution, I have used in my app and works awesome.
Let me explain the logic, 1. Keep track of 2 button clicks - previous button clicked and current button clicked. I am using ArrayList 2. for every button click keep updating the previous and current button clicks value in ArrayList. 3. change the background color of previous button clicked. 4. change the background color of current button clicked.
I hope the logic is simple and straightforward.
Here is the implementation
xml
<Button
android:onClick="onClickRosterDay"
android:text="Mon"
android:textColor="@color/textColorWhite"
android:background="@color/colorAccent"
android:id="@+id/rosterMonday"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
the OnClick method is defined for every button in XML, in the example it is onClickRosterDay
Java
//buttons
Button rosterMonday;
Button rosterTuesday;
Button rosterWednesday;
Button rosterThursday;
Button rosterFriday;
Button rosterSaturday;
//ArrayList to track button clicks
private ArrayList<Button> buttonClickedDay;
in OnCreate
buttonClickedDay = new ArrayList<>();
// to start with these are the default clicks.
buttonClickedDay.add(rosterMonday ); //previous button clicked
buttonClickedDay.add(rosterMonday ); // current button clicked
public void onClickRosterDay(View v) {
switch (v.getId()){
case R.id.rosterMonday:
daySelected = "MONDAY";
// move current click button to previous button clicked position
buttonClickedDay.set(0, buttonClickedDay.get(1));
// update current clicked position
buttonClickedDay.set(1,rosterMonday);
break;
case R.id.rosterTuesday:
daySelected = "TUESDAY";
buttonClickedDay.set(0, buttonClickedDay.get(1));
buttonClickedDay.set(1,rosterTuesday);
break;
case R.id.rosterWednesday:
daySelected = "WEDNESDAY";
buttonClickedDay.set(0, buttonClickedDay.get(1));
buttonClickedDay.set(1,rosterWednesday);
break;
case R.id.rosterThursday:
daySelected = "THURSDAY";
buttonClickedDay.set(0, buttonClickedDay.get(1));
buttonClickedDay.set(1,rosterThursday);
break;
case R.id.rosterFriday:
daySelected = "FRIDAY";
buttonClickedDay.set(0, buttonClickedDay.get(1));
buttonClickedDay.set(1,rosterFriday);
break;
case R.id.rosterSaturday:
daySelected = "SATURDAY";
buttonClickedDay.set(0, buttonClickedDay.get(1));
buttonClickedDay.set(1,rosterSaturday);
break;
}
if(buttonClickedDay.get(0) != buttonClickedDay.get(1)) {
// update background color of previous button clicked
buttonClickedDay.get(0).setBackgroundColor(this.getResources().getColor(R.color.colorAccent));
// update background color of current button clicked
buttonClickedDay.get(1).setBackgroundColor(this.getResources().getColor(R.color.textBackgroundGreen));
}
}