Skip to content

Commit

Permalink
Implementation of RobotoTextAppearanceSpan.
Browse files Browse the repository at this point in the history
Close #43
  • Loading branch information
johnkil committed Nov 9, 2015
1 parent 69c86b0 commit 1b33c32
Show file tree
Hide file tree
Showing 18 changed files with 239 additions and 69 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package com.devspark.robototextview.style;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
import android.util.Log;
import android.util.SparseIntArray;

import com.devspark.robototextview.R;
import com.devspark.robototextview.util.RobotoTypefaceManager;
import com.devspark.robototextview.util.RobotoTypefaceUtils;

/**
* Sets the text color, size and typeface to match a TextAppearance resource.
*/
public class RobotoTextAppearanceSpan extends MetricAffectingSpan {
private static final int[] TEXT_ATTRS = new int[]{
android.R.attr.textSize, android.R.attr.textColor, android.R.attr.textColorLink};

private final Typeface mTypeface;
private final int mTextSize;
private final ColorStateList mTextColor;
private final ColorStateList mTextColorLink;

/**
* Uses the specified TextAppearance resource to determine the
* text appearance. The <code>appearance</code> should be, for example,
* <code>android.R.style.TextAppearance_Small</code>.
*/
public RobotoTextAppearanceSpan(Context context, int appearance) {
this(context, appearance, -1);
}

/**
* Uses the specified TextAppearance resource to determine the
* text appearance, and the specified text color resource
* to determine the color. The <code>appearance</code> should be,
* for example, <code>android.R.style.TextAppearance_Small</code>,
* and the <code>colorList</code> should be, for example,
* <code>android.R.styleable.Theme_textColorPrimary</code>.
*/
public RobotoTextAppearanceSpan(Context context, int appearance, int colorList) {
TypedArray a = context.obtainStyledAttributes(appearance, R.styleable.RobotoTextView);
mTypeface = RobotoTypefaceUtils.typefaceFromAttrs(context, a);
a.recycle();

ColorStateList textColor;

a = context.obtainStyledAttributes(appearance, TEXT_ATTRS);
SparseIntArray attrsIndexes = textAttrsIndexes();

textColor = a.getColorStateList(attrsIndexes.get(android.R.attr.textColor));
mTextColorLink = a.getColorStateList(attrsIndexes.get(android.R.attr.textColorLink));
mTextSize = a.getDimensionPixelSize(attrsIndexes.get(android.R.attr.textSize), -1);

a.recycle();

if (colorList >= 0) {
a = context.obtainStyledAttributes(themeResId(context), TEXT_ATTRS);
textColor = a.getColorStateList(colorList);
a.recycle();
}

mTextColor = textColor;
}

/**
* Makes text be drawn with the specified typeface, size and colors.
*/
public RobotoTextAppearanceSpan(Context context, int typefaceId, int size,
ColorStateList color, ColorStateList linkColor) {
mTypeface = RobotoTypefaceManager.obtainTypeface(context, typefaceId);
mTextSize = size;
mTextColor = color;
mTextColorLink = linkColor;
}

private int themeResId(Context context) {
try {
String packageName = context.getPackageName();
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(packageName, PackageManager.GET_META_DATA);
return packageInfo.applicationInfo.theme;
} catch (PackageManager.NameNotFoundException e) {
Log.w(getClass().getSimpleName(), e);
}
return -1;
}

private SparseIntArray textAttrsIndexes() {
SparseIntArray indexes = new SparseIntArray(TEXT_ATTRS.length);
for (int i = 0; i < TEXT_ATTRS.length; i++) {
indexes.put(TEXT_ATTRS[i], i);
}
return indexes;
}

/**
* Returns the typeface specified by this span.
*/
@NonNull
public Typeface getTypeface() {
return mTypeface;
}

/**
* Returns the text size specified by this span, or <code>-1</code>
* if it does not specify one.
*/
public int getTextSize() {
return mTextSize;
}

/**
* Returns the text color specified by this span, or <code>null</code>
* if it does not specify one.
*/
@Nullable
public ColorStateList getTextColor() {
return mTextColor;
}

/**
* Returns the link color specified by this span, or <code>null</code>
* if it does not specify one.
*/
@Nullable
public ColorStateList getLinkTextColor() {
return mTextColorLink;
}

@Override
public void updateDrawState(TextPaint tp) {
updateMeasureState(tp);
if (mTextColor != null) {
tp.setColor(mTextColor.getColorForState(tp.drawableState, 0));
}
if (mTextColorLink != null) {
tp.linkColor = mTextColorLink.getColorForState(tp.drawableState, 0);
}
}

@Override
public void updateMeasureState(TextPaint tp) {
RobotoTypefaceUtils.setup(tp, mTypeface);
if (mTextSize > 0) {
tp.setTextSize(mTextSize);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import android.content.Context;
import android.graphics.Typeface;
import android.support.annotation.NonNull;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;

import com.devspark.robototextview.util.RobotoTextViewUtils;
import com.devspark.robototextview.util.RobotoTypefaceUtils;
import com.devspark.robototextview.util.RobotoTypefaceManager;

/**
Expand Down Expand Up @@ -52,14 +53,21 @@ public RobotoTypefaceSpan(Context context, int fontFamily, int textWeight, int t
mTypeface = RobotoTypefaceManager.obtainTypeface(context, fontFamily, textWeight, textStyle);
}

@Override
public void updateDrawState(TextPaint ds) {
RobotoTextViewUtils.setTypeface(ds, mTypeface);
/**
* Returns the typeface specified by this span.
*/
@NonNull
public Typeface getTypeface() {
return mTypeface;
}

@Override
public void updateMeasureState(TextPaint paint) {
RobotoTextViewUtils.setTypeface(paint, mTypeface);
public void updateDrawState(TextPaint tp) {
updateMeasureState(tp);
}

@Override
public void updateMeasureState(TextPaint tp) {
RobotoTypefaceUtils.setup(tp, mTypeface);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.TextView;

Expand All @@ -30,9 +32,9 @@
*
* @author Evgeny Shishkin
*/
public class RobotoTextViewUtils {
public final class RobotoTypefaceUtils {

private RobotoTextViewUtils() {
private RobotoTypefaceUtils() {
}

/**
Expand All @@ -43,29 +45,33 @@ private RobotoTextViewUtils() {
* access the current theme, resources, etc.
* @param attrs The attributes of the XML tag that is inflating the widget.
*/
public static void initTypeface(TextView textView, Context context, AttributeSet attrs) {
public static void initView(@NonNull TextView textView, @NonNull Context context, @Nullable AttributeSet attrs) {
Typeface typeface;

if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RobotoTextView);

if (a.hasValue(R.styleable.RobotoTextView_typeface)) {
int typefaceValue = a.getInt(R.styleable.RobotoTextView_typeface, RobotoTypefaceManager.Typeface.ROBOTO_REGULAR);
typeface = RobotoTypefaceManager.obtainTypeface(context, typefaceValue);
} else {
int fontFamily = a.getInt(R.styleable.RobotoTextView_fontFamily, RobotoTypefaceManager.FontFamily.ROBOTO);
int textWeight = a.getInt(R.styleable.RobotoTextView_textWeight, RobotoTypefaceManager.TextWeight.NORMAL);
int textStyle = a.getInt(R.styleable.RobotoTextView_textStyle, RobotoTypefaceManager.TextStyle.NORMAL);

typeface = RobotoTypefaceManager.obtainTypeface(context, fontFamily, textWeight, textStyle);
}

typeface = typefaceFromAttrs(context, a);
a.recycle();
} else {
typeface = RobotoTypefaceManager.obtainTypeface(context, RobotoTypefaceManager.Typeface.ROBOTO_REGULAR);
}

setTypeface(textView, typeface);
setup(textView, typeface);
}

@NonNull
public static Typeface typefaceFromAttrs(@NonNull Context context, @NonNull TypedArray a) {
Typeface typeface;
if (a.hasValue(R.styleable.RobotoTextView_typeface)) {
int typefaceValue = a.getInt(R.styleable.RobotoTextView_typeface, RobotoTypefaceManager.Typeface.ROBOTO_REGULAR);
typeface = RobotoTypefaceManager.obtainTypeface(context, typefaceValue);
} else {
int fontFamily = a.getInt(R.styleable.RobotoTextView_fontFamily, RobotoTypefaceManager.FontFamily.ROBOTO);
int textWeight = a.getInt(R.styleable.RobotoTextView_textWeight, RobotoTypefaceManager.TextWeight.NORMAL);
int textStyle = a.getInt(R.styleable.RobotoTextView_textStyle, RobotoTypefaceManager.TextStyle.NORMAL);
typeface = RobotoTypefaceManager.obtainTypeface(context, fontFamily, textWeight, textStyle);
}
return typeface;
}

/**
Expand All @@ -75,7 +81,7 @@ public static void initTypeface(TextView textView, Context context, AttributeSet
* @param textView The text view
* @param typeface The specify typeface
*/
public static void setTypeface(TextView textView, Typeface typeface) {
public static void setup(@NonNull TextView textView, @NonNull Typeface typeface) {
textView.setPaintFlags(textView.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
textView.setTypeface(typeface);
}
Expand All @@ -86,9 +92,8 @@ public static void setTypeface(TextView textView, Typeface typeface) {
* @param paint The paint
* @param typeface The specify typeface
*/
public static void setTypeface(Paint paint, Typeface typeface) {
public static void setup(@NonNull Paint paint, @NonNull Typeface typeface) {
paint.setFlags(paint.getFlags() | Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
paint.setTypeface(typeface);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import android.util.AttributeSet;
import android.widget.AutoCompleteTextView;

import com.devspark.robototextview.util.RobotoTextViewUtils;
import com.devspark.robototextview.util.RobotoTypefaceUtils;

/**
* Implementation of a {@link AutoCompleteTextView} with native support for all the Roboto fonts.
Expand Down Expand Up @@ -60,7 +60,7 @@ public RobotoAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);

if (!isInEditMode()) {
RobotoTextViewUtils.initTypeface(this, context, attrs);
RobotoTypefaceUtils.initView(this, context, attrs);
}
}

Expand All @@ -82,7 +82,7 @@ public RobotoAutoCompleteTextView(Context context, AttributeSet attrs, int defSt
super(context, attrs, defStyle);

if (!isInEditMode()) {
RobotoTextViewUtils.initTypeface(this, context, attrs);
RobotoTypefaceUtils.initView(this, context, attrs);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import android.util.AttributeSet;
import android.widget.Button;

import com.devspark.robototextview.util.RobotoTextViewUtils;
import com.devspark.robototextview.util.RobotoTypefaceUtils;

/**
* Implementation of a {@link Button} with native support for all the Roboto fonts.
Expand Down Expand Up @@ -60,7 +60,7 @@ public RobotoButton(Context context, AttributeSet attrs) {
super(context, attrs);

if (!isInEditMode()) {
RobotoTextViewUtils.initTypeface(this, context, attrs);
RobotoTypefaceUtils.initView(this, context, attrs);
}
}

Expand All @@ -82,7 +82,7 @@ public RobotoButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);

if (!isInEditMode()) {
RobotoTextViewUtils.initTypeface(this, context, attrs);
RobotoTypefaceUtils.initView(this, context, attrs);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import android.util.AttributeSet;
import android.widget.CheckBox;

import com.devspark.robototextview.util.RobotoTextViewUtils;
import com.devspark.robototextview.util.RobotoTypefaceUtils;

/**
* Implementation of a {@link CheckBox} with native support for all the Roboto fonts.
Expand Down Expand Up @@ -60,7 +60,7 @@ public RobotoCheckBox(Context context, AttributeSet attrs) {
super(context, attrs);

if (!isInEditMode()) {
RobotoTextViewUtils.initTypeface(this, context, attrs);
RobotoTypefaceUtils.initView(this, context, attrs);
}
}

Expand All @@ -82,7 +82,7 @@ public RobotoCheckBox(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);

if (!isInEditMode()) {
RobotoTextViewUtils.initTypeface(this, context, attrs);
RobotoTypefaceUtils.initView(this, context, attrs);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import android.util.AttributeSet;
import android.widget.CheckedTextView;

import com.devspark.robototextview.util.RobotoTextViewUtils;
import com.devspark.robototextview.util.RobotoTypefaceUtils;

/**
* Implementation of a {@link CheckedTextView} with native support for all the Roboto fonts.
Expand Down Expand Up @@ -60,7 +60,7 @@ public RobotoCheckedTextView(Context context, AttributeSet attrs) {
super(context, attrs);

if (!isInEditMode()) {
RobotoTextViewUtils.initTypeface(this, context, attrs);
RobotoTypefaceUtils.initView(this, context, attrs);
}
}

Expand All @@ -82,7 +82,7 @@ public RobotoCheckedTextView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);

if (!isInEditMode()) {
RobotoTextViewUtils.initTypeface(this, context, attrs);
RobotoTypefaceUtils.initView(this, context, attrs);
}
}

Expand Down
Loading

0 comments on commit 1b33c32

Please sign in to comment.