I have TextView
with drawableLeft
& drawableRight
in List item.
The problem is, whenever the height of TextView
is l
I solved an equivalent usecase by introducing a ScaleDrawable
and overriding its .getIntrisicHeight()
so that it is at least the TextView
height. The TextView.addOnLayoutChangeListener
part, required to rebind the Drawable
on a TextView
size change works with API11+
Drawable underlyingDrawable =
new BitmapDrawable(context.getResources(), result);
// Wrap to scale up to the TextView height
final ScaleDrawable scaledLeft =
new ScaleDrawable(underlyingDrawable, Gravity.CENTER, 1F, 1F) {
// Give this drawable a height being at
// least the TextView height. It will be
// used by
// TextView.setCompoundDrawablesWithIntrinsicBounds
public int getIntrinsicHeight() {
return Math.max(super.getIntrinsicHeight(),
competitorView.getHeight());
};
};
// Set explicitly level else the default value
// (0) will prevent .draw to effectively draw
// the underlying Drawable
scaledLeft.setLevel(10000);
// Set the drawable as a component of the
// TextView
competitorView.setCompoundDrawablesWithIntrinsicBounds(
scaledLeft, null, null, null);
// If the text is changed, we need to
// re-register the Drawable to recompute the
// bounds given the new TextView height
competitorView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
competitorView.setCompoundDrawablesWithIntrinsicBounds(scaledLeft, null, null, null);
}
});
Just make 9-path background repeating this pattern.
And also it seems it will be better look in case the pattern will be applied to the list, not to individual item.
Hope this help
Textview tv = (TextView) findViewById(R.id.tv_dummy)
int imageResource = R.mipmap.ic_image;
Drawable drawable = ContextCompat.getDrawable(context, imageResource);
int pixelDrawableSize = (int)Math.round(tv.getLineHeight() * 0.7); // Or the percentage you like (0.8, 0.9, etc.)
drawable.setBounds(0, 0, pixelDrawableSize, pixelDrawableSize); // setBounds(int left, int top, int right, int bottom), in this case, drawable is a square image
tv.setCompoundDrawables(
null, //left
null, //top
drawable, //right
null //bottom
);
I did not found way. But that you show looks like a list of items. Each item would be a LinearLayout horizontal with imagesView from left to right and text in center. The image dimension do a android:scaleType="fitXY" for ajust the size height to the textview height. If you want no deform de image use scaleType="CENTER_INSIDE". http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
<LinearLayout
android:layout_width="fill_parent"
android:id="@+id/HeaderList"
android:layout_gravity="top"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/backImg"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:background="@color/blancotransless"
android:src="@drawable/header"
android:scaleType="fitXY" >
</ImageView>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/NameText"
android:text="The time of prayer"
android:textColor="#FFFFFF"
android:textSize="30sp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:paddingLeft="4dp"
android:paddingTop="4dp"
/>
<ImageView
android:id="@+id/backImg"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:background="@color/blancotransless"
android:src="@drawable/header"
android:scaleType="fitXY" >
</ImageView>
</LinearLayout>
This might help you out. There are two properties scaleX and scaleY
The code below will scale down the image and the text with 30%. Therefore you have to increase the font size with that many "sp", so that when it get re-sized (scaled) it would fit the "sp" you prefer.
Example. If I set the font to 18, then 30% out of 18 is 5.4sp, so roughly, this is the value I am targeting at, because when it gets scaled, it would become 13sp
<TextView
android:textSize="18sp"
android:scaleX="0.7"
android:scaleY="0.7"
The last thing to do is set the CompundDrawable.
tview.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.xxx), null, null, null);
I think the cleanest solution would be to override TextView
. Here's an example:
https://gist.github.com/hrules6872/578b52fe90c30c7445a2
I changed a bit:
private void resizeCompoundDrawables() {
Drawable[] drawables = getCompoundDrawables();
if (compoundDrawableWidth > 0 || compoundDrawableHeight > 0) {
for (Drawable drawable : drawables) {
if (drawable == null) continue;
Rect realBounds = drawable.getBounds();
float drawableWidth = realBounds.width();
if(this.compoundDrawableWidth>0)
drawableWidth = this.compoundDrawableWidth;
float drawableHeight = realBounds.height();
if(this.compoundDrawableHeight>0)
drawableHeight = this.compoundDrawableHeight;
realBounds.right = realBounds.left + Math.round(drawableWidth);
realBounds.bottom = realBounds.top + Math.round(drawableHeight);
drawable.setBounds(realBounds);
}
}
super.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]);
}
This way you can set the size of the drawable but if you care about width/height ratio make it the way suits you.
Now if you want it to automatically match height of the textview you may also override the TextView
's method onSizeChanged
:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
compoundDrawableHeight = h;
resizeCompoundDrawables();
}
You my also want to declare sizes for each side, for example leftCompoundDrawableWidth, rightCompoundDrawableWidth and so on.
Note that it does not work with a Shape as drawable. Sounds like TextView
only accepts it if it has the size attributes, that way one can implement it by updating the size of the shapedrawable using setSize or setIntrinsicWidth or ... Not tested.