Two different styles in a single textview with different gravity and height - android

I am looking for a textview which looks like . I have used below code for the implementation of this..
SpannableString text;
text = new SpannableString(bal_dollars.getText());
int index = bal_dollars.getText().toString().indexOf(".");
text.setSpan(new TextAppearanceSpan(getApplicationContext(),
R.style.HeroGraphicBalanceSmallFont), index, bal_dollars
.getText().toString().length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
bal_dollars.setText(text, TextView.BufferType.SPANNABLE);
here is the style used in the span..
<style name="HeroGraphicBalanceSmallFont" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">wrap_content</item>
<item name="android:textSize">50sp</item>
<item name="android:singleLine">true</item>
<item name="android:layout_height">match_parent</item>
<item name="android:layout_gravity">top|right</item>
<item name="android:paddingBottom">30dp</item>
<item name="android:gravity">top|right</item>
<item name="android:textColor">#color/status_text</item>
<item name="customFont">fonts/HeroicCondensedMedium.ttf</item>
</style>
everything looks fine except the spacing of targeted span of text i.e decimal part gravity.. . I tried all the xml attributes. Please help

I cracked it. I am posting this as it might be helpful for others and thanks to #kcoppock for the hint.
I have extended MetricAffectingSpan class which affects character-level text formatting in a way that changes the width or height of characters extend this class.
public class CustomCharacterSpan extends MetricAffectingSpan {
double ratio = 0.5;
public CustomCharacterSpan() {
}
public CustomCharacterSpan(double ratio) {
this.ratio = ratio;
}
#Override
public void updateDrawState(TextPaint paint) {
paint.baselineShift += (int) (paint.ascent() * ratio);
}
#Override
public void updateMeasureState(TextPaint paint) {
paint.baselineShift += (int) (paint.ascent() * ratio);
}}
use this to update the text in your views..
String string = tv.getText().toString();
SpannableString text = new SpannableString(tv.getText());
int index = tv.getText().toString().indexOf(".");
text.setSpan(new CustomCharacterSpan(), index, string.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);//u can use ur own ratio using another constructor
tv.setText(text, TextView.BufferType.SPANNABLE);

Related

Generate and set random colors on text view background within Recycler View in Android

I am Trying to Generate Random Colors and set the Random color as background of Text View Just Like in GMail app. The Text view is Having a circular background initially set in xml which i have done using shape. I have done some research and used some code available on internet but the changes are not reflecting in my app.
Below is my Recycler View Adapter Class:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.Items> {
ArrayList<GmailDataHolder> data;
Context context;
public RecyclerViewAdapter(ArrayList<GmailDataHolder> data, Context context) {
this.data = data;
this.context = context;
}
#Override
public RecyclerViewAdapter.Items onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.gmail_layout_row, parent, false);
Items i = new Items(v);
return i;
}
#Override
public void onBindViewHolder(final RecyclerViewAdapter.Items holder, int position) {
//Generating Random Color
int randomAndroidColor = holder.androidColors[new Random().nextInt(holder.androidColors.length)];
Drawable background = holder.circleTv.getBackground();
if (background instanceof ShapeDrawable) {
((ShapeDrawable)background).getPaint().setColor(randomAndroidColor);
} else if (background instanceof GradientDrawable) {
((GradientDrawable)background).setColor(randomAndroidColor);
} else if (background instanceof ColorDrawable) {
((ColorDrawable)background).setColor(randomAndroidColor);
}
holder.line1.setText(data.get(position).getLine1());
holder.line2.setText(data.get(position).getLine2() + "...");
holder.line3.setText(data.get(position).getLine3() + "...");
holder.time.setText(data.get(position).getTime());
//get Star Image State from MySql DB
MyFunctions.getStarState(data, holder, position);
holder.circleTv.setText(String.valueOf(data.get(position).getLine1().charAt(0)).toUpperCase());
//Changing Star Image on Click
MyFunctions.starClickListener(holder);
}
#Override
public int getItemCount() {
return data.size();
}
public class Items extends RecyclerView.ViewHolder {
TextView circleTv, line1, line2, line3, time;
int[] androidColors;
public ImageView star;
public Items(View itemView) {
super(itemView);
//Loading Color from resources
androidColors = itemView.getResources().getIntArray(R.array.androidcolors);
circleTv = (TextView) itemView.findViewById(R.id.tv_circle);
line1 = (TextView) itemView.findViewById(R.id.tv_line1);
line2 = (TextView) itemView.findViewById(R.id.tv_line2);
line3 = (TextView) itemView.findViewById(R.id.tv_line3);
time = (TextView) itemView.findViewById(R.id.tv_time);
star = (ImageView) itemView.findViewById(R.id.img_star);
}
}
Colors.xml File:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#dc4538</color>
<color name="colorFacebook">#374dae</color>
<color name="colorCenterFb">#d5617ae6</color>
<color name="colorStartGoogle">#d8dd4c3a</color>
<color name="colorEndGoogle">#dd4c3a</color>
<color name="colorEndLinkedIn">#1887b0</color>
<color name="colorStartLinkedIn">#e31887b0</color>
<color name="colorStrokeLinkedIn">#ec106584</color>
<color name="colorStrokeGoogle">#b73e2e</color>
<color name="colorStrokeFacebook">#e2263a91</color>
<color name="status">#ba3223</color>
<item name="blue" type="color">#FF33B5E5</item>
<item name="purple" type="color">#FFAA66CC</item>
<item name="green" type="color">#FF99CC00</item>
<item name="orange" type="color">#FFFFBB33</item>
<item name="red" type="color">#FFFF4444</item>
<item name="darkblue" type="color">#FF0099CC</item>
<item name="darkpurple" type="color">#FF9933CC</item>
<item name="darkgreen" type="color">#FF669900</item>
<item name="darkorange" type="color">#FFFF8800</item>
<item name="darkred" type="color">#FFCC0000</item>
<integer-array name="androidcolors">
<item>#color/blue</item>
<item>#color/purple</item>
<item>#color/green</item>
<item>#color/orange</item>
<item>#color/red</item>
<item>#color/darkblue</item>
<item>#color/darkpurple</item>
<item>#color/darkgreen</item>
<item>#color/darkorange</item>
<item>#color/darkred</item>
</integer-array>
</resources>
Initially The TextView is having the following Background declared in xml:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="#48b3ff"/>
</shape>
Random r = new Random();
int red=r.nextInt(255 - 0 + 1)+0;
int green=r.nextInt(255 - 0 + 1)+0;
int blue=r.nextInt(255 - 0 + 1)+0;
GradientDrawable draw = new GradientDrawable();
draw.setShape(GradientDrawable.OVAL);
draw.setColor(Color.rgb(red,green,blue));
mTextView.setBackground(draw);
// google's material design colours from , 254 colors
// http://www.google.com/design/spec/style/color.html#color-ui-color-palette
public String[] mColors = {
"FFEBEE", "FFCDD2", "EF9A9A", "E57373", "EF5350", "F44336", "E53935", //reds
"D32F2F", "C62828", "B71C1C", "FF8A80", "FF5252", "FF1744", "D50000",
"FCE4EC", "F8BBD0", "F48FB1", "F06292", "EC407A", "E91E63", "D81B60", //pinks
"C2185B", "AD1457", "880E4F", "FF80AB", "FF4081", "F50057", "C51162",
"F3E5F5", "E1BEE7", "CE93D8", "BA68C8", "AB47BC", "9C27B0", "8E24AA", //purples
"7B1FA2", "6A1B9A", "4A148C", "EA80FC", "E040FB", "D500F9", "AA00FF",
"EDE7F6", "D1C4E9", "B39DDB", "9575CD", "7E57C2", "673AB7", "5E35B1", //deep purples
"512DA8", "4527A0", "311B92", "B388FF", "7C4DFF", "651FFF", "6200EA",
"E8EAF6", "C5CAE9", "9FA8DA", "7986CB", "5C6BC0", "3F51B5", "3949AB", //indigo
"303F9F", "283593", "1A237E", "8C9EFF", "536DFE", "3D5AFE", "304FFE",
"E3F2FD", "BBDEFB", "90CAF9", "64B5F6", "42A5F5", "2196F3", "1E88E5", //blue
"1976D2", "1565C0", "0D47A1", "82B1FF", "448AFF", "2979FF", "2962FF",
"E1F5FE", "B3E5FC", "81D4fA", "4fC3F7", "29B6FC", "03A9F4", "039BE5", //light blue
"0288D1", "0277BD", "01579B", "80D8FF", "40C4FF", "00B0FF", "0091EA",
"E0F7FA", "B2EBF2", "80DEEA", "4DD0E1", "26C6DA", "00BCD4", "00ACC1", //cyan
"0097A7", "00838F", "006064", "84FFFF", "18FFFF", "00E5FF", "00B8D4",
"E0F2F1", "B2DFDB", "80CBC4", "4DB6AC", "26A69A", "009688", "00897B", //teal
"00796B", "00695C", "004D40", "A7FFEB", "64FFDA", "1DE9B6", "00BFA5",
"E8F5E9", "C8E6C9", "A5D6A7", "81C784", "66BB6A", "4CAF50", "43A047", //green
"388E3C", "2E7D32", "1B5E20", "B9F6CA", "69F0AE", "00E676", "00C853",
"F1F8E9", "DCEDC8", "C5E1A5", "AED581", "9CCC65", "8BC34A", "7CB342", //light green
"689F38", "558B2F", "33691E", "CCFF90", "B2FF59", "76FF03", "64DD17",
"F9FBE7", "F0F4C3", "E6EE9C", "DCE775", "D4E157", "CDDC39", "C0CA33", //lime
"A4B42B", "9E9D24", "827717", "F4FF81", "EEFF41", "C6FF00", "AEEA00",
"FFFDE7", "FFF9C4", "FFF590", "FFF176", "FFEE58", "FFEB3B", "FDD835", //yellow
"FBC02D", "F9A825", "F57F17", "FFFF82", "FFFF00", "FFEA00", "FFD600",
"FFF8E1", "FFECB3", "FFE082", "FFD54F", "FFCA28", "FFC107", "FFB300", //amber
"FFA000", "FF8F00", "FF6F00", "FFE57F", "FFD740", "FFC400", "FFAB00",
"FFF3E0", "FFE0B2", "FFCC80", "FFB74D", "FFA726", "FF9800", "FB8C00", //orange
"F57C00", "EF6C00", "E65100", "FFD180", "FFAB40", "FF9100", "FF6D00",
"FBE9A7", "FFCCBC", "FFAB91", "FF8A65", "FF7043", "FF5722", "F4511E", //deep orange
"E64A19", "D84315", "BF360C", "FF9E80", "FF6E40", "FF3D00", "DD2600",
"EFEBE9", "D7CCC8", "BCAAA4", "A1887F", "8D6E63", "795548", "6D4C41", //brown
"5D4037", "4E342E", "3E2723",
"FAFAFA", "F5F5F5", "EEEEEE", "E0E0E0", "BDBDBD", "9E9E9E", "757575", //grey
"616161", "424242", "212121",
"ECEFF1", "CFD8DC", "B0BBC5", "90A4AE", "78909C", "607D8B", "546E7A", //blue grey
"455A64", "37474F", "263238"
};
These are the material design colors.take a random color from it.
// generate a random number
int i = new Random().nextInt(254);
it will generate a random number from 0 to 254
GradientDrawable shape = new GradientDrawable();
shape.setShape(GradientDrawable.OVAL);
shape.setColor(Color.parseColor ("#"+mColors[new Random().nextInt(254)]));
mTextView..setBackground(shape);
it will choose a random color from the list and set as textview background color
This is what you want
on BindViewHolder Method
Random r = new Random();
int red=r.nextInt(255 - 0 + 1)+0;
int green=r.nextInt(255 - 0 + 1)+0;
int blue=r.nextInt(255 - 0 + 1)+0;
GradientDrawable draw = new GradientDrawable();
draw.setShape(GradientDrawable.RECTANGLE);
draw.setColor(Color.rgb(red,green,blue));
holder.viewInside.setBackground(draw);
ps- view inside is the name of the view.
If you want the exact type of Gmail view then you can use this tiny library which will give you the exact thing you want.
https://github.com/amulyakhare/TextDrawable
If you needs to use your own/required colors, just use below code
List<String> colors;
colors=new ArrayList<String>();
colors.add("#5E97F6");
colors.add("#9CCC65");
colors.add("#FF8A65");
colors.add("#9E9E9E");
colors.add("#9FA8DA");
colors.add("#90A4AE");
colors.add("#AED581");
colors.add("#F6BF26");
colors.add("#FFA726");
colors.add("#4DD0E1");
colors.add("#BA68C8");
colors.add("#A1887F");
// all colors used by gmail application :) may be,
// genrating random num from 0 to 11 because you can add more or less
Random r = new Random();
int i1 = r.nextInt(11- 0) + 0;
//genrating shape with colors
GradientDrawable draw = new GradientDrawable();
draw.setShape(GradientDrawable.OVAL);
draw.setColor(Color.parseColor(colors.get(i1)))
// assigning to textview
contact_name_circle.setBackground(draw); //textview
If you want to generate random (any) color you can just do
Color.rgb(Math.random()*255, Math.random()*255, Math.random()*255)
If you want to pick color from your list i would sugest leaving that xml file and making the list in java of all the colors you want and then just simply using randomly picked color from that array.
In your onBindViewHolder you can do the following:
int remainder = getAdapterPosition() % colorsArray.size();
mView.setCardBackgroundColor(Color.parseColor(colorsArray.get(remainder)));
In this way, each RecyclerView item will show the same color on scrolling and also each time when user will see this list.

