it possible to use drawableRight etc for SVG assets ?
Yes
AppCompatTextView now supports app:drawableLeftCompat
, app:drawableTopCompat
, app:drawableRightCompat
, app:drawableBottomCompat
, app:drawableStartCompat
and app:drawableEndCompat
compound drawables, supporting backported drawable types such as VectorDrawableCompat
.
Include this in your gradle file
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
In your text view you can use
app:drawableLeftCompat
app:drawableStartCompat
If you have problems while using app:drawableLeftCompat, app:drawableStartCompat in buttons you will need to update your library to
androidx.appcompat:appcompat:1.2.0-alpha01
they had a bug on
androidx.appcompat:appcompat:1.1.0-alpha01
you can see the docs
Or if you don't want to update yet, then:
Because it seems Google not going to do anything about this issue any time soon, I had to came up with a more solid reusable solution for all of my apps:
First add custom TextView attributes in attrs.xml file of your app "res/values/attrs.xml" :
<resources>
<declare-styleable name="CustomTextView">
<attr name="drawableStartCompat" format="reference"/>
<attr name="drawableEndCompat" format="reference"/>
<attr name="drawableTopCompat" format="reference"/>
<attr name="drawableBottomCompat" format="reference"/>
</declare-styleable>
</resources>
Then create custom TextView class like this:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.content.res.AppCompatResources;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
public class CustomTextView extends AppCompatTextView {
public CustomTextView(Context context) {
super(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initAttrs(context, attrs);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs);
}
void initAttrs(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray attributeArray = context.obtainStyledAttributes(
attrs,
R.styleable.CustomTextView);
Drawable drawableStart = null;
Drawable drawableEnd = null;
Drawable drawableBottom = null;
Drawable drawableTop = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
drawableStart = attributeArray.getDrawable(R.styleable.CustomTextView_drawableStartCompat);
drawableEnd = attributeArray.getDrawable(R.styleable.CustomTextView_drawableEndCompat);
drawableBottom = attributeArray.getDrawable(R.styleable.CustomTextView_drawableBottomCompat);
drawableTop = attributeArray.getDrawable(R.styleable.CustomTextView_drawableTopCompat);
} else {
final int drawableStartId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableStartCompat, -1);
final int drawableEndId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableEndCompat, -1);
final int drawableBottomId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableBottomCompat, -1);
final int drawableTopId = attributeArray.getResourceId(R.styleable.CustomTextView_drawableTopCompat, -1);
if (drawableStartId != -1)
drawableStart = AppCompatResources.getDrawable(context, drawableStartId);
if (drawableEndId != -1)
drawableEnd = AppCompatResources.getDrawable(context, drawableEndId);
if (drawableBottomId != -1)
drawableBottom = AppCompatResources.getDrawable(context, drawableBottomId);
if (drawableTopId != -1)
drawableTop = AppCompatResources.getDrawable(context, drawableTopId);
}
// to support rtl
setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, drawableTop, drawableEnd, drawableBottom);
attributeArray.recycle();
}
}
}
Now you can use it easily in any layouts by your custom attributes:
<YOUR_VIEW_PACKAGE.CustomTextView
android:id="@+id/edt_my_edit_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:drawableStartCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
app:drawableEndCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
app:drawableTopCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
app:drawableBottomCompat="@drawable/your_vector_drawable" <!-- vector drawable -->
/>
Hope this helps :)
The best way I found:
Drawable leftDrawable = AppCompatResources.getDrawable(this, R.drawable.ic_search);
search.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null);
This solution is no longer correct. From 23.3.0 version vector drawables can only be loaded via app:srcCompat or setImageResource()
Try to wrap your vector drawable into layer-list or selector:
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableRight="@drawable/ic_accessible_white_wrapped"
android:background="@color/colorPrimary"
android:textColor="#FFFFFF"
android:textSize="22sp"
android:text="Hello World!"/>
ic_accessible_white_wrapped.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_accessible_white_36px"/>
</layer-list>
To complement some of the answers here: you can get VectorDrawable to work as drawableLeft
(etc.) but it depends on the Support Library version and it comes with a price.
In which cases does it work? I've made this diagram to help (valid for Support Library 23.4.0 to - at least - 25.1.0).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With