এক্সএমএল ব্যবহার করে অ্যান্ড্রয়েড টেক্সটভিউতে কাস্টম ফন্ট ব্যবহার করা


93

আমি আমার সম্পদ / ফন্ট ফোল্ডারে একটি কাস্টম ফন্ট ফাইল যুক্ত করেছি। আমি কীভাবে এটি আমার এক্সএমএল থেকে ব্যবহার করব?

আমি কোড থেকে এটি ব্যবহার করতে পারি:

TextView text = (TextView) findViewById(R.id.textview03);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Molot.otf");
text.setTypeface(tf);

আমি কোনও android:typeface="/fonts/Molot.otf"অ্যাট্রিবিউট ব্যবহার করে এটি এক্সএমএল থেকে করতে পারি না ?


আমি এটি অনেক অনুসন্ধান করেছি এবং এক্সএমএল থেকে এটি করার কোনও উপায় নেই।
সিডি

4
পোস্টটি চেক আউট চেষ্টা stackoverflow.com/questions/2376250/...
dor506

এই উত্তরটি একবার দেখুন ! এটি আপনাকে একাধিক ফন্ট এবং এক্সএমএল ব্যবহার করতে দেয়।
রাফা0809

যেমন অন্যান্য বলেছেন নমুনা, আপনি এটি অর্জনের জন্য ক্যালিগ্রাফি ব্যবহার করতে পারেন ।
mbonnin

এই নিবন্ধটি দেখুন gadgetsaint.com/tips/…
এএসপি

উত্তর:


45

সংক্ষিপ্ত উত্তর: নং অ্যান্ড্রয়েডের এক্সএমএল এর মাধ্যমে পাঠ্য উইজেটে কাস্টম ফন্টগুলি প্রয়োগ করার জন্য অন্তর্নির্মিত সমর্থন নেই।

তবে, এমন একটি কাজ রয়েছে যা বাস্তবায়ন করা মারাত্মকভাবে কঠিন নয়।

প্রথম

আপনার নিজের স্টাইলযোগ্য সংজ্ঞা দিতে হবে। আপনার / res / মান ফোল্ডারে, attrs.xML ফাইলটি খুলুন / তৈরি করুন এবং এর মতো একটি ঘোষিত-স্টাইলযোগ্য বস্তু যুক্ত করুন:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="FontText">
        <attr name="typefaceAsset" format="string"/>
    </declare-styleable>
</resources>

দ্বিতীয়

ধরে নিই যে আপনি এই উইজেটটি প্রায়শই ব্যবহার করতে চান, আপনার বোঝা Typefaceবস্তুগুলির জন্য একটি সাধারণ ক্যাশে সেট আপ করা উচিত , কারণ ফ্লাইতে মেমরি থেকে এগুলি লোড করতে সময় নিতে পারে। কিছুটা এইরকম:

public class FontManager {
    private static FontManager instance;

    private AssetManager mgr;

    private Map<String, Typeface> fonts;

    private FontManager(AssetManager _mgr) {
        mgr = _mgr;
        fonts = new HashMap<String, Typeface>();
    }

    public static void init(AssetManager mgr) {
        instance = new FontManager(mgr);
    }

    public static FontManager getInstance() {
        if (instance == null) {
            // App.getContext() is just one way to get a Context here
            // getContext() is just a method in an Application subclass
            // that returns the application context
            AssetManager assetManager = App.getContext().getAssets();
            init(assetManager);
        }
        return instance;
    }

    public Typeface getFont(String asset) {
        if (fonts.containsKey(asset))
            return fonts.get(asset);

        Typeface font = null;

        try {
            font = Typeface.createFromAsset(mgr, asset);
            fonts.put(asset, font);
        } catch (Exception e) {

        }

        if (font == null) {
            try {
                String fixedAsset = fixAssetFilename(asset);
                font = Typeface.createFromAsset(mgr, fixedAsset);
                fonts.put(asset, font);
                fonts.put(fixedAsset, font);
            } catch (Exception e) {

            }
        }

        return font;
    }

    private String fixAssetFilename(String asset) {
        // Empty font filename?
        // Just return it. We can't help.
        if (TextUtils.isEmpty(asset))
            return asset;

        // Make sure that the font ends in '.ttf' or '.ttc'
        if ((!asset.endsWith(".ttf")) && (!asset.endsWith(".ttc")))
            asset = String.format("%s.ttf", asset);

        return asset;
    }
}

এইটি আপনাকে .ttc ফাইল এক্সটেনশানগুলি ব্যবহার করার অনুমতি দেবে, তবে এটি নিরীক্ষিত।

তৃতীয়

একটি নতুন ক্লাস তৈরি করুন যা সাবক্লাস করে TextView। এই নির্দিষ্ট উদাহরণটি নির্ধারিত এক্সএমএল টাইপফেস ( bold, italicইত্যাদি) বিবেচনা করে এবং এটি ফন্টে প্রয়োগ করে (ধরে নিবেন আপনি একটি .ttc ফাইল ব্যবহার করছেন)।

/**
 * TextView subclass which allows the user to define a truetype font file to use as the view's typeface.
 */
public class FontText extends TextView {
    public FontText(Context context) {
        this(context, null);
    }

    public FontText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FontText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        if (isInEditMode())
            return;

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FontText);

        if (ta != null) {
            String fontAsset = ta.getString(R.styleable.FontText_typefaceAsset);

            if (!TextUtils.isEmpty(fontAsset)) {
                Typeface tf = FontManager.getInstance().getFont(fontAsset);
                int style = Typeface.NORMAL;
                float size = getTextSize();

                if (getTypeface() != null)
                    style = getTypeface().getStyle();

                if (tf != null)
                    setTypeface(tf, style);
                else
                    Log.d("FontText", String.format("Could not create a font from asset: %s", fontAsset));
            }
        }
    }
}

অবশেষে

TextViewআপনার এক্সএমএল এর উদাহরণগুলি পুরোপুরি যোগ্যতাসম্পন্ন শ্রেণীর নামের সাথে প্রতিস্থাপন করুন । আপনার কাস্টম নেমস্পেসটি ঠিক যেমন আপনার অ্যান্ড্রয়েড নেমস্পেসের মতো ঘোষণা করুন। নোট করুন যে "টাইপফেসএসেট" আপনার / সম্পত্তির ডিরেক্টরিতে থাকা একটি .ttf বা .ttc ফাইলকে নির্দেশ করবে।

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.FontText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is a custom font text"
        custom:typefaceAsset="fonts/AvenirNext-Regular.ttf"/>
</RelativeLayout>

দুর্দান্ত উত্তর! যদিও একটি প্রশ্ন: আপনি আইডিএডিটমোডের সময় কেন ফিরে এসেছিলেন?
আভি শুক্রন

04-11 18: 18: 32.685 3506-3506 / com.example.demo ই / অ্যান্ড্রয়েড রুনটাইম ﹕ চূড়ান্ত ছাড়: মূল প্রক্রিয়া: com.example.demo, PID: 3506 android.view.InflateException: বাইনারি এক্সএমএল ফাইল লাইন # 2: ত্রুটি অ্যান্ড্রয়েড.ভিউ.লয়েআউটআইন্টারফ্ল্যাটার.জাভা: 20২০) এ অ্যান্ড্রয়েড.ভিউ.লাইআউটআইলেটফ্রেটার.ক্রিয়াভিউফ্রোমটাগ (লেআউটআইনফ্লেটার.এলআউট.আইটি.আইইএইচ.আর.ইট.ইইক.আইটি.এইচ.আর.ইট.আইটি.এইচআরআইটি.এইচআরএইচআইআরএইচআইআরএইচআইআরএইচআরএফ.এল.আর.আই.এফ.এল.আইটি.এইচআরএফ.এল.আই.এফ.আর.ইট.এইচআরএফ.এল.আইআরএফ্লাইটার LayoutInflater.java:469) at android.view.LayoutInflater.inflate (
LayoutInflater.java:397

@ অভ্রাহামশোক্রন - এটি সেখানে আছে কারণ আমি পূর্বরূপ মোডে থাকাকালীন অ্যান্ড্রয়েড স্টুডিওতে ত্রুটি পেতে থাকি (সম্ভবত কারণ এটি কোনও কাস্টম টাইপফেস প্রয়োগ করার পদ্ধতি জানে না।
থিমারশাল

যোগ করা এক্সএমএনএলএস: কাস্টম = " স্কিমাস.অ্যান্ড্রয়েড.com/ টলস " রিলেটিভলয়েউটে এবং ত্রুটিটি চলে গেছে। ধন্যবাদ মানুষ
নাভিদ আহমদ

4
হ্যালো @ থিমারশাল: এক্সএমএলএন এর পরিবর্তে: কাস্টম = " স্কিমাস.অ্যান্ড্রয়েড.com/tools " আপনার ব্যবহার করা উচিত: xmlns: কাস্টম = " স্কিমাস.অ্যান্ড্রয়েড. com/apk/res- auto " স্টাইলযোগ্য বৈশিষ্ট্যগুলি ব্যবহার করতে।
অভিনব সাক্সেনা

28

এখানে উদাহরণ কোড রয়েছে যা এটি করে। আমার ফন্ট স্থিতিশীল চূড়ান্ত ভেরিয়েবলে সংজ্ঞায়িত হয়েছে এবং ফন্ট ফাইলটি সম্পদ ডিরেক্টরিতে রয়েছে।

public class TextViewWithFont extends TextView {

    public TextViewWithFont(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setTypeface(MainActivity.typeface);
    }

    public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.setTypeface(MainActivity.typeface);
    }

    public TextViewWithFont(Context context) {
        super(context);
        this.setTypeface(MainActivity.typeface);
    }

}

5
ওপিতে বিশেষভাবে বলা হয়েছে যে তিনি কীভাবে ফন্টটি অগ্রগতিতে সেট করতে জানেন (তিনি এমনকি একটি উদাহরণও সরবরাহ করেন)। প্রশ্নটি কীভাবে এক্সএমএলে ফন্ট সেট করবেন?
এসএমবিগস

13

আপনি যে ফন্টটি ব্যবহার করতে চান তার সাথে যুক্ত করুন আপনার গ্রাফিক টেক্সটভিউ Create এই শ্রেণিতে আমি টাইপফেসটি ক্যাশে করতে একটি স্ট্যাটিক এমটাইপেস ক্ষেত্র ব্যবহার করি (আরও ভাল পারফরম্যান্সের জন্য)

public class HeliVnTextView extends TextView {

/*
 * Caches typefaces based on their file path and name, so that they don't have to be created every time when they are referenced.
 */
private static Typeface mTypeface;

public HeliVnTextView(final Context context) {
    this(context, null);
}

public HeliVnTextView(final Context context, final AttributeSet attrs) {
    this(context, attrs, 0);
}

public HeliVnTextView(final Context context, final AttributeSet attrs, final int defStyle) {
    super(context, attrs, defStyle);

     if (mTypeface == null) {
         mTypeface = Typeface.createFromAsset(context.getAssets(), "HelveticaiDesignVnLt.ttf");
     }
     setTypeface(mTypeface);
}

}

এক্সএমএল ফাইলে:

<java.example.HeliVnTextView
        android:id="@+id/textView1"
        android:layout_width="0dp"
        ... />

জাভা ক্লাসে:

HeliVnTextView title = new HeliVnTextView(getActivity());
title.setText(issue.getName());

11

ক্রিয়াকলাপ লেআউটআইনফ্লেটার.ফ্যাক্টরি 2 প্রয়োগ করে যা প্রতিটি তৈরি ভিউতে কলব্যাক সরবরাহ করে। কাস্টম ফন্ট ফ্যামিলি অ্যাট্রিবিউটের সাথে টেক্সটভিউকে স্টাইল করা, চাহিদা অনুযায়ী টাইপফেসগুলি লোড করা এবং ইনস্ট্যান্টিয়েটেড টেক্সট দর্শনগুলিতে সেট টাইপফেসটি স্বয়ংক্রিয়ভাবে কল করা সম্ভব।

দুর্ভাগ্যক্রমে ক্রিয়াকলাপ এবং উইন্ডোজের তুলনায় ইনফ্ল্যাটারের উদাহরণগুলির আর্কিটেকচারাল সম্পর্কের কারণে অ্যান্ড্রয়েডে কাস্টম ফন্টগুলি ব্যবহার করার সহজ পদ্ধতির হ'ল অ্যাপ্লিকেশন স্তরের লোডযুক্ত ফন্টগুলি ক্যাশে করা।

নমুনা কোড বেস এখানে:

https://github.com/leok7v/android-textview-custom-fouts

  <style name="Baroque" parent="@android:style/TextAppearance.Medium">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textColor">#F2BAD0</item>
    <item name="android:textSize">14pt</item>
    <item name="fontFamily">baroque_script</item>
  </style>

  <?xml version="1.0" encoding="utf-8"?>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:custom="http://schemas.android.com/apk/res/custom.fonts"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
  >
  <TextView
    style="@style/Baroque"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/sample_text"
  />

ফলাফল স্বরূপ

এখানে চিত্র বর্ণনা লিখুন


2 বছর ধরে এই কোডটি স্পর্শ করেনি। তবে এটা করা উচিত। থিওরীতে এটিকে প্রতিরোধ করার মতো কিছুই দেখছি না।
লিও

7

এক্সএমএলে কাস্টম ফন্টগুলি ব্যবহার করা ভাল ধারণা নয় কারণ এটি হ'ল মেমরি ফাঁস এড়াতে আপনাকে প্রোগ্রামক্রমে এটি করতে হবে!


6
এটি আইসক্রিম স্যান্ডউইচ মধ্যে মেমরি ফাঁস স্থির ছিল উপস্থিত হয়।
মাইকেল শ্যাপার

4
মেমরি ফাঁস এড়াতে আপনার টাইপড্রাই পদ্ধতি পুনর্ব্যবহার করা () ব্যবহার করা উচিত।
অভিনব সাক্সেনা

7

আপডেট: https://github.com/chrisjenx/ ক্যালিগ্রাফি এটির জন্য একটি সর্বোত্তম সমাধান বলে মনে হয়।


আপনার অ্যাপ্লিকেশনটি তৈরি হওয়ার সময় আপনি উপলব্ধ ফন্টগুলির স্থির তালিকায় আপনার ফন্টটি ইনজেকশন / হ্যাক করতে প্রতিবিম্বটি ব্যবহার করতে পারেন ? আমি যদি অন্যদের কাছ থেকে প্রতিক্রিয়া জানাতে আগ্রহী তবে যদি এটি সত্যই, সত্যিই খারাপ ধারণা হয় বা যদি এটি দুর্দান্ত সমাধান হয় - মনে হয় এটি সেই চূড়ান্তগুলির মধ্যে একটি হতে চলেছে ...

আমি নিজের কাস্টম টাইপফেসটি আমার নিজের ফন্ট পরিবারের নামের সাথে সিস্টেম টাইপফেসগুলির তালিকায় ইনজেকশনে সক্ষম হয়েছি, তারপরে সেই কাস্টম ফন্ট পরিবারের নাম ("ব্রাশ-স্ক্রিপ্ট") কে অ্যান্ড্রয়েডের মান হিসাবে উল্লেখ করেছি : ফন্টফ্যামিলি একটি স্ট্যান্ডার্ড টেক্সটভিউতে আমার এলজিতে কাজ করেছিল জি 4 চলমান অ্যান্ড্রয়েড 6.0।

public class MyApplication extends android.app.Application
{
    @Override
    public void onCreate()
    {
        super.onCreate();

        Typeface font = Typeface.createFromAsset(this.getResources().getAssets(),"fonts/brush-script.ttf");
        injectTypeface("brush-script", font);
    }

    private boolean injectTypeface(String fontFamily, Typeface typeface)
    {
        try
        {
            Field field = Typeface.class.getDeclaredField("sSystemFontMap");
            field.setAccessible(true);
            Object fieldValue = field.get(null);
            Map<String, Typeface> map = (Map<String, Typeface>) fieldValue;
            map.put(fontFamily, typeface);
            return true;
        }
        catch (Exception e)
        {
            Log.e("Font-Injection", "Failed to inject typeface.", e);
        }
        return false;
    }
}

আমার লেআউটে

<TextView
    android:id="@+id/name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Fancy Text"
    android:fontFamily="brush-script"/>

আমার জন্য কাজ করে না, আপনি কীভাবে এটি ব্যবহার করবেন তা আরও বিশদ দিতে পারেন? না MyApplicationবর্গ চাহিদা বলা হবে?
দাদান

@ ইয়াউজকে আপনার প্রয়োগে অন্তত একবার ইনজেক্ট টাইপফেস পদ্ধতিটি কল করতে হবে। যদি এটি ব্যতিক্রম লগ করে তবে আমি বিশদে আগ্রহী। আমি এটি কেবলমাত্র আমার এলজি জি 4 চলমান অ্যান্ড্রয়েড 6.0 এ পরীক্ষিত করেছি (আমি তখন নিজের নিজস্ব কিছু গবেষণা করছিলাম) এবং আমি আশা করি এটি অ্যান্ড্রয়েডের সমস্ত সংস্করণে কাজ করে না doesn't
রস ব্র্যাডবারি

@ রোসব্রেডবারি এটি কিছু ডিভাইসে কাজ করে না .. বেশিরভাগ ডিভাইস সঠিকভাবে কাজ করে তবে কিছু ডিভাইস এই ফন্টফ্যামিলি গ্রহণ করে না .. আমার পরীক্ষিত ডিভাইস - লেনোভা এ 000০০০ মডেল
রঞ্জিত কুমার

আপডেট: github.com/chrisjenx/ কলিগ্রাফি একটি উচ্চতর সমাধান।
রস ব্র্যাডবারি

5

সম্পদে একটি ফন্ট ফোল্ডার তৈরি করুন এবং আপনার প্রয়োজনীয় ফন্টগুলি সেখানে যুক্ত করুন।

public class CustomTextView extends TextView {
    private static final String TAG = "TextView";

    public CustomTextView(Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(context, attrs);
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }

    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.CustomTextView);
        String customFont = a.getString(R.styleable.CustomTextView_customFont);
        setCustomFont(ctx, customFont);
        a.recycle();
    }

    public boolean setCustomFont(Context ctx, String fontName) {
        Typeface typeface = null;
        try {
            if(fontName == null){
                fontName = Constants.DEFAULT_FONT_NAME;
            }
            typeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/" + fontName);
        } catch (Exception e) {
            Log.e(TAG, "Unable to load typeface: "+e.getMessage());
            return false;
        }
        setTypeface(typeface);
        return true;
    }
}

এবং attrs.xML এ একটি ঘোষণাযোগ্য যুক্ত করুন

<declare-styleable name="CustomTextView">
      <attr name="customFont" format="string"/>
</declare-styleable>

এবং তারপরে আপনার কাস্টমফন্টটি যুক্ত করুন

app:customFont="arial.ttf"

আপনি এখানে শ্রেণীর মতো শৈলীর সাথে কাজ করতে উপরে বর্গের উপরেও অনুকূলিতকরণ করতে পারেন। github.com/leok7v/android-textview-custom-fouts/blob/master/res/…
অ্যান্ড্রয়েডগীক

5

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে আমি একটি আরও সহজ সমাধান খুঁজে পেয়েছি।

প্রথমে আপনার টেক্সটভিউটি যথারীতি এক্সএমএলে ঘোষণা করুন। সম্পদ ফোল্ডারে আপনার ফন্ট (টিটিএফ বা টিটিসি) রাখুন

অ্যাপ্লিকেশন \ src \ প্রধান \ সম্পদ \

তারপরে আপনার অনক্রিট পদ্ধতিতে কেবল আপনার পাঠ্য দর্শনের জন্য টাইপফেসটি সেট করুন।

@Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_name);    

    TextView textView = findViewById(R.id.my_textView);
    Typeface typeface = Typeface.createFromAsset(getAssets(), "fontName.ttf");
    textView.setTypeface(typeface);
}

সম্পন্ন.


4
প্রশ্নটি এক্সএমএল ফাইলগুলির ভিতরে এটি ব্যবহার করার জন্য স্পষ্টভাবে বলেছে
গুস্তাভো বায়োচি কোস্টা

2

এক্সএমএল এ দেশীয় কাস্টম ফন্ট বৈশিষ্ট্য গুগল দ্বারা প্রবর্তিত (শেষ অবধি) সবচেয়ে ভাল সমাধান। তবে আপনাকে এপিআই 26 কে লক্ষ্য করতে হবে It এটি API 16+ সমর্থন করে

https://developer.android.com/guide/topics/ui/look-and-feel/fouts-in-xML


0

এক্সএমএনএলএসের পরিবর্তে: কাস্টম = "স্কিমাস.অ্যান্ড্রয়েড / টলস"; আপনার ব্যবহার করা উচিত: xmlns: কাস্টম = "স্কিমাস.অ্যান্ড্রয়েড.com/apk/res-auto"; স্টাইলযোগ্য বৈশিষ্ট্য ব্যবহার করার জন্য। আমি এই পরিবর্তন করেছি এবং এটি এখন কাজ করছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.