Edit
As explained in the comments, the previously proposed form does not answer.
Soon I'm proposing another, using custom states, I believe that a cleaner and more correct way.
The steps are as follows:
First we need to create a Custom View
that extends whatever one uses to represent its square in the crossword. In my case, it is a subclass of TextView
.
public class PalavraCruzadaTextView extends TextView {
private static final int[] ERRADO_STATE_SET = {R.attr.state_errado};
private static final int[] CORRETO_STATE_SET = {R.attr.state_correto};
private static final int[] PALAVRA_STATE_SET = {R.attr.state_palavra};
boolean correto, errado, palavra;
public RobotoTextView(Context context) {
super(context);
}
public RobotoTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RobotoTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected int[] onCreateDrawableState(int extraSpace) {
// Chama o metodo da superclasse para tratar os estados comuns
// Passando o espaco + 3, por causa dos nossos estados customizados
final int[] drawableState = super.onCreateDrawableState(extraSpace + 3);
if (isCorreto()) {
mergeDrawableStates(drawableState, CORRETO_STATE_SET);
}
if (isErrado()) {
mergeDrawableStates(drawableState, ERRADO_STATE_SET);
}
if (isPalavra()) {
mergeDrawableStates(drawableState, PALAVRA_STATE_SET);
}
return drawableState;
}
public boolean isCorreto() {
return correto;
}
public boolean isErrado() {
return errado;
}
public boolean isPalavra() {
return palavra;
}
public void setCorreto(boolean correto) {
this.correto = correto;
// Atualiza o estado do drawable
refreshDrawableState();
}
public void setErrado(boolean errado) {
this.errado = errado;
// Atualiza o estado do drawable
refreshDrawableState();
}
public void setPalavra(boolean palavra) {
this.palavra = palavra;
// Atualiza o estado do drawable
refreshDrawableState();
}
}
With this you have to define the states that PalavraCruzadaTextView
can have, in terms of xml. Put in your file /res/values/attrs.xml
(or create) the following statement:
<declare-styleable name="PalavraCruzadaTextView">
<attr name="state_errado" format="boolean" />
<attr name="state_correto" format="boolean" />
<attr name="state_palavra" format="boolean" />
</declare-styleable>
This defines the 3 possible custom states that PalavraCruzadaTextView
can have.
To set a background for PalavraCruzadaTextView
, taking into account the states, just do:
<nome.do.pacote.PalavraCruzadaTextView
android:id="@+id/palavra_cruzada_text_view"
android:width="wrap_content"
android:height="wrap_content"
android:background="@drawable/background_palavra_cruzada" />
The background_word_ definition.xml definition:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item app:state_correto="true">
<!-- Define o Drawable para o estado correto -->
<shape android:shape="rectangle">
<solid android:color="@color/green" />
</shape>
</item>
<item app:state_errado="true">
<!-- Define o Drawable para o estado errado -->
<shape android:shape="rectangle">
<solid android:color="@color/red" />
</shape>
</item>
<!-- Como temos outro estado combinando esses dois,
eh preciso forçar o false para nao sobrepor -->
<item app:state_palavra="true" android:state_pressed="false">
<!-- Define o Drawable para o estado palavra -->
<shape android:shape="rectangle">
<solid android:color="@color/orange" />
</shape>
</item>
<!-- Pode-se combinar com outros estados -->
<item app:state_palavra="true" android:state_pressed="true">
<!-- Define o Drawable para o estado palavra -->
<shape android:shape="rectangle">
<solid android:color="@color/orange" />
</shape>
</item>
</selector>
And to change the states:
PalavraCruzadaTextView pl = (PalavraCruzadaTextView) findViewById(R.id.palavra_cruzada_text_view);
pl.setCorreto(...);
pl.setErrado(...);
pl.setPalavra(...);
// E para saber o estado atual:
pl.isCorreto();
pl.isErrado();
pl.isPalavra();
References:
Custom drawing states possible?
Another solution could be:
When using the @color/back_corDoFundo
attribute you have created a reference. From the moment your Layout has been inflated, the reference is "resolved" and becomes a 4-byte color value that has no identifier.
The background of a View
is Drawable
, depending on the subclass there is a different way of getting the color.
Using background="@color/...
LayoutInflater
creates a ColorDrawable
that represents this color, each type of Drawable
for this attribute will generate a different subclass. And in this subclass it is possible to obtain the color easily.
What you can do is:
// Pego o background da View
Drawable background = suaView.getBackground();
// Pego a cor na representação em 4 bytes relativa a sua cor no resource
int corDoFundo = getResources().getColor(R.color.back_corDoFundo);
// Como voce usou o @color/back_corDoFundo, a subclasse eh ColorDrawable
ColorDrawable = cBackground = (ColorDrawable) background;
// Comparo as duas cores
if(corDoFundo == cBackground.getColor()) {
// A cor do fundo da View e back_corDoFundo
}
Watch out !! Any change in this attribute can generate a different subclass. And there the approach must be different!
If you use Drawable State List
, xml being for example:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@color/red" />
<item android:drawable="@color/blue" />
</selector>
In this case, the LayoutInflater
will create a Drawable
whose subclass is StateListDrawable
, where it has two states. Where each state is ColorDrawable
.
And so on ...