Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Custom TextView implementation to allow VectorDrawableCompat to work with compound Drawables
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CompatTextView">
<attr name="drawableStart" format="reference"/>
<attr name="drawableTop" format="reference"/>
<attr name="drawableEnd" format="reference"/>
<attr name="drawableBottom" format="reference"/>
</declare-styleable>
</resources>
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.AppCompatDrawableManager;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import android.widget.TextView;
public class CompatTextView extends AppCompatTextView {
public CompatTextView(Context context) {
super(context);
init(null);
}
public CompatTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public CompatTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CompatTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
private void init(@Nullable AttributeSet attrs) {
if (attrs != null) {
Context context = getContext();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CompatTextView);
// Obtain DrawableManager used to pull Drawables safely, and check if we're in RTL
AppCompatDrawableManager dm = AppCompatDrawableManager.get();
boolean rtl = ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
// Grab the compat drawable resources from the XML
int startDrawableRes = a.getResourceId(R.styleable.CompatTextView_drawableStart, 0);
int topDrawableRes = a.getResourceId(R.styleable.CompatTextView_drawableTop, 0);
int endDrawableRes = a.getResourceId(R.styleable.CompatTextView_drawableEnd, 0);
int bottomDrawableRes = a.getResourceId(R.styleable.CompatTextView_drawableBottom, 0);
// Load the used drawables, falling back to whatever may be set in an "android:" namespace attribute
Drawable[] currentDrawables = getCompoundDrawables();
Drawable left = startDrawableRes != 0 ? dm.getDrawable(context, startDrawableRes) : currentDrawables[0];
Drawable right = endDrawableRes != 0 ? dm.getDrawable(context, endDrawableRes) : currentDrawables[1];
Drawable top = topDrawableRes != 0 ? dm.getDrawable(context, topDrawableRes) : currentDrawables[2];
Drawable bottom = bottomDrawableRes != 0 ? dm.getDrawable(context, bottomDrawableRes) : currentDrawables[3];
// Account for RTL and apply the compound Drawables
Drawable start = rtl ? right : left;
Drawable end = rtl ? left : right;
setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom);
a.recycle();
}
}
}
@trevjonez

This comment has been minimized.

Copy link

@trevjonez trevjonez commented Apr 9, 2016

Thanks for putting this together. Not sure why they didn't do this to AppCompatTextView in 23.2.0

@ZacSweers

This comment has been minimized.

Copy link

@ZacSweers ZacSweers commented Apr 14, 2016

Is this just for loading compound drawables or can it load vector drawables directly? I get crashes with the latter, which seems counter to the point :/

@danielgomezrico

This comment has been minimized.

@raychenon

This comment has been minimized.

Copy link

@raychenon raychenon commented Nov 23, 2016

This code won't build at this line

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public CompatTextView(final Context context, final AttributeSet attrs, final int defStyleAttr,
         final int defStyleRes) {
     super(context, attrs, defStyleAttr, defStyleRes); //  AppCompatTextView doesn't have this constructor .
     init(attrs);
 }

My support version is '24.2.0'

final SUPPORT_LIBRARY_VERSION = '24.2.0'
compile "com.android.support:support-vector-drawable:$SUPPORT_LIBRARY_VERSION"
@Jericho2Code

This comment has been minimized.

Copy link

@Jericho2Code Jericho2Code commented Aug 30, 2018

Hello, method getCompoundDrawables() return drawables in order "start, top, end, and bottom". Why you use currentDrawables[1] for right (end), in 53 line ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment