PagerTabStrip is clipping off the icon - android

The design called for just icon on the tab of the PagerTabStrip.
Here's the XML:
<android.support.v4.view.PagerTabStrip
android:id="#+id/tbstrp_album"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foregroundGravity="bottom"
android:padding="0dp"
android:background="#color/offWhite">
Here's my getPageTitle inside the adapter:
#Override
public CharSequence getPageTitle(int position) {
// This is "generic" string that we will use as the title to be replaced.
String title = "title";
Drawable myDrawable = oContext.getDrawable(R.drawable.alpha);
// initiate the SpannableString builder
SpannableStringBuilder spanBuilder = new SpannableStringBuilder(title); // space added before text for convenience
// set the drawable's size...if it could be too big or too small for display
myDrawable.setBounds(0, 0, 50, 50);
// turn the Drawable into ImageSpan and align it along the baseline
ImageSpan imageSpan = new ImageSpan(myDrawable, ImageSpan.ALIGN_BASELINE);
// CRUCIAL: this is where we replace the "title" w/ the image
// 0: we start from the beginning
// title.length(): we are replacing the entire string
// the last flag doesn't do anything in our case
spanBuilder.setSpan(imageSpan, 0, title.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spanBuilder;
}
The output looks like this:
What's causing the strip clipping the image? Thanks!

It turns out this statement is the culprit:
myDrawable.setBounds(0, 0, 50, 50);
I changed the second argument which is the "top" to 30 and the icon was not clipped.
The unanswered question is still...why do I have to specify a value for the "top" argument.

Related

Adding multiple smiles in TextView using ImageSpan

I am trying to add multiple smiles in textview using this code.
This is my TextView.
<TextView
android:id="#+id/textViewId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:bufferType="spannable" />
And this is add smiley function.
public void addSmily() {
int resource = R.drawable.smily ;
Spannable spannable = Spannable.Factory.getInstance().newSpannable(" ");
Drawable d = ContextCompat.getDrawable(this, resource);
d.setBounds(0, 0, 40, 40);
ImageSpan smilySpan = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
spannable.setSpan(smilySpan, spannable.length()-1, spannable.length(), 0);
sendText.append(spannable);
}
Smiles are adding perfectly but the problem is when I add lots of smiles did not fit in a single line then the first line of smiles become invisible and they start from the 2nd line.
This is what happening. Plz, someone help me.
Solution:
Try this inside your button:
SpannableString ss = new SpannableString("abc");
Drawable d = ContextCompat.getDrawable(your_activity.this, R.drawable.your_smiley_drawable);
d.setBounds(0, 0, 40, 40);
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, 0, 3, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
edittext.append(ss);
Note: Also, EditText's inputtype must be textMultiline.
Try it, Works in my lap, Let's Hope it helps to you too.
You can also set smiley by unicode in textview.
how set emoji by unicode in a textview?
int unicode = 0x1F60A;
Which can be used with
public String getEmojiByUnicode(int unicode){
return new String(Character.toChars(unicode));
}
So Textview displays 😊 without Drawable
Try it with http://apps.timwhitlock.info/emoji/tables/unicode
Hope it may help you.

ImageSpan Size Measurement with TextView and StaticLayout

I have a simple layout contains just one TextView.
I wanna load an image into TextView using ImageSpan.
Below method creates Spannable:
private Spannable getImageSpannable(int drawableId, int targetWidth, int targetHeight) {
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), drawableId);
Bitmap bitmap = Bitmap.createScaledBitmap(originalBitmap, targetWidth, targetHeight, true);
Drawable dr = new BitmapDrawable(getResources(), bitmap);
dr.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
Spannable imageSpannable = new SpannableString("\uFFFC");
ImageSpan imgSpan = new ImageSpan(dr, DynamicDrawableSpan.ALIGN_BOTTOM);
imageSpannable.setSpan(imgSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return imageSpannable;
}
I use this method to create content like this:
public void setContent() {
SpannableStringBuilder content = new SpannableStringBuilder();
content.append(getImageSpannable(R.drawable.my_image, 100, 260));
content.append("\n");
txtContent.setText(content);
}
When I call setContent() method my result is something like this:
As you see there is small gap between ImageSpan and top of TextView.
This is not line spacing, because I set line spacing to 0.
And interesting point is when I remove "\n" from content(declared in setContent method) this space is gone.
And another point is that when I tried to measure content size using StaticLayout, with "\n" at the end bottom of line 0 it returns 270 and without "\n" it returns 260.
This behavior causes some difficulties for me, because I have to measure text and ImageSpan using StaticLayout and decide witch one can fit into TextView.
I appreciate everyone can help me.
Thanks.
Here's my xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtContent"
android:layout_width="300dp"
android:layout_height="500dp"
android:background="#fed9f4"
android:textSize="22sp"/>
</LinearLayout>
I'v done some tests and I find that font size is affects ImageSpan rendering.
Can somebody explain this affect please?
I hope this method works
The following line of code
public void setContent() {
SpannableStringBuilder content = new SpannableStringBuilder();
content.append(getImageSpannable(R.drawable.my_image, 100, 260));
content.append("\n");
txtContent.setText(content);
}
Change to
public void setContent() {
SpannableStringBuilder content = new SpannableStringBuilder();
content.append(getImageSpannable(R.drawable.my_image, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
content.append("\n");
txtContent.setText(content);
}
And resize "R.drawable.my_image" dimensions

How to modify SpannableString to string below icon?

Currently I have a spannableString like this, the icon is at the left of the title string. The problem is, is there any way to make the icon above the string , while the icon is align center?
Sample like this:
[] <==== This is the icon
TitleTest <=== This is the title
ABCD
Thanks
Here is my code attempted:
Drawable image = context.getResources().getDrawable(R.drawable.ic_launcher);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
// Replace blank spaces with image icon
SpannableString sb = new SpannableString(" " + tabTitles[position]);
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BASELINE);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
Thanks for helping
I was looking at https://guides.codepath.com/android/Google-Play-Style-Tabs-using-TabLayout today and had the same question. Adding a newline to the SpannableString worked for me, so the following modification will do the trick:
SpannableString sb = new SpannableString(" \n" + tabTitles[position]);
Put the three views (ImageView for icon and 2 TextViews) in a vertical LinearLayout and use the android:layout_gravity property in XML to centre the views in the LinearLayout. Additionally set the android:gravity property on the TextViews to be "center" to centre the text within the TextView.
If you don't want to use XML (which seems to be the case) layout_gravity can be set using the LinearLayout.LayoutParams constructor with parameters for width, height AND GRAVITY. Text alignment can be done using mTextView.setGravity(Gravity.CENTER);
Just use the drawableTop attribute for this.
<TextView
android:drawableTop="#drawable/my_drawable"/>
Or from code:
myTextView.setCompoundDrawablesWithIntrinsicBounds(
0, R.drawable.my_drawable, 0, 0);

create spaces between image and string in spannable setSpan

I need to place an image and string in the center of the button. Need to create spaces between them.
a Hello (%1$d)
My code:
String textValue = getResources().getString(R.string.hello_text);
final Spannable buttonLabel = new SpannableString(String.format(textValue, 2));
//buttonLabel.setSpan(new ImageSpan(getApplicationContext(), R.drawable.hello_imagel,
// ImageSpan.ALIGN_BOTTOM), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
mButton.setText(buttonLabel);
I need give spaces between the image and the text. I tried giving spaces in the strings.xml but it doesn't display the spaces. After adding the below xml, the image is to the left and the string is in the center. I want the image and string to be in center with few spaces between image and string
xml:
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#2A2A2A"
android:drawableLeft="#drawable/hello_image1"
android:gravity="center"
If you don't need to show an icon inside a string you can add drawable to your button.
i.e. an icon at the left side of the text:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/icon"
android:drawablePadding="20dp">
where #drawable/icon is your icon and 20dp is padding between icon and text
Shure you can do the same from code - take a look at setCompoundDrawables and setCompoundDrawablePadding
sorry to be late, I hope this method helps you, is on kotlin:
fun setLeftIcon(roundButton: RoundButton, iconId: Int) = with(roundButton) {
if (iconId == DEFAULT_IMAGE_ID) return
val currentText = text.toString()
// The spaces are a workaround to add some space between the image and the text
val buttonLabel = SpannableString(" $currentText")
buttonLabel.setSpan(
ImageSpan(context, iconId),
0,
1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
text = buttonLabel
}

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