i want to change background after clicking Button in android with kotlin - android

I want to change background after clicking Button
var bm : Button = messeg
bm . setOnClickListener {
bm . background = R.color.green
}
Error Log:
Error:(35, 31) Type mismatch: inferred type is Int but Drawable! was
expected Error:Execution failed for task ':app:compileDebugKotlin'.
Compilation error. See log for more details

background requires a Drawable, but you are passing a color resource.
You can use setBackgroundColor to set a color resource:
bm.setBackgroundColor(R.color.green)
setBackgroundResource can be used to set a drawable resource:
bm.setBackgroundResource(R.drawable.green_resource)
background property can be used to set a drawable:
bm.background = ContextCompat.getDrawable(context, R.drawable.green_resource)

The current accepted answer is wrong for setBackgroundColor(). In the given example, you set the color to the resource id, but you must pass the color directly.
This won't fail because both values are int, but you'll get weird colors.
Instead of that, you should retrieve first the color from the resource, then set it as background. Example :
val colorValue = ContextCompat.getColor(context, R.color.green)
bm.setBackgroundColor(colorValue)

Related

Get background tint of an android View for testing

I am creating Android Instrumented tests using Espresso and I would like to test that the backgroundTint of a view changes after a certain action. I did not have any luck finding a similar question specifically for background tint. In this case it is an ImageView that uses a circle drawable and the color changes from green to red depending on server connection. The view is updating via livedata databinding
<ImageView
android:id="#+id/connected_status"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_gravity="end|top"
android:background="#drawable/circle"
android:backgroundTint="#{safeUnbox(viewModel.onlineStatus) ? #colorStateList/colorGreenMaterial : #colorStateList/colorRedPrimary}"
android:contentDescription="#string/connection_indication"
/>
How can I programmatically get the backgroundTint of the ImageView during an Instrumented test and check its color?
I believe I found a solution to this problem as the test is passing, however I do not know if it is the best solution. I noticed when getting the backgroundTintList from the ImageView it contains an array of integers representing colors. I was able to use this to test the colors like so (Kotlin):
// Get the integer value of the colors to test
val redColorInt = Color.parseColor(activityTestRule.activity.getString(R.color.colorRedPrimary))
var greenColorInt = Color.parseColor(activityTestRule.activity.getString(R.color.colorGreenMaterial))
// Add integers to a stateSet array
val stateSet = intArrayOf(redColorInt, greenColorInt)
// Get the view
val connectedStatus = activityTestRule.activity.findViewById<ImageView>(id.connected_status)
// Get the backgroundTintList
var tintList = connectedStatus.backgroundTintList
// Assert color, getColorForState returns 1 as default to fail the test if the correct color is not found
assertThat(tintList!!.getColorForState(stateSet, 1), `is`(redColorInt))
//Perform actions that change the background tint
...
// Get the updated backgroundTintList
tintList = connectedStatus.backgroundTintList
// Assert new color is now set
assertThat(tintList!!.getColorForState(stateSet, 1), `is`(greenColorInt))

Material Chips - Can't find resource ID (Color/Icon)

