public static int RGB(float[] hsv) {
return Color.HSVToColor(hsv);
}
this function add an int, froma color. how can i convert that int to a hexa string: #efefef
The answer of st0le is not correct with respect to colors. It does not work if first color components are 0. So toHexString is useless.
However this code will work as expected:
String strColor = String.format("#%06X", 0xFFFFFF & intColor);
Here are 2 ways to convert Integer to Hex Strings...
int n = 123456;
System.out.println(String.format("#%X", n)); //use lower case x for lowercase hex
System.out.println("#"+Integer.toHexString(n));
If you want to convert to javascript format:
val hexColor = String.format("%06X", 0xFFFFFFFF.and(R.color.text.toColorInt(context).toLong()))
val javascriptHexColor = "#" + hexColor.substring(2) + hexColor.substring(0, 2)
Use this way
Java:
String hexColor = "#" + Integer.toHexString(ContextCompat.getColor(context, R.color.colorTest))
Kotlin:
var hexColor = "#${Integer.toHexString(ContextCompat.getColor(context, R.color.colorTest))}"
Related
Background
Suppose I use SpannableStringBuilder to append multiple stuff into it, and one of them is string that I format from the strings.xml file, which has a span inside:
SpannableStringBuilder stringBuilder = new SpannableStringBuilder ();
stringBuilder.append(...)...
final SpannableString span = new SpannableString(...);
span.setSpan(new BackgroundColorSpan(0xff990000), ...,...,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.append(getString(R.string.string_to_format, span));
stringBuilder.append(...)...
textView.setText(stringBuilder);
The problem
Sadly, formatting such a string removes the span itself, so in my case, there won't be any text with a background color.
This happens on the line of the "getString".
What I've tried
If I just append the span alone (without "getString"), it works fine.
I also tried to investigate Html.fromHtml, but it doesn't seem to support a background color for text anyway.
The question
Is it possible to format a string that has a span, yet still have the span within?
More specifically, the input is a string A from the strings.xml file, which only has a placeholder (no special HTML tags), and another string B that is supposed to replace the placeholder at runtime. The string B should have a highlight for a partial text of itself.
In my case, the highlighted text is a something to search for within string B.
OK, I've found an answer to my special end case, but I'd still like to know if there are better ways.
Here's what I did:
String stringToSearchAt=...
String query=...
int queryIdx = stringToSearchAt.toLowerCase().indexOf(query);
stringToSearchAt= stringToSearchAt.substring(0, queryIdx + query.length()) + "<bc/>" + stringToSearchAt.substring(queryIdx + query.length());
final String formattedStr=getString(..., stringToSearchAt);
stringBuilder.append(Html.fromHtml(formattedStr, null, new TagHandler() {
int start;
#Override
public void handleTag(final boolean opening, final String tag, Editable output, final XMLReader xmlReader) {
switch (tag) {
case "bc":
if (!opening)
start = output.length() - query.length();
break;
case "html":
if (!opening)
output.setSpan(new BackgroundColorSpan(0xff00bbaa), start, start + query.length(), 0);
}
}
}));
This is only good for my case, but in the case of general formatting, this won't suffice.
format a spanned string may be impossible, because it still use String.format() to format a String finilly, it's a Java API, and Span is Android API.
But I think you can use html string instead. Look at this document Styling with HTML markup.
for example:
String str = "Hi <strong><font color=\"#00bbaa\">%s</font></strong>, Welcome to <em><font color=\"#FF4081\">%s</font></em>";
String text = String.format(str, "Lucy", "Android");
Spanned spanned = Html.fromHtml(text);
// after Html.fromHtml(), you can still change the Span
SpannableString spannableString = new SpannableString(spanned);
spannableString.setSpan(new BackgroundColorSpan(0xff990000), 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
the result
if you want to put the string in the string.xml, you may need to change '<' to '<', '%s' to '%1$s'.
<string name="from_offical">Hello <strong><font color="#00bbaa">%1$s</font></strong>, Welcome to <em><font color="#00bbaa">%2$s</font></em></string>
This is an old question, but I am posting a more general solution than the accepted answer.
Reference is made to the following string resources:
<string name="string_1"><b>Bolded</b> <abc>Not bolded</abc></string>
<string name="string_2"><font bgcolor="red">Background red</font> No background color.</string>
<string name="string_3">The <b>capital</b> of %1 is %2\n%2 is the capital of %1.</string>
Android stores string resource tags separately from strings. Tags will always be consumed when read into an app.
var s1 = getString(R.string.string_1)
var s2 = getText(R.string.string_1)
s1 placed in a TextView will show "Bolded Not bolded" while s2 in a TextView will show "Bolded Not bolded". The tag "<abc>" has no interpretation, so it is lost.
If the background color is known at compile time then we can do the following:
textView.text = getText(R.string.string_2)
will display:
Of some interest is that while the font tag is supported by the Android framework and the HTML translation class (Html .java), the Html.java implementation does not support the bgcolor attribute, so the following
var s4 = "<font bgcolor=\"red\">Background red</font> No background color."
textView.text = HtmlCompat.fromHtml(s4, FROM_HTML_MODE_LEGACY)
will not display the background color.
If the formatting is indeterminate at compile time, then we must do a little more work. Replacing string arguments with spanned text using getString(string_id, varargs) fails as the OP notes. What is an alternative?
One way is to read a string in with placeholders intact.
getString(R.string.string_3) will produce the string "The capital of %1 is %2\n%2 is the capital of %1.". We could then search for "%1", "%2", etc. and make the replacements with spanned text. In this case, the placeholder identifiers could be any unique set of characters.
It may be better, however, to use getText(R.string.string_3) which will interpret any HTML codes supported by the framework.
The following code shows hot to make substitutions of spanned text into string_3. The spanned text that will be substituted simply has the first letter highlighted.
textView.text = SpanFormatter.getText(this, R.string.string_3, { Int -> getArg(Int) })
private fun getArg(argNum: Int) =
when (argNum) {
1 -> { // Get the country with a highlighted first character.
SpannableString("France").apply {
setSpan(
BackgroundColorSpan(0x55FF0000),
0,
1,
SpannedString.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
}
2 -> { // Get the capital city with a highlighted first character.
SpannableString("Paris").apply {
setSpan(
BackgroundColorSpan(0x550000FF),
0,
1,
SpannedString.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
}
else -> throw IllegalArgumentException("$argNum is a bad argument number.")
}
SpanFormatter.kt
object SpanFormatter {
private const val END_OF_STRING = -1
private const val SPAN_FLAGS = SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
fun getText(
context: Context,
#StringRes stringId: Int,
argFactory: (Int) -> CharSequence,
argStartChar: Char = '%'
) = getText(context.getText(stringId), argFactory, argStartChar)
fun getText(
cs: CharSequence,
argFactory: (Int) -> CharSequence,
argStartChar: Char = '%'
): CharSequence {
// Mark all areas of substitution with an ArgNum span.
val sb = SpannableStringBuilder(cs)
var pos = sb.indexOf(argStartChar, 0)
while (pos != END_OF_STRING) {
var argEnd = pos + 1
while (argEnd < sb.length && sb[argEnd].isDigit()) ++argEnd
if (argEnd - pos > 1) {
val argnum = sb.substring(pos + 1, argEnd).toInt()
check(argnum > 0) {
"Incorrect argument number (%d) which must greater than zero.\nString: %s".format(
argnum
)
}
sb.setSpan(ArgMark(argnum), pos, argEnd, SPAN_FLAGS)
}
pos = sb.indexOf(argStartChar, argEnd)
}
// Replace all ArgMark spans with the appropriate substitution text.
val argMarkSpans = sb.getSpans<ArgMark>(0, sb.length)
argMarkSpans.forEach { argMarkSpan ->
val start = sb.getSpanStart(argMarkSpan)
val end = sb.getSpanEnd(argMarkSpan)
sb.replace(start, end, argFactory(argMarkSpan.argNum))
sb.removeSpan(argMarkSpan)
}
return sb
}
private data class ArgMark(val argNum: Int)
}
The foregoing displays:
And a simpler way without the use of the marking spans which aren't really needed:
SpanFormatter.kt
object SpanFormatter {
private const val END_OF_STRING = -1
fun getText(
context: Context,
#StringRes stringId: Int,
argFactory: (Int) -> CharSequence,
argStartChar: Char = '%'
) = getText(context.getText(stringId), argFactory, argStartChar)
fun getText(
cs: CharSequence,
argFactory: (Int) -> CharSequence,
argStartChar: Char = '%'
): CharSequence {
val sb = SpannableStringBuilder(cs)
var argStart = sb.indexOf(argStartChar, 0)
while (argStart != END_OF_STRING) {
var argEnd = argStart + 1
while (argEnd < sb.length && sb[argEnd].isDigit()) ++argEnd
if (argEnd - argStart > 1) {
val argNum = sb.substring(argStart + 1, argEnd).toInt()
argFactory(argNum).apply {
sb.replace(argStart, argEnd, this)
argEnd = argStart + length
}
}
argStart = sb.indexOf(argStartChar, argEnd)
}
return sb
}
}
I has a Hex String like "0xff"
I want to convert the String to int
but remain the part of "0x"
such as
String hex = "0x32";
int convert = Integer.parseInt(hex, 16);
the result of convert = 50
but what i want is directly convert the hex to int like:
convert = 0x32
How should i do?
Edit:
I have an variable hex like
String Hex = "0x32"
Now I want to parse it to int value but i want the int result is
int convert = 0x32
My question is which method can help me convert the hex String directly to int like
String hex = "0x32"
int convert = hex do some thing but result will be convert = 0x32
You seem to confuse the value of an integer with its representation as a string. For example the integer value twelve can be represented in various ways, decimal 12, octal 14, hex c, binary 1100, roman XII, are just a few of the possible representations.
An int in Java just stores the value. Representations come into play when you convert the value to a string or vice versa.
I've got a String filled with hex values like this:
received_Value = fffec780
The string isn't declared as a hex string, it is declared as a normal string and filled with this characters. But I must define it as a Hex string to make the conversion to int.
int_value_receive = Integer.parseInt(received_Value, 16)
Because when doing this i'm getting an error.
fffec780's value as an int is greater than MAX_INTEGER.
Try this
Long.parseLong(received_Value, 16);
I have to convert an int to an hex value. This is for example the int value:
int_value = -13516;
To convert to a hex value i do:
hex_value = Integer.toHexString(int_value);
The value that I should get is : -34CC (I don't know if i should make it positive).
The thing is that doing the conversion that way, the value that I get is: ffff cb34
Can't I use this function to make this conversion?
Documentation says Integer.toHexString returns the hexadecimal representation of the int as an unsigned value.
I believe Integer.toString(value, 16) will accomplish what you want.
public static int convert(int n) {
return Integer.valueOf(String.valueOf(n), 16);
}
// in onstart:
Log.v("TAG", convert(20) + ""); // 32
Log.v("TAG", convert(54) + ""); // 84
From: Java Convert integer to hex integer
Both Integer.toHexString, as well as String.format("%x") do not support signs. To solve the problem, you can use a ternary expression:
int int_value = -13516;
String hex_value = int_value < 0
? "-" + Integer.toHexString(-int_value)
: Integer.toHexString(int_value);
String.format("#%06X", (0xFFFFFF & colorYellow));
Output: #FFC107
Go through following code for Integer to hex and Hex to integer Conversion
public class MainActivity extends Activity {
int number;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
number = 678668;
Log.i("ACT", "Integer Number " + number);
/**
* Code for convert integer number to hex number. two mwthods.
*/
Log.i("ACT", String.format("#%x", number)); // use lower case x for
// lowercase hex
Log.i("ACT", "#" + Integer.toHexString(number));
/**
* Code for convert hex number to integer number
*/
String hex = Integer.toHexString(number).replace("/^#/", "");
int intValue = Integer.parseInt(hex, 16);
Log.i("ACT", "Integer Number " + intValue);
}
}
I don't think the above answers would give you the exact value for the signed bits. For example the value of 11 is 0B but the value of -11 would be F5 and not -B since 2's complement gets into the game to solve this i have modified the above answer
int int_value = -11;
String hex_value = int_value < 0
? Integer.toHexString(int_value+65536) : Integer.toHexString(int_value);
String shortHexString = hex_value.substring(2);
where, 65536 is 2^16 now you can get the expected results . Happy coding :)
List item
If i defined a color in resources
<resources>
<color name="someColor">#123456</color>
</resources>
it's possible to set color by its id, like
view.setTextColor(R.color.someColor);
Is it also possible to get color string value from colors.xml?
Something like
colorStr = getColor(R.color.someColor);
// -> colorStr = "#123456"
If yes, can anybody give an example?
Thank you
This is your answer
colorStr=getResources().getString(R.color.someColor);
you will get
colorStr = "#123456"
Just for the sake of easy copypasta:
"#" + Integer.toHexString(ContextCompat.getColor(getActivity(), R.color.some_color));
Or if you want it without the transparency:
"#" + Integer.toHexString(ContextCompat.getColor(getActivity(), R.color.some_color) & 0x00ffffff);
All of the solutions here using Integer.toHexString() break if you would have leading zeroes in your hex string. Colors like #0affff would result in #affff. Use this instead:
String.format("#%06x", ContextCompat.getColor(this, R.color.your_color) & 0xffffff)
or with alpha:
String.format("#%08x", ContextCompat.getColor(this, R.color.your_color) & 0xffffffff)
The answers provided above are not updated.
Please try this one
String colorHex = "#" + Integer.toHexString(ContextCompat.getColor(getActivity(), R.color.dark_sky_blue) & 0x00ffffff);
Cause getResources().getColor need api > 23. So this is better:
Just for the sake of easy copy & paste:
Integer.toHexString( ContextCompat.getColor( getContext(), R.color.someColor ) );
Or if you want it without the transparency:`
Integer.toHexString( ContextCompat.getColor( getContext(), R.color.someColor ) & 0x00ffffff );
For API above 21 you can use
getString(R.color.color_name);
This will return the color in a string format.
To convert that to a color in integer format (sometimes only integers are accepted) then:
Color.parseColor(getString(R.color.color_name));
The above expression returns the integer equivalent of the color defined in color.xml file
It works for me!
String.format("#%06x", ContextCompat.getColor(this, R.color.my_color) & 0xffffff)
Add #SuppressLint("ResourceType") if an error occurs. Like bellow.
private String formatUsernameAction(UserInfo userInfo, String action) {
String username = userInfo.getUsername();
#SuppressLint("ResourceType") String usernameColor = getContext().getResources().getString(R.color.background_button);
return "<font color=\""+usernameColor+"\">" + username
+ "</font> <font color=\"#787f83\">" + action.toLowerCase() + "</font>";
}
I don't think there is standard functionality for that. You can however turn the return in value from getColor() to hex and turn the hex value to string.
hex 123456 = int 1193046;
This is how I've done it:
String color = "#" + Integer.toHexString(ContextCompat.getColor
(getApplicationContext(), R.color.yourColor) & 0x00ffffff);