Add drawable starting of multiline text view - android

Need to add Quote as a drawable in multiline text like below mentioned screen. Like you can see quote is in a starting of multiline text and next line text is just starting from the below to the quote.
I need to use TextView to achieve this and quote should be a drawable.
If I am using drawableLeft property of TextView Its showing like below mentioned image.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!\nHello World!\nHello World!\nHello World!"
android:drawableStart="#drawable/ic_quote"
android:drawableLeft="#drawable/ic_quote"/>

You can create a SpannableString to add the drawable :
TextView myTextView = (TextView) findViewById(R.id.myTextView);
ImageSpan imageSpan = new ImageSpan(this, R.drawable.ic_quote);
SpannableString spannableString = new SpannableString("*" + myTextView.getText()); // "*" will be replaced by your drawable
int start = 0; // the start index, inclusive
int end = 1; // the end index, exclusive
int flag = 0;
spannableString.setSpan(imageSpan, start, end, flag);
myTextView.setText(spannableString);
And in your layout :
<TextView
android:id="#+id/myTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!\nHello World!\nHello World!\nHello World!"/>

Try using android:gravity="top"
if it didnt work then go with negative margin like this
android:drawablePadding="-20sp"
Another alternative way is to take an ImageView beside TextView inside LinearLayout so you can apply gravity

You can use SpannableStringBuilder.
val spannableText = SpannableStringBuilder("*Your text!").apply {
val imageSpan = ImageSpan(context, R.drawable.your_icon)
setSpan(imageSpan, 0, 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
}
textView.setText(spannableText, TextView.BufferType.SPANNABLE)
The symbol * will be raplaced witn your icon.

Related

Change position of icon drawable in TextView

In my case, I have a textView with a drawable icon at the start of it(android:drawableStart), when the text of textView is multi-line, the icon goes in the vertical center of textView, but I want the icon to be aligned to the top of the text, how can I do this?
I don't want use any other layouts for doing this
There is api to set the drawable, but first you should set the bounds .
You can use setCompoundDrawablesWithIntrinsicBounds to set the drawable icons.
textview.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(getApplicationContext(), R.drawable.icon), null, ContextCompat.getDrawable(getApplicationContext(), R.drawable.icon_two), null);
As according to the interface you can see the position clearly and use accordingly to your need.
public void setCompoundDrawablesWithIntrinsicBounds (int left,
int top,
int right,
int bottom)
It is something different but a quick workaround.
Just use a Checkbox instead of a TextView and use android:button to define your drawable:
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:button="#drawable/..."
android:gravity="top"
android:clickable="false"
android:text=".."/>
The approach I followed is to use SpannableString by setting a Span to the beginning of the string, being the Spain an ImageSpain
fun TextView.setDrawableAtStart(context: Context, textToSet: String?, #DrawableRes drawableRes: Int) {
if (textToSet.isNullOrBlank()) return
text = SpannableString(" $textToSet ").apply {
val drawable = ContextCompat.getDrawable(context, drawableRes) ?: return
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
setSpan(
ImageSpan(drawable, ImageSpan.ALIGN_BASELINE),
0, // Start position
1, // End position
Spannable.SPAN_INCLUSIVE_EXCLUSIVE
)
}
}
I encourage you to read this interesting article about styling a text in Android.

Android: SetSpan does not apply to TextView

everyone. I have two Linear Layoutthat used as Button in my activity. Inside my Linear Layout, I have one TextView. When I clicked the first or second Linear Layout, I am trying to change its fonts.
I have used a similar code before one of my fragments and I was working. However, I tried with it with my new activity, and it does not apply. I tried both StyleSpanand TextAppearanceSpanand non of them worked.
My Activiy:
private fun changeFont(status: Boolean) {
val bss = TextAppearanceSpan(this, R.style.CustomFont1)
val gss = TextAppearanceSpan(this, R.style.CustomFont2)
val x = StyleSpan(Typeface.BOLD)
val y = StyleSpan(Typeface.NORMAL)
if (status) {
var text = SpannableString(binding?.tvList?.text)
text.setSpan(bss, 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
binding?.tvList?.text = text
text = SpannableString(binding?.tvMap?.text)
text.setSpan(gss, 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
binding?.tvMap?.text = text
} else {
var text = SpannableString(binding?.tvList?.text)
text.setSpan(x, 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
binding?.tvList?.text = text
text = SpannableString(binding?.tvMap?.text)
text.setSpan(y, 0, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
binding?.tvMap?.text = text
}
}
My Example Linear Layout Design:
<LinearLayout
android:id="#+id/llMap"
android:layout_margin="4dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:background="#drawable/bg_card_round_6"
android:backgroundTint="#color/filterBackground"
android:gravity="center">
<com.google.android.material.textview.MaterialTextView
android:id="#+id/tvMap"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
style="#style/CustomFont1"
android:text="#string/stock_toggle_btn2"/>
</LinearLayout>
PS: I have also tried to remove text style from XML and SPAN_INCLUSIVE_INCLUSIVEon code.

GradientDrawable border textview croped

As you can see on the picture below, I put a GradientDrawable as background of a textview.
The result is weird : the text is croped.
Result
And there is the code :
GradientDrawable border = new GradientDrawable();
border.setColor(0x00FFFFFF);
border.setStroke(1,Color.GRAY);
border.setCornerRadius(size);
EditText surname = new EditText(this);
surname.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
surname.setBackground(border);
surname.setTypeface(Stats.fontRegular);
FrameLayout.LayoutParams lps = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, size_x);
surname.setLayoutParams(lps);
view.addView(surname);
If you know a way to uncrop the text it will be very usefull for me :)
You can change the gravity with this XML code:
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/**yourstringname**"
/>
I found something that works :
When you use a EditText, it seems that there are some paddings inside the view. So you can 'disable' them using
EditText.setPadding(int left, int top, int right, int bottom)
Try this:
GradientDrawable border = new GradientDrawable();
border.setColor(0x00FFFFFF);
border.setStroke(1,Color.GRAY);
border.setCornerRadius(size);
border.setSize(450, 150);

How can I set Imageview and Textview on same line in LinearLayout

I want to set Imageview and Textview on same line in LinearLayout but the Imageview is always higher than the Textview.
Here is my code:
String b[] = cacBuocThucHien.split("#");
for (int j = 0; j < b.length; j++) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(30,30);
lp.setMargins(50, 0, 0, 0);
ImageView img = new ImageView(RecipesDetailActivity.this);
TextView tv = new TextView(RecipesDetailActivity.this);
img.setLayoutParams(lp2);
img.setImageResource(R.mipmap.testic);
tv.setLayoutParams(lp);
tv.setText(b[j] + "\n");
layoutHuongDan.addView(img);
layoutHuongDan.addView(tv);
}
This You can use to put image in one line.. and it will work in all kind of layouts. Hope this will help you
<LinerLayout>
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
....... // Put how many TextViews you want
<TextView
android:id="#+id/textn"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinerLayout>
You can set visibility gone initially if you wanna show these textviews only after setting text.
Now in your activity make an array of ids of textviews like this...
public static int[] textRows = {R.id.text1, R.id.text2, ........ R.id.textn};
then use for loop for initializing them and setting text and images like this
TextView[] allTexts = new TextView[n];
for (int i = 0; i < n; i++) {
allTexts[i] = (TextView) findViewById(textRows[i]);
allTexts[i].setText("your text");
allTexts[i].setCompoundDrawables(left_image, null, null, null);
}
It will work. Try it out
set textview drawable left no need of extra imageview
android:drawableLeft="#drawable/img"
If you only want to show an icon beside that TextView, in my opinion you should consider using drawable icon feature of TextView
tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.icon, 0, 0, 0);
But if you would insist to using two views beside each other, using layout gravity would be useful in such circumstances.
lp.gravity= Gravity.CENTER_VERTICAL;
If you want to display only TextView and ImageView.. go for setting CompounDrawable in TextView itself..
But, for having two views side-by-side in LinearLayout programmatically try setting the orientation=horizontal, check out this link.

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
}

Categories

Resources