Je souhaite utiliser le jeu d'icônes de Font Awesome dans mon application Android. J'ai un TextView
pour définir ces icônes. Je ne veux pas utiliser d'image png. Mon Textview est comme ça ->
<TextView
Android:id="@+id/userLogin"
Android:text="Login Now"
Android:clickable="true"
Android:onClick="login"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
Non, je veux mettre une icône avant le texte Login Now. Comment faire ça ?
Vous pouvez suivre ceci répondre .
Commencez par télécharger le fichier fontawesome.ttf à partir de ici . Et mettez le fichier dans asset/fontawesome.ttf.
Ensuite, créez une classe FontAwesome
qui représente réellement la vue textuelle de FontAwesome
comme ceci.
public class FontAwesome extends TextView {
public FontAwesome(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public FontAwesome(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FontAwesome(Context context) {
super(context);
init();
}
private void init() {
//Font name should not contain "/".
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"fontawesome.ttf");
setTypeface(tf);
}
}
vous pouvez maintenant utiliser la classe Fontawesome selon vos besoins et également suivre la feuille de triche . pour obtenir le code Unicode de votre icône.
Donc, votre textview sera comme ça.
<PACKAGE_NAME.Fontawesome
Android:id="@+id/userLogin"
Android:text=" Login Now"
Android:clickable="true"
Android:onClick="login"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
Voici les étapes à suivre:
public class FontManager {
public static final String ROOT = "fonts/",
FONTAWESOME = ROOT + "fontawesome-webfont.ttf";
public static Typeface getTypeface(Context context, String font) {
return Typeface.createFromAsset(context.getAssets(), font);
}
}
4. Maintenant, utilisez la police awesome pour votre textview en utilisant le code ci-dessous
Typeface iconFont = FontManager.getTypeface(getApplicationContext(), FontManager.FONTAWESOME);
tvIcon1 = (TextView) findViewById(R.id.tvIcon1);
tvIcon2 = (TextView) findViewById(R.id.tvIcon2);
tvIcon3 = (TextView) findViewById(R.id.tvIcon3);
tvIcon1.setTypeface(iconFont);
tvIcon2.setTypeface(iconFont);
tvIcon3.setTypeface(iconFont);
Vous pouvez obtenir le code source complet dans mon article de blog ici .
Vous pouvez utiliser FontAwesome , simplement déclarer dans String.xml
<resources>
<string name="fa_icon_areachart"></string>
<string name="fa_icon_piechart"></string>
<string name="fa_icon_linechart"></string>
</resources>
Vous pouvez également importer les images vectorielles brutes de Font Awesome et les importer en tant que dessinables dans votre projet à l'aide de la création d'un nouvel actif vectoriel dans Android Studio:
Allez dans le dossier où vous avez installé Font Awesome
...../fontawesome-pro-version #/advanced-options/raw-svg
Vous y trouverez 4 dossiers: marques, léger, régulier et solide.
Toutes les icônes sont disponibles sous forme d'images vectorielles séparées dans ces 4 dossiers
Pour importer une icône, accédez à la liste des ressources, cliquez avec le bouton droit de la souris et sélectionnez Nouveau -> Actif vectoriel. Un dialogue s'ouvrira. Sélectionnez Fichier local en tant qu'option, puis sélectionnez l'image vectorielle à importer (chemin). Le nom de l'image sera soustrait du fichier image.
Et ensuite, vous pourrez résoudre votre problème simplement en utilisant un TextView composé, à peu près comme ceci:
<TextView
Android:drawableStart="@drawable/my_imported_fontawesome_login_icon"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Login Now"
Android:gravity="center_vertical"/>
L’un des avantages de cette solution est qu’il vous suffit d’importer les icônes dont vous avez réellement besoin, sans les frais généraux associés à une police complète, voire davantage, car elles sont réparties sur 4 polices.
Code similaire, mais petit changement.
Utilisez AppCompatTextView, car lorsque vous utilisez TextView, vous recevrez un avertissement comme celui-ci:
Cette vue personnalisée devrait plutôt étendre Android.support.v7.widget.AppCompatTextView
Si gentiment utilisez AppCompatTextView. Ce sera mieux si vous utilisez AppCompatTextView au lieu de TextView:
import Android.graphics.Typeface;
import Android.support.v7.widget.AppCompatTextView;
import Android.content.Context;
import Android.util.AttributeSet;
public class FontAwesome extends AppCompatTextView{
public FontAwesome(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public FontAwesome(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FontAwesome(Context context) {
super(context);
init();
}
private void init() {
//Font name should not contain "/".
Typeface tf = Typeface.createFromAsset(getContext().getAssets(),
"fontawesome.ttf");
setTypeface(tf);
}
}
En utilisant Typeface, vous pouvez le définir directement par code
mTypeFace = FontCache.get("font/GFont.ttf", getActivity());
mButtonQkView.setTypeface(mTypeFace);
mButtonQkView.setText(String.valueOf((char) 0xe907));
Pour définir l’icône de police comme pouvant être laissée à la gauche, commencez par générer l’icône pouvant être dessinée à l’aide de la classe TextDrawable
TextDrawable gIcon = new TextDrawable(this);
gIcon.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
gIcon.setTextAlign(Layout.Alignment.ALIGN_CENTER);
gIcon.setTypeface(FontCache.get(getString(R.string.icomoon), this));
gIcon.setText(String.valueOf((char) 0xe907));
gIcon.setTextColor(getResources().getColor(color));
Et définissez-le comme pouvant être dessiné à gauche
mButtonQkView.setCompoundDrawablesWithIntrinsicBounds(gIcon, null, null, null);
Le code de la classe TextDrawable
public class TextDrawable extends Drawable {
/* Platform XML constants for typeface */
private static final int SANS = 1;
private static final int SERIF = 2;
private static final int MONOSPACE = 3;
/* Attribute lists to pull default values from the current theme */
private static final int[] themeAttributes = {
Android.R.attr.textAppearance
};
private static final int[] appearanceAttributes = {
Android.R.attr.textSize,
Android.R.attr.typeface,
Android.R.attr.textStyle,
Android.R.attr.textColor
};
/* Resources for scaling values to the given device */
private Resources mResources;
/* Paint to hold most drawing primitives for the text */
private TextPaint mTextPaint;
/* Layout is used to measure and draw the text */
private StaticLayout mTextLayout;
/* Alignment of the text inside its bounds */
private Layout.Alignment mTextAlignment = Layout.Alignment.ALIGN_NORMAL;
/* Optional path on which to draw the text */
private Path mTextPath;
/* Stateful text color list */
private ColorStateList mTextColors;
/* Container for the bounds to be reported to widgets */
private Rect mTextBounds;
/* Text string to draw */
private CharSequence mText = "";
public TextDrawable(Context context) {
super();
//Used to load and scale resource items
mResources = context.getResources();
//Definition of this drawables size
mTextBounds = new Rect();
//Paint to use for the text
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.density = mResources.getDisplayMetrics().density;
mTextPaint.setDither(true);
int textSize = 15;
ColorStateList textColor = null;
int styleIndex = -1;
int typefaceIndex = -1;
//Set default parameters from the current theme
TypedArray a = context.getTheme().obtainStyledAttributes(themeAttributes);
int appearanceId = a.getResourceId(0, -1);
a.recycle();
TypedArray ap = null;
if (appearanceId != -1) {
ap = context.obtainStyledAttributes(appearanceId, appearanceAttributes);
}
if (ap != null) {
for (int i = 0; i < ap.getIndexCount(); i++) {
int attr = ap.getIndex(i);
switch (attr) {
case 0: //Text Size
textSize = a.getDimensionPixelSize(attr, textSize);
break;
case 1: //Typeface
typefaceIndex = a.getInt(attr, typefaceIndex);
break;
case 2: //Text Style
styleIndex = a.getInt(attr, styleIndex);
break;
case 3: //Text Color
textColor = a.getColorStateList(attr);
break;
default:
break;
}
}
ap.recycle();
}
setTextColor(textColor != null ? textColor : ColorStateList.valueOf(0xFF000000));
setRawTextSize(textSize);
Typeface tf = null;
switch (typefaceIndex) {
case SANS:
tf = Typeface.SANS_SERIF;
break;
case SERIF:
tf = Typeface.SERIF;
break;
case MONOSPACE:
tf = Typeface.MONOSPACE;
break;
}
setTypeface(tf, styleIndex);
}
/**
* Return the text currently being displayed
*/
public CharSequence getText() {
return mText;
}
/**
* Set the text that will be displayed
* @param text Text to display
*/
public void setText(CharSequence text) {
if (text == null) text = "";
mText = text;
measureContent();
}
/**
* Return the current text size, in pixels
*/
public float getTextSize() {
return mTextPaint.getTextSize();
}
/**
* Set the text size. The value will be interpreted in "sp" units
* @param size Text size value, in sp
*/
public void setTextSize(float size) {
setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}
/**
* Set the text size, using the supplied complex units
* @param unit Units for the text size, such as dp or sp
* @param size Text size value
*/
public void setTextSize(int unit, float size) {
float dimension = TypedValue.applyDimension(unit, size,
mResources.getDisplayMetrics());
setRawTextSize(dimension);
}
/*
* Set the text size, in raw pixels
*/
private void setRawTextSize(float size) {
if (size != mTextPaint.getTextSize()) {
mTextPaint.setTextSize(size);
measureContent();
}
}
/**
* Return the horizontal stretch factor of the text
*/
public float getTextScaleX() {
return mTextPaint.getTextScaleX();
}
/**
* Set the horizontal stretch factor of the text
* @param size Text scale factor
*/
public void setTextScaleX(float size) {
if (size != mTextPaint.getTextScaleX()) {
mTextPaint.setTextScaleX(size);
measureContent();
}
}
/**
* Return the current text alignment setting
*/
public Layout.Alignment getTextAlign() {
return mTextAlignment;
}
/**
* Set the text alignment. The alignment itself is based on the text layout direction.
* For LTR text NORMAL is left aligned and OPPOSITE is right aligned.
* For RTL text, those alignments are reversed.
* @param align Text alignment value. Should be set to one of:
*
* {@link Layout.Alignment#ALIGN_NORMAL},
* {@link Layout.Alignment#ALIGN_NORMAL},
* {@link Layout.Alignment#ALIGN_OPPOSITE}.
*/
public void setTextAlign(Layout.Alignment align) {
if (mTextAlignment != align) {
mTextAlignment = align;
measureContent();
}
}
/**
* Sets the typeface and style in which the text should be displayed,
* and turns on the fake bold and italic bits in the Paint if the
* Typeface that you provided does not have all the bits in the
* style that you specified.
*
*/
private void setTypeface(Typeface tf, int style) {
if (style > 0) {
if (tf == null) {
tf = Typeface.defaultFromStyle(style);
} else {
tf = Typeface.create(tf, style);
}
setTypeface(tf);
// now compute what (if any) algorithmic styling is needed
int typefaceStyle = tf != null ? tf.getStyle() : 0;
int need = style & ~typefaceStyle;
mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0);
mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
} else {
mTextPaint.setFakeBoldText(false);
mTextPaint.setTextSkewX(0);
setTypeface(tf);
}
}
/**
* Return the current typeface and style that the Paint
* using for display.
*/
public Typeface getTypeface() {
return mTextPaint.getTypeface();
}
/**
* Sets the typeface and style in which the text should be displayed.
* Note that not all Typeface families actually have bold and italic
* variants, so you may need to use
* {@link #setTypeface(Typeface, int)} to get the appearance
* that you actually want.
*/
public void setTypeface(Typeface tf) {
if (mTextPaint.getTypeface() != tf) {
mTextPaint.setTypeface(tf);
measureContent();
}
}
/**
* Set a single text color for all states
* @param color Color value such as {@link Color#WHITE} or {@link Color#argb(int, int, int, int)}
*/
public void setTextColor(int color) {
setTextColor(ColorStateList.valueOf(color));
}
/**
* Set the text color as a state list
* @param colorStateList ColorStateList of text colors, such as inflated from an R.color resource
*/
private void setTextColor(ColorStateList colorStateList) {
mTextColors = colorStateList;
updateTextColors(getState());
}
/**
* Optional Path object on which to draw the text. If this is set,
* TextDrawable cannot properly measure the bounds this drawable will need.
* You must call {@link #setBounds(int, int, int, int) setBounds()} before
* applying this TextDrawable to any View.
*
* Calling this method with <code>null</code> will remove any Path currently attached.
*/
public void setTextPath(Path path) {
if (mTextPath != path) {
mTextPath = path;
measureContent();
}
}
/**
* Internal method to take measurements of the current contents and apply
* the correct bounds when possible.
*/
private void measureContent() {
//If drawing to a path, we cannot measure intrinsic bounds
//We must resly on setBounds being called externally
if (mTextPath != null) {
//Clear any previous measurement
mTextLayout = null;
mTextBounds.setEmpty();
} else {
//Measure text bounds
double desired = Math.ceil(Layout.getDesiredWidth(mText, mTextPaint));
mTextLayout = new StaticLayout(mText, mTextPaint, (int) desired,
mTextAlignment, 1.0f, 0.0f, false);
mTextBounds.set(0, 0, mTextLayout.getWidth(), mTextLayout.getHeight());
}
//We may need to be redrawn
invalidateSelf();
}
/**
* Internal method to apply the correct text color based on the drawable's state
*/
private boolean updateTextColors(int[] stateSet) {
int newColor = mTextColors.getColorForState(stateSet, Color.WHITE);
if (mTextPaint.getColor() != newColor) {
mTextPaint.setColor(newColor);
return true;
}
return false;
}
@Override
protected void onBoundsChange(Rect bounds) {
//Update the internal bounds in response to any external requests
mTextBounds.set(bounds);
}
@Override
public boolean isStateful() {
/*
* The drawable's ability to represent state is based on
* the text color list set
*/
return mTextColors.isStateful();
}
@Override
protected boolean onStateChange(int[] state) {
//Upon state changes, grab the correct text color
return updateTextColors(state);
}
@Override
public int getIntrinsicHeight() {
//Return the vertical bounds measured, or -1 if none
if (mTextBounds.isEmpty()) {
return -1;
} else {
return (mTextBounds.bottom - mTextBounds.top);
}
}
@Override
public int getIntrinsicWidth() {
//Return the horizontal bounds measured, or -1 if none
if (mTextBounds.isEmpty()) {
return -1;
} else {
return (mTextBounds.right - mTextBounds.left);
}
}
@Override
public void draw(@NonNull Canvas canvas) {
final Rect bounds = getBounds();
final int count = canvas.save();
canvas.translate(bounds.left, bounds.top);
if (mTextPath == null) {
//Allow the layout to draw the text
mTextLayout.draw(canvas);
} else {
//Draw directly on the canvas using the supplied path
canvas.drawTextOnPath(mText.toString(), mTextPath, 0, 0, mTextPaint);
}
canvas.restoreToCount(count);
}
@Override
public void setAlpha(int alpha) {
if (mTextPaint.getAlpha() != alpha) {
mTextPaint.setAlpha(alpha);
}
}
@Override
public int getOpacity() {
return mTextPaint.getAlpha();
}
@Override
public void setColorFilter(ColorFilter cf) {
if (mTextPaint.getColorFilter() != cf) {
mTextPaint.setColorFilter(cf);
}
}
}