如何在android应用程序中使用Font Awesome图标?

时间:2016-06-22 06:01:46

标签: android textview

我想在我的Android应用程序中使用Font Awesome的图标集。我有一些TextView来设置这些图标。我不想使用任何png图像。我的Textview就是这样 - >

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

不,我想在“立即登录”文本前添加一个图标。怎么做?

11 个答案:

答案 0 :(得分:12)

您可以关注此answer

首先从here下载fontawesome.ttf。并将文件放在 asset / fontawesome.ttf

然后创建一个FontAwesome类,它实际上代表FontAwesome的文本视图。

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);
    }

}

现在您可以根据需要使用Fontawesome类,并按照cheatsheet.获取图标的Unicode。

所以,你的textview会是这样的。

<PACKAGE_NAME.Fontawesome
    android:id="@+id/userLogin"
    android:text="&#xf007;  Login Now"
    android:clickable="true"
    android:onClick="login"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

答案 1 :(得分:6)

以下是要遵循的步骤:

  1. 首先从这里下载font-awesome:http://fontawesome.io/
  2. 创建资源文件夹并将fontawesome-webfont.ttf添加到此文件夹
  3. 通过以下代码创建一个帮助程序类:
  4. 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。现在使用下面的代码

    对您的textview使用字体真棒
    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);
    

    您可以在我的博文here中获取完整的源代码。

答案 2 :(得分:4)

您可以使用FontAwesome,只需在String.xml中声明

<resources>
    <string name="fa_icon_areachart">&#xf1fe;</string>
    <string name="fa_icon_piechart">&#xf200;</string>
    <string name="fa_icon_linechart">&#xf201;</string>
</resources>

答案 3 :(得分:2)

您还可以从Font Awesome导入原始矢量图像,并在Android Studio中创建新的Vector Asset的帮助下将它们作为drawable导入:

转到已安装Font Awesome

的文件夹

..... / fontawesome-PRO-版本#/高级选项/原始SVG

在那里你会找到4个文件夹:品牌,灯光,常规和实体。

所有图标均可在这4个文件夹中作为分隔的矢量图像使用

要导入图标,请转到资源,右键单击并选择新建 - &gt;矢量资产。将打开一个对话框。选择“本地文件”作为选项,然后选择要导入的矢量图像(路径)。将从图像文件中减去图像的名称。

然后您可以通过简单地使用复合TextView解决您的问题,如下所示:

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

此解决方案的一个优点是,您只需要导入您真正需要的图标,而不需要完整或更多字体的开销,因为图标分为4种字体。

答案 4 :(得分:1)

由于在我的Android项目中没有真正舒适的方法来包含FontAwesome

我创建了一个Github Repository,该帮助使用FontAwesome和 Kotlin而非Java

存储库可帮助您动态在FontAwesome类型(solidregularbrands)之间进行切换。动态示例(see code):


资源


我从这里的所有答案中学到了很多东西,所以谢谢大家!我希望这个答案对您也有帮助!

答案 5 :(得分:1)

如果有人想以编程方式分配字体值,那么我就是这样做的。 创建资产文件夹(如果不存在),然后将ttf文件放入文件夹

Typeface type = Typeface.createFromAsset(getContext().getAssets(), "fonts/fa_solid_900.ttf");
tvHeart.setTypeface(type);
tvHeart.setText(Html.fromHtml("&#xf004;"));

答案 6 :(得分:1)

  1. 首先创建您的字体资源目录

    1. 右键点击 res 文件夹,然后转到新建 > Android 资源目录
    2. 资源类型列表中,选择字体,然后点击确定
    3. 查看this guide了解更多详情
  2. 下载 FontAwesome TTF 文件

  3. font 文件夹中添加您的字体文件

    1. 右键单击字体文件夹,然后转到在资源管理器中显示
    2. 将所需的 TTF 文件移动到此文件夹
  4. 创建您的图标字典:

    1. 右键单击 values 资源文件夹,然后转到在资源管理器中显示
    2. XML Files 移动到此文件夹:
      • 品牌图标 XML:strings_fa_brands.xml
      • 常规图标的 XML:strings_fa_regular.xml
      • 实体图标的 XML:strings_fa_solid.xml
    3. 或者选中 FontAwesome Cheatsheet 以创建您自己的 XML,XML 将如下所示:
    <resources>
       <string name="fa_regular_sun">&#xf185;</string>
       <string name="fa_regular_surprise">&#xf5c2;</string>
       <string name="fa_regular_thumbs_up">&#xf164;</string>
    </resources>
    
  5. 在布局 XML 文件中,将 textfontFamily 属性设置为您想要的图标

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/fa_regular_thumbs_up"
            android:fontFamily="@font/fa-regular-400"/>
    

答案 7 :(得分:0)

使用Typeface,您可以直接通过代码

进行设置
  mTypeFace = FontCache.get("font/GFont.ttf", getActivity());
  mButtonQkView.setTypeface(mTypeFace);
  mButtonQkView.setText(String.valueOf((char) 0xe907));

要将字体图标设置为Leftdrawable,首先使用TextDrawable类从字体图标生成drawable

        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));

并将其设置为左侧可绘制

mButtonQkView.setCompoundDrawablesWithIntrinsicBounds(gIcon, null, null, null);

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);
    }
}

}

答案 8 :(得分:0)

类似的代码,但是变化很小。

使用AppCompatTextView,因为当您使用TextView时,会收到如下警告:

  

此自定义视图应改为扩展android.support.v7.widget.AppCompatTextView

因此,请使用AppCompatTextView。如果使用AppCompatTextView而不是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);
    }
}

答案 9 :(得分:0)

以前的情况还可以,但是可以想象您需要基于从api获得的数据动态生成的菜单项。 在获取页面模型之前,我们现在不应该在每个项目中使用确切的图标。 当然,我们可以像前面所示那样将所有FA图标放入String资源,但是也可以按名称插入FA图标

开始吧

  1. 添加FA字体库: 实施'com.mikepenz:fontawesome-typeface:5.9.0.0-kotlin@aar'

  2. 添加ext lib图标:
    实施“ com.mikepenz:iconics-core:4.0.2”

  3. 执行验证码(kotlin):

     //add class property in your activity
     private lateinit var navView: NavigationView
    
     //find your navigation view on activity onCreate
     navView = findViewById(R.id.event_details_nav_view)
    
     //call your updateNavigation(pages) function when you received data with menu items. i.e. Page is a data object with Id, Name, faIcon (it's name)
    
     //add function where we create menu items based on pages model
     fun updateNavigation(pages: List<Page>) {
         pages.forEach {
                     navView.menu.add(0, it.id, 0, it.name)
                         .apply {
                             IconsHelper.getFontAwesomeIcon(
                                 this,
                                 name,
                                 24,
                                 R.color.nav_drawer_item_icon_color_default
                            ).let {
                                menuItem.icon = it
                            }
                         }
                 }
      }
    

所有的魔力都在IconHelper中,让我们开始吧

//添加IconHelper.kt并将其粘贴在那里

import android.content.Context
import com.mikepenz.iconics.Iconics.findFont
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp


object IconsHelper {
private const val defaultIconName = "faw_question_circle"

fun getFontAwesomeIcon(context: Context, name: String, size: Int, color: Int): IconicsDrawable {
    return when(name.isEmpty()) {
        true ->
            getIcon(defaultIconName, size, color, context)

        false -> {
            normalizeIconName(name)
                .let {
                    when(iconExists(context, it)) {
                        true ->
                            getIcon(it, size, color, context)

                        false ->
                            getIcon(IconsHelper.defaultIconName, size, color, context)
                    }
                }
        }
    }
}

private fun getIcon(name: String, size: Int, color: Int, context: Context): IconicsDrawable {
    return IconicsDrawable(context, name)
        .apply {
            sizeDp(size)
            colorInt(color)
        }
}

private fun normalizeIconName(name: String): String {
    name
        .replaceFirst("fa", "faw")
        .replace("-", "_")
        .let {
            return when(it.contains("sliders")) {
                true ->
                    "faw_sliders_h"
                false ->
                    it
            }
        }
}

private fun iconExists(context: Context, icon: String): Boolean {
    try {
        findFont(icon.substring(0, 3), context)
            .let {
                it!!.getIcon(icon)
            }
        return true
    } catch (e: Exception) {
        print(e)
    }

    return false
}

}

p.s。看一下normalizeIconName()函数,也许您不需要它。

答案 10 :(得分:0)

首先,在 build.gradle 中包含 fontawesome 并同步您的项目。

dependencies {
// font awesome
implementation 'info.androidhive:fontawesome:0.0.5'
}

使用它?

<info.androidhive.fontawesome.FontTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/fa_calendar_check_solid"
            android:textColor="@color/icon_color"
            android:textSize="@dimen/icon_size"
            app:solid_icon="true" />

solid_icon: 要显示实心图标,请将此值设置为 true。 brand_icon: 要显示品牌图标,请将此值设置为 true。