Relevant code:
fun updateCategories(categories: List<Category>) {
categories.forEach {
var chipText = "${it.title.capitalize()} (${it.amount})"
val chip = Chip(context)
chip.text = chipText
chip.isCheckable = true
chip.chipBackgroundColor = null
when(it.title.toLowerCase()){
"utilities" -> {
chip.setChipIconTintResource(Color.parseColor("#115FFF"))
chip.setChipStrokeColorResource(Color.parseColor("#115FFF"))
chip.setChipDrawable(ChipDrawable.createFromResource(this.context, R.drawable.ic_utilities))
}
chips_group.addView(chip)
}
}
So for this code, I had 2 errors,
Expected a color resource id (R.color.) but received an RGB integer for the colors
and Expected resource of type xml for the drawables
I could fix this error by adding a #SuppressLint("ResourceType"), but this resulted in runtime errors when reaching this code about not finding the resource either the color id or the drawable
The error if i comment colors and keep drawables is
android.content.res.Resources$NotFoundException: Can't load chip resource ID #0x7f070078
the error for the colors is
android.content.res.Resources$NotFoundException: Resource ID #0xff115fff
any help is appreciated.
What im attempting to do is to add a chip with an icon i specified and color that I picked, this is the result I hope to achieve
One of the errors you're facing is Expected a color resource id (R.color.)
That is because instead of passing R.color.tint_resource to setChipIconTintResource and setChipStrokeColorResource you are passing Color.parseColor(colorString)
Move the hex codes to colors.xml and use them.
Second thing, the reason you are getting resource not found exception is that createFromResource takes an xml resource and your passing a drawable resource. So, Create a xml resource file in the res/xml folder.
After making the changes, your code will look something like below.
chip.setChipIconTintResource(R.color.chip_icon_tint)
chip.setChipStrokeColorResource(R.color.chip_stroke_color)
chip.setChipDrawable(
ChipDrawable.createFromResource(this, R.xml.chip_resource)
)
Finally, Adding #SuppressLint just suppress the warning escalating the chances of a run time crash compared to solving the issue.
Set Chip Icon:
chip.chipIcon = ContextCompat.getDrawable(this, R.drawable.ic_utilities)
Set Stroke Width:
chip.chipStrokeWidth = 6f

How to programmatically get value of built-in resources like colorAccent?

How do you get the actual value of a referenced color. In a layout I can use the following...
android:textColor="?android:attr/colorAccent"
..and this works in setting the text color of a TextView to the theme defined accent color. How do I get the value of the colorAccent using code at runtime?
Also, how do you discover a list of all the available values, there must be a long list of available colors I could get hold of, but where is that list defined?
If the resource is an Android defined one:
var id = Android.Resource.Attribute.ColorAccent;
If the resource is within a Dialog, Widget, etc.. that is not an Android system resource (i.e. to obtain a DatePickerDialog resource)
var id = SomeDatePickerDialog.Resources.GetIdentifier("date_picker_header_date", "id", "android");
Using the id obtained:
var typedArray = Theme.ObtainStyledAttributes(new int[] { id });
var color = typedArray.GetColor(0, int.MaxValue);
if (color != int.MaxValue)
{
Log.Debug("COLOR", color.ToString());
}
The R list changes with API/Theme, for the base values available:
Colors: https://developer.android.com/reference/android/R.color.html
Styles: https://developer.android.com/reference/android/R.style.html
etc...
But for a complete reference you have to use the Android source for the API the you are looking at:
https://android.googlesource.com/platform/frameworks/base/
So the colors that are defined in the Oreo beta:
https://android.googlesource.com/platform/frameworks/base/+/android-8.0.0_r4/core/res/res/color/
Then look within the specific color xml file for the how it is defined and use that definition to find the actual value of it (in one on the valueXXX files....)
For the example you have you can get that value with something like this:
//default color instead the attribute is not set.
var color = Color.Blue;
var attributes = new int[] { Android.Resource.Attribute.ColorAccent };
var typeArray = ObtainStyledAttributes(attributes);
//get the fist item (we are sending only one) and passing
//the default value we want, just in case.
var colorAccent = typeArray.GetColor(0, color);
colorAccent will have the Color set in your Theme for the ColorAccent attribute if any or the default value .
Important to mention that this method ObtainStyledAttributes is part of a Context so if you are already in an Activity you will find it as part of it but if you are in any other class you will need to pass in the context in case it's not available.
For the full list of available values you can get it from the Android.Resource.Attribute class. In VS do an inspection to see the different properties this class has. Maybe Android documentation has a better way though.
Hope this helps.-

explain the main reason to use getColor() method from ContextCompat class?

LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linear);
int color = ContextCompat.getColor(getContext(), mColorResourceId);
linearLayout.setBackgroundColor(color);
i have these line of code :
mColorResourceId it's hold R.color.category_numbers -> mColorResourceId = R.color.category_numbers
when i pass mColorResourceId directly to setBackgroundColor(mColorResourceId); it's doesn't change the color despite the method accept int value .
my question why i need this extra step int color = ContextCompat.getColor(getContext(), mColorResourceId); to change the color ??
The setBackgroundColor() method accepts an int that is supposed to be a color value in aarrggbb format. The resource ID R.color.category_numbers is also an int, but it is not a color value; instead it is the identifier of a color resource. Calling ContextCompat.getColor(getContext(), mColorResourceId) retrieves the actual color value corresponding to mColorResourceId.
Part of the reason Android does this kind of indirection is to provide flexibility. The actual color returned may depend on the current theme or the device configuration and may actually change at run time (depending on how you declare your color resource).

Get the color of the button

I want to use a code that indicates the color of the button (id=button1) and do something if the color is blue,
I mean =
if the color of button1 is blue type 1, if its green,yellow or other color, type game over.
how can i do it?
i tried this way:
if(v.getId() == R.id.button1){
ColorDrawable buttonColor = (ColorDrawable) button1.getBackground();
int colorId = buttonColor.getColor();
}
there is an error:
Multiple markers at this line
- Type mismatch: cannot convert from ColorDrawable to int
- The method getColor() is undefined for the type
and if you are hovering over the getColor() you get another error:
The method getColor() is undefined for the type ColorDrawable
what can I do?
thx.
This is the wrong way to do it. You should never use UI attributes to determine program state, doing so leads to spaghetti code. Instead, you should have some variable in your code with a name that means something easily understood that tracks the state of the button. Whenever you change the color of the button, you set this variable. Then when you need to make some decision based on the color, you use this variable.
You can also try something like set the color value as the tag like
android:tag="#ff0000"
And access it from the code
String colorCode = (String)btn.getTag();
OR
Button button = (Button) findViewById(R.id.my_button);
Drawable buttonBackground = button.getBackground();

Categories

Resources