android - Different colors in one textview

I would like to know how can I define different colors in a single textview depending on the textview repeats, for example:
If I declare something like: Color[] colors = {Color.green, Color.blue, Color.red, Color.brown, Color.yellow};
Then I want to pass "colors" somehow in tv.setBackgroundColor(Color.GREEN); instead of "Color.green" in order that if the textview repeats five times I could see the textview in green, blue, red, brown and yellow and if it's 7 times I could get green, blue, red, brown, yellow, green and blue.
Here's some code, plus an image
adapter = new SimpleCursorAdapter(this, R.layout.hrprocess_item_list, cursor, from, to, 0);
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if (view.getId() == R.id.category) {
String s=cursor.getString(cursor.getColumnIndex(manager.CONTENT_CATEGORY));
TextView tv = (TextView)view;
int[] androidColors = getResources().getIntArray(R.array.androidcolors);
for (int i = 0; i < androidColors.length; i++) {
tv.setBackgroundColor(androidColors[i]);
}
tv.setText(s);
return true;
}
return false;
}
});
lv.setAdapter(adapter);
Colors.xml
<item name="azul1" type="color">#4178BE</item>
<item name="verde1" type="color">#008571</item>
<item name="morado1" type="color">#9855D4</item>
<item name="rojo1" type="color">#E71D32</item>
<item name="rojo_naranja1" type="color">#D74108</item>
<item name="amarillo1" type="color">#EFC100</item>
<item name="gris1" type="color">#6D7777</item>
<integer-array name="androidcolors">
<item>#color/azul1</item>
<item>#color/verde1</item>
<item>#color/morado1</item>
<item>#color/rojo1</item>
<item>#color/rojo_naranja1</item>
<item>#color/amarillo1</item>
<item>#color/gris1</item>
</integer-array>
(http://i.stack.imgur.com/dCQep.jpg)
Rather than using setBackgroundColor(), you will need to apply BackgroundColorSpan objects to the ranges that you are interested in.
This sample project applies BackgroundColorSpan to highlight search results in a TextView:
private void searchFor(String text) {
TextView prose=(TextView)findViewById(R.id.prose);
Spannable raw=new SpannableString(prose.getText());
BackgroundColorSpan[] spans=raw.getSpans(0,
raw.length(),
BackgroundColorSpan.class);
for (BackgroundColorSpan span : spans) {
raw.removeSpan(span);
}
int index=TextUtils.indexOf(raw, text);
while (index >= 0) {
raw.setSpan(new BackgroundColorSpan(0xFF8B008B), index, index
+ text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
index=TextUtils.indexOf(raw, text, index + text.length());
}
prose.setText(raw);
}
In your case, you would rotate through your colors, rather than using the hardcoded hex value of a color that I'm using.

Android actionbarsherlock get height return 0

I was looking for get the height of my actionbar(sherlock). The value returned is 0.
value/styles.xml (and for value11 I used "android:actionBarSize")
<style name="AppTheme" parent="Theme.Sherlock.Light.DarkActionBar">
<item name="actionBarStyle">#style/Widget.AppTheme.ActionBar</item>
<item name="actionBarSize">48dip</item>
</style>
code :
getSupportActionBar().getHeight()
This didn't work?
// Calculate ActionBar height
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
{
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}
ref: How to get the ActionBar height?

Changing text color in action bar? [duplicate]

This question already has answers here:
ActionBar text color
(28 answers)
Closed 9 years ago.
I can't seem to figure out how to change the color of the actionbar to white instead of the default black.
<resources>
<style name="ActionBarOrange" parent="#android:style/Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarStyle">#style/MyActionBar</item>
<item name="android:titleTextStyle">#style/MyTheme.ActionBar.TitleTextStyle</item>
</style>
<style name="MyActionBar" parent="#android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">#color/orange</item>
</style>
</resources>
Any help?
In this article you will find how to customize ActionBar and more things
http://developer.android.com/guide/topics/ui/actionbar.html#AdvancedStyles
Just use HTML:
String htmlColor;
Color orange = getResources().getColor(R.color.orange);
int alpha = Color.alpha(orange);
if (alpha == 0)
htmlColor = String.format(Locale.US, "#%06X", (0xFFFFFF & orange));
else {
int red = Color.red(orange);
int green = Color.green(orange);
int blue = Color.blue(orange);
if (Build.VERSION >= 18) //KITKAT first provided CSS3 support
htmlColor = String.format(Locale.US, "rgba(%d,%d,%d,%d)", red, green, blue, alpha);
else
htmlColor = String.format(Locale.US, "#%06X", (0xFFFFFF & Color.argb(0, red, green, blue)));
}
getActionBar()/* or getSupportActionBar() */.setTitle(Html.fromHtml("<font color=\"" + hexColor + "\">" + getString(R.string.app_name) + "</font>"));

Aligning ImageSpan to the top of the TextView

Currently, I wish to add an image in between texts and align it to the top of the TextView.
Something like this:
The only vertical alignments I can find are baseline (which seems to put it right down the center of the text) and align bottom.
What happens if I use ALIGN_BASELINE is:
Is there a way to align it to the top instead?
My current code:
txtView.setText(this.addImageAsterisk(
"The string to have asterisk at the end*"), BufferType.SPANNABLE);
then
private CharSequence addImageAsterisk(String string) {
Drawable d = context.getResources().getDrawable(R.drawable.img_asterisk);
ImageSpan imageSpan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
final SpannableString spannableString = new SpannableString(string);
spannableString.setSpan(imageSpan, string.length()-1, string.length(), 0);
return spannableString;
}
removing ImageSpan.ALIGN_BASELINE sets it to align to the bottom which is also not my expected result.
--- Thank you user Lalit Poptani, I tried applying your answer----
after applying this, what happens is that the whole textview seems to have extra margin top.
before applying span:
This is the text*
after applying the SuperscriptSpanAdjuster
(some extra space)
This is the text*
My code:
String string = "This is the text*";
Drawable d = this.context.getResources().getDrawable(R.drawable.img_asterisk);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan imageSpan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
SuperscriptSpanAdjuster s = new SuperscriptSpanAdjuster(1.5);
final SpannableString spannableString = new SpannableString(string);
spannableString.setSpan(s, string.length() - 1, string.length(), 0);
spannableString.setSpan(imageSpan, string.length(), string.length() + 1, 0);
textView.setText(spannableString);
What you can do is use a custom MetricAffectingSpan for maintaining its ratio like,
public class SuperscriptSpanAdjuster extends MetricAffectingSpan {
double ratio = 0.5;
public SuperscriptSpanAdjuster(double ratio) {
this.ratio = ratio;
}
#Override
public void updateDrawState(TextPaint paint) {
paint.baselineShift += (int) (paint.ascent() * ratio);
}
#Override
public void updateMeasureState(TextPaint paint) {
paint.baselineShift += (int) (paint.ascent() * ratio);
}
}
And the you can use SpannableString to apply asterisk to your String like,
SpannableString mString = new SpannableString("This is what I wanted*");
mString.setSpan(new SuperscriptSpanAdjuster(0.5), mString.length() - 1,
mString.length(), SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
mTextView.append("\n");
mTextView.append(mString);
This is append asterisk to your text as you required. And your output will be as,
Just wrap your drawable in inset drawable and set inset bottom to some value like 8dp. Not the best solution, but will work.
Modify your drawable/img_asterisk.xml --
<inset
xmlns:android="http://schemas.android.com/apk/res/android"
android:insetBottom="8dp">
<!-- Your previous asterisk drawable, probably a 'shape' -->
</inset>

Categories

Resources