Reputation: 21937
In TextView
I set drawableLeft
where the drawable
is showing from center. I need to align the drawableLeft
with top inside TextView
like this image.
Is it possible to achieve this?
Upvotes: 55
Views: 30419
Reputation: 3645
Try like this:
class MyTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null
) : AppCompatTextView(context, style) {
private val leftDrawable = ContextCompat.getDrawable(context, R.drawable.checkmark)
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
setBulletPoint(compoundDrawables[0], canvas)
}
private fun setBulletPoint(drawableLeft: Drawable?, canvas: Canvas?) {
if (!TextUtils.isEmpty(text)) {
leftDrawable?.let { drlft ->
if (lineCount == 1) {
setCompoundDrawablesWithIntrinsicBounds(drlft, null, null, null)
} else {
val buttonWidth = drlft.intrinsicWidth
val buttonHeight = drlft.intrinsicHeight
val topSpace = abs(buttonHeight - lineHeight) / 2
drlft.setBounds(0, topSpace, buttonWidth, topSpace + buttonHeight)
canvas?.apply {
save()
drlft.draw(canvas)
restore()
}
}
}
}
}
}
Upvotes: 0
Reputation: 16329
I think it's even easier than all the answers above: You only need to do this:
public class TopGravityDrawable extends BitmapDrawable {
public TopGravityDrawable(Resources res, Bitmap bitmap) {
super(res, bitmap);
}
@Override
public void draw(Canvas canvas) {
int halfCanvas = canvas.getHeight() / 2;
int halfDrawable = getIntrinsicHeight() / 2;
canvas.save();
canvas.translate(0, -halfCanvas + halfDrawable);
super.draw(canvas);
canvas.restore();
}
}
And then
final Bitmap bitmap = BitmapFactory.decodeResource(mTitle.getResources(), R.drawable.icon);
icon = new TopGravityDrawable(mTitle.getResources(), bitmap);
title.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
Remember this only works properly with LEFT and RIGHT compound drawables
Upvotes: 10
Reputation: 2188
If you want a purely XML solution then you can use an inset drawable to re-position your desired drawable.
<?xml version="1.0" encoding="utf-8"?>
<inset
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/actual_image_to_be_shown"
android:insetTop="-32dp" />
You might have to play around with the inset value depending on your scenario. Then just use this XML drawable in your TextView drawableLeft/Start definition.
Upvotes: 3
Reputation: 101
you can do like this:
public class DrawableTopLeftTextView extends TextView {
public DrawableTopLeftTextView(Context context) {
super(context);
}
public DrawableTopLeftTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawableTopLeftTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
if (!TextUtils.isEmpty(getText())) {
Drawable[] drawables = getCompoundDrawables();
if (drawables != null) {
Drawable drawableLeft = drawables[0];
if (drawableLeft != null) {
Paint.FontMetricsInt fontMetricsInt = getPaint().getFontMetricsInt();
Rect bounds = new Rect();
getPaint().getTextBounds((String) getText(), 0, length(), bounds);
int textVerticalSpace = Math.round(bounds.top - fontMetricsInt.top);
int offset = (getHeight() - drawableLeft.getIntrinsicHeight()) / 2 - textVerticalSpace - getPaddingTop() / 2;
drawableLeft.setBounds(0, -offset, drawableLeft.getIntrinsicWidth(), drawableLeft.getIntrinsicHeight() - offset);
}
}
}
super.onDraw(canvas);
}
}
Upvotes: 5
Reputation: 293
Use SpannableString and ImageSpan to achieve this.
String msg=" "+"haii";
ImageSpan mImageSpan== new ImageSpan(mContext, R.drawable.icon);
SpannableString text = new SpannableString(msg);
text.setSpan(mImageSpan, 0, 1, 0);
mTextView.setText(text);
the extra space in the string variable is replaced by the icon.
Upvotes: 13
Reputation: 3876
See my answer here.
You can align a compound-Drawable to the top (or bottom) by creating a custom Drawable that wraps your Drawable, and then manipulate the drawing of your custom Drawable by overriding the method onDraw(Canvas)
.
The sample below is the simplest possible example. This aligns the image to the top, but you can also make it align to the bottom, left or right of the TextView by implementing the required logic in the onDraw(Canvas)
-method. You might also want to build in a margin in the onDraw(Canvas)
, to make your design implementation pixel perfect.
Sample usage:
GravityCompoundDrawable gravityDrawable = new GravityCompoundDrawable(innerDrawable);
// NOTE: next 2 lines are important!
innerDrawable.setBounds(0, 0, innerDrawable.getIntrinsicWidth(), innerDrawable.getIntrinsicHeight());
gravityDrawable.setBounds(0, 0, innerDrawable.getIntrinsicWidth(), innerDrawable.getIntrinsicHeight());
mTextView.setCompoundDrawables(gravityDrawable, null, null, null);
Sample code:
public class GravityCompoundDrawable extends Drawable {
// inner Drawable
private final Drawable mDrawable;
public GravityCompoundDrawable(Drawable drawable) {
mDrawable = drawable;
}
@Override
public int getIntrinsicWidth() {
return mDrawable.getIntrinsicWidth();
}
@Override
public int getIntrinsicHeight() {
return mDrawable.getIntrinsicHeight();
}
@Override
public void draw(Canvas canvas) {
int halfCanvas= canvas.getHeight() / 2;
int halfDrawable = mDrawable.getIntrinsicHeight() / 2;
// align to top
canvas.save();
canvas.translate(0, -halfCanvas + halfDrawable);
mDrawable.draw(canvas);
canvas.restore();
}
}
Upvotes: 8
Reputation: 474
Your can use by this way. May it can helpful you.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="@drawable/ic_launcher" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/imageView1"
android:text=" Text Text Text Text Text Text Text Text Text Text Text Text
Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text" />
</RelativeLayout>
Upvotes: 0