I have TextView
with drawableLeft
& drawableRight
in List item.
The problem is, whenever the height of TextView
is larger, drawableLeft
& drawableLeft
didn't automatically scale based on the height of the TextView
.
Is it possible to scale the height of drawableLeft
& drawableRight
in TextView
?开发者_运维百科
(I was using 9 patch image)
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);
Wrap your resource in a drawable that defines your desired size similar to:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@drawable/icon"
android:width="@dimen/icon_size"
android:height="@dimen/icon_size" />
</layer-list >
After that, use this drawable in your textview tag
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
);
The only acceptable answer here should be to use an ImageView with the scaleTypes as per usual. Hacky work arounds to scale an image on a TextView that isn't supported by Android seems.. unnecessary. Use the SDK as it was intended.
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);
}
});
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>
Another approach to create a custom size for the drawable inside the TextView is by using the BindingAdapter. Using this, you will be able to set you image size in your xml.
For example, TextViewBindingAdapter.java
public class TextViewBindingAdapter {
@BindingAdapter({"android:imageSize"})
public static void bindIconSize(TextView textView, int size) {
Drawable[] drawables = textView.getCompoundDrawables();
if(drawables[0] != null) {
drawables[0].setBounds(0, 0, size, size); // setBounds(int left, int top, int right, int bottom), in this case, drawable is a square image
textView.setCompoundDrawables(
drawables[0], //left
null, //top
null, //right
null //bottom
);
}
if(drawables[1] != null) {
drawables[1].setBounds(0, 0, size, size); // setBounds(int left, int top, int right, int bottom), in this case, drawable is a square image
textView.setCompoundDrawables(
null, //left
drawables[1], //top
null, //right
null //bottom
);
}
if(drawables[2] != null) {
drawables[2].setBounds(0, 0, size, size); // setBounds(int left, int top, int right, int bottom), in this case, drawable is a square image
textView.setCompoundDrawables(
null, //left
null, //top
drawables[2], //right
null //bottom
);
}
if(drawables[3] != null) {
drawables[3].setBounds(0, 0, size, size); // setBounds(int left, int top, int right, int bottom), in this case, drawable is a square image
textView.setCompoundDrawables(
null, //left
null, //top
null, //right
drawables[3] //bottom
);
}
}
}
Now, in your .xml you can set the android:imageSize.
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:drawableLeft="@drawable/alpha_s_circle"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:textSize="16sp"
android:imageSize="@{300}"/>
And don't forget to set in your gradle.build this code below:
android {
....
buildFeatures {
dataBinding = true
}
}
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.
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.
Maybe it's worth look at ImageSpan. It's a span that replaces the text it's attached to with a Drawable that can be aligned with the bottom or with the baseline of the surrounding. I think it will automatically scale it as well based on the height of the textview.
https://developer.android.com/reference/android/text/style/ImageSpan
I Tried all the solutions but none of them worked for me, then I tried this one
in TextView
<TextView
android:gravity="left"
android:id="@+id/product_view_count"
android:text="@string/view_product_count"
android:drawableLeft="@drawable/ic_eye"
android:drawablePadding="2dp"
android:drawableTint="@color/orange"
android:textSize="20sp"
android:textColor="@color/orange"
android:textStyle="bold"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
in your Activity or fragment or Adapter. I am using my adapter like this
viewcount=itemView.findViewById(R.id.product_view_count);
holder.viewcount.setPivotX(0);
holder.viewcount.setPivotY(0);
holder.viewcount.setScaleX(.7f);
holder.viewcount.setScaleY(.7f);
by using ScaleX, ScaleY
in TextView
text position will change. to keep the position in left/start
using setPivotX,setPivotY
Thank's to Bö macht Blau for the nice solution here
The easiest is to create a new drawable and adjust the drawable objects size
<vector xmlns:android="http://schemas.android.com/apk/res/android"
**android:width="50dp"
android:height="50dp"**
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="@android:color/white">
<path
android:fillColor="@android:color/black"
android:pathData="M19,3H4.99C3.89,3 3,3.9 3,5l0.01,14c0,1.1 0.89,2 1.99,2h10l6,-6V5C21,3.9 20.1,3 19,3zM7,8h10v2H7V8zM12,14H7v-2h5V14zM14,19.5V14h5.5L14,19.5z"/>
</vector>
精彩评论