Skip to content

Instantly share code, notes, and snippets.

@mannodermaus
Last active August 30, 2018 09:59
Show Gist options
  • Save mannodermaus/2f0c4089fcd20ef1ccc550600b56f99f to your computer and use it in GitHub Desktop.
Save mannodermaus/2f0c4089fcd20ef1ccc550600b56f99f to your computer and use it in GitHub Desktop.
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
Copy link

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

@ZacSweers
Copy link

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 :/

@raychenon
Copy link

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
Copy link

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