অ্যান্ড্রয়েডে একটি কাস্টম টাইপফেস ব্যবহার করা


111

আমি আমার অ্যান্ড্রয়েড অ্যাপ্লিকেশনটির জন্য একটি কাস্টম ফন্ট ব্যবহার করতে চাই যা আমি তৈরি করছি।
আমি কোড থেকে প্রতিটি বস্তুর টাইপফেসটি স্বতন্ত্রভাবে পরিবর্তন করতে পারি, তবে আমার শত শত রয়েছে।

সুতরাং,

  • এক্সএমএল থেকে এটি করার কোনও উপায় আছে? [একটি কাস্টম টাইপফেস সেট করা হচ্ছে]
  • কোড থেকে এটি এক জায়গায় করার কোনও উপায় আছে কি না, পুরো অ্যাপ্লিকেশন এবং সমস্ত উপাদানগুলির ডিফল্টটির পরিবর্তে কাস্টম টাইপফেসটি ব্যবহার করা উচিত?

stackoverflow.com/questions/5541058/… এই পোস্টটি দেখুন আমি এই সমস্যাটি সম্পর্কে এখানে সম্পূর্ণ কোড পোস্ট করেছি
মণীশ সিঙ্গলা

আপনি এম্বেড থাকা ফন্টগুলির রেফারেন্স রাখতে আপনার মূল ক্রিয়াকলাপে স্থির পরিবর্তনশীল ব্যবহার করতে পারেন use এর ফলে সেখানে ফন্টগুলির একটি ধ্রুবক সেট থাকবে যা জিসি দ্বারা গ্রহণ করা হবে না।
জ্যাকসনকর

কারখানা পদ্ধতি। বা এমন একটি পদ্ধতি যা আপনার দৃষ্টিভঙ্গি নেয় এবং সমস্ত ফন্ট এবং টাইপফেস সেটিংস সেট করে।
mtmurdock

নতুন সমর্থন লাইব্রেরি 26 আপনাকে এখন এক্সএমএলে ফন্ট ব্যবহার করতে দেয়। এটি কীভাবে এটি এক্সএমএলে ফন্টগুলি রয়েছে
ভিনিসিয়াস সিলভা

উত্তর:


80

এক্সএমএল থেকে এটি করার কোনও উপায় আছে?

না, দুঃখিত। আপনি কেবল এক্সএমএলের মাধ্যমে বিল্ট-ইন টাইপফেসগুলি নির্দিষ্ট করতে পারবেন।

কোড থেকে এটি এক জায়গায় করার কোনও উপায় আছে কি না, পুরো অ্যাপ্লিকেশন এবং সমস্ত উপাদানগুলির ডিফল্টটির পরিবর্তে কাস্টম টাইপফেসটি ব্যবহার করা উচিত?

এমন নয় যে আমি জানিনা.

আজকাল এগুলির জন্য বিভিন্ন ধরণের বিকল্প রয়েছে:

  • আপনি যদি ব্যবহার করেন তবে অ্যান্ড্রয়েড এসডিকে ফন্ট সংস্থান এবং ব্যাকপোর্টগুলি appcompat

  • তৃতীয় পক্ষের গ্রন্থাগারগুলি যারা ব্যবহার করছেন না তাদের জন্য appcompat, যদিও সকলেই লেআউট সংস্থানগুলিতে ফন্টটি সংজ্ঞায়িত করতে সমর্থন করবেন না


4
@ কোডডলি: ওয়েল, বিভিন্ন উপায়ে কাস্টম ফন্টগুলির সাথে ঝগড়া না করা এর থেকে ভাল উত্তর। আপনার ডাউনলোডগুলি আরও বড় করে এবং আপনার অ্যাপ্লিকেশনটি ডাউনলোড এবং ব্যবহার করে রাখবে এমন লোকের সংখ্যা হ্রাস করে এগুলি বড় হয়ে থাকে।
কমন্সওয়্যার

22
@ কমন্সওয়্যার: আমি অগত্যা একমত হই না। টাইপফেস ইউআই স্টাইলিংয়ের একটি অবিচ্ছেদ্য অঙ্গ যা আপনি ব্যাকগ্রাউন্ডের চিত্র ইত্যাদি দিয়ে করেন এবং আকার সর্বদা বড় হয় না। উদাহরণস্বরূপ, আমার ক্ষেত্রে ফন্টটি কেবল 19.6KB :)
কোডভেলি

2
@ অ্যামিট: এই ইস্যুতে কোনও পরিবর্তন হয়নি। জাভাতে আপনার ইউআইতে টাইপফেস প্রয়োগ করা সহজ করার জন্য প্রচুর কোড স্নিপেট রয়েছে তবে এক্সএমএল থেকে এটি করার কোনও উপায় নেই।
কমন্সওয়্যার

1
@ অ্যামিট: "তবে তার মানে কি কাস্টম ফন্টগুলির জন্য আমার নিজের .tf বা .otf ফাইলগুলি তৈরি করতে হবে?" - উম, না আপনি বিদ্যমান টিটিএফ / ওটিএফ ফন্টগুলি ব্যবহার করতে পারেন, যদিও সেগুলি সমস্ত কাজ না করে। এই প্রশ্নের বিষয়টি হ'ল কীভাবে একটি সম্পূর্ণ অ্যাপ্লিকেশন জুড়ে এই ফন্টগুলি প্রয়োগ করা যায়, যা এখনও সম্ভব নয়, এবং এটি আমি আমার মন্তব্যে উল্লেখ করছি।
কমন্সওয়্যার

1
এই গৃহীত উত্তরটি অপ্রচলিত, এবং এটি আপডেট করা বা এটি মুছে ফেলা দুর্দান্ত হবে।
স্কাই কেলসি

109

হ্যা এটা সম্ভব.

আপনাকে একটি কাস্টম ভিউ তৈরি করতে হবে যা পাঠ্য দর্শনকে প্রসারিত করে।

ইন attrs.xmlমধ্যে valuesফোল্ডার:

<resources>
    <declare-styleable name="MyTextView">
        <attr name="first_name" format="string"/>
        <attr name="last_name" format="string"/>
        <attr name="ttf_name" format="string"/>
    </declare-styleable>
</resources>

ইন main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:lht="http://schemas.android.com/apk/res/com.lht"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView  android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:text="Hello"/>
    <com.lht.ui.MyTextView  
        android:id="@+id/MyTextView"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:text="Hello friends"
        lht:ttf_name="ITCBLKAD.TTF"
        />   
</LinearLayout>

ইন MyTextView.java:

package com.lht.ui;

import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

public class MyTextView extends TextView {

    Context context;
    String ttfName;

    String TAG = getClass().getName();

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;

        for (int i = 0; i < attrs.getAttributeCount(); i++) {
            Log.i(TAG, attrs.getAttributeName(i));
            /*
             * Read value of custom attributes
             */

            this.ttfName = attrs.getAttributeValue(
                    "http://schemas.android.com/apk/res/com.lht", "ttf_name");
            Log.i(TAG, "firstText " + firstText);
            // Log.i(TAG, "lastText "+ lastText);

            init();
        }

    }

    private void init() {
        Typeface font = Typeface.createFromAsset(context.getAssets(), ttfName);
        setTypeface(font);
    }

    @Override
    public void setTypeface(Typeface tf) {

        // TODO Auto-generated method stub
        super.setTypeface(tf);
    }

}

4
এটি কাজ করবে, তবে কেবল তার জন্য TextView। এটির জন্য প্রতিটি উইজেট শ্রেণীর জন্য কাস্টম সাবক্লাসের প্রয়োজন হবে TextViewযেখানে উত্তরাধিকার সূত্রে একই ক্ষমতাটি কাঙ্ক্ষিত।
কমন্সওয়্যার

হাই মণীশ, সমাধানের জন্য ধন্যবাদ। যদিও আমি এটি ব্যবহার করতে কোনও সমস্যার মুখোমুখি। আমি প্যাকেজ com.lht.android তে ttf_name বৈশিষ্ট্যের জন্য কোনও সংস্থান সনাক্তকারী পাইনি '
আগরওয়াল

17
এটি কাজ করবে, তবে প্রাক-আইসিএস এটি আপনার প্রতিটি তাত্ক্ষণিক দর্শনের জন্য ফন্টগুলির জন্য মেমরি বরাদ্দ করবে: কোড. google.com/p/android/issues/detail?id=9904 এটি ঠিক করার একটি উপায় বিশ্বব্যাপী অ্যাক্সেসযোগ্য তৈরি করা সমস্ত তাত্ক্ষণিক ফন্টগুলির স্ট্যাটিক হ্যাশম্যাপ
কেন ভ্যান হোয়েল্যান্ড

আমাদের কেন একটি লুপ দরকার ?, এটি কি একক কল দিয়ে কাজ করা উচিত নয়?
গিলারমো টোবার

1
@AlaksiejN। আপনি যদি বিভিন্ন পাঠ্যদর্শনগুলিতে আলাদা আলাদা টাইপফেস সেট করতে চান ...
নিক

49

আমি এটি আরও "ব্রুট ফোর্স" উপায়ে এটি করেছি যাতে বিন্যাসে এক্সএমএল বা ক্রিয়াকলাপগুলির পরিবর্তন দরকার হয় না।

অ্যান্ড্রয়েড সংস্করণ ২.১ এর মাধ্যমে ৪.৪ এর মাধ্যমে পরীক্ষিত। আপনার অ্যাপ্লিকেশন শ্রেণিতে এটি অ্যাপ্লিকেশন প্রারম্ভকালে চালান:

private void setDefaultFont() {

    try {
        final Typeface bold = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_FONT_FILENAME);
        final Typeface italic = Typeface.createFromAsset(getAssets(), DEFAULT_ITALIC_FONT_FILENAME);
        final Typeface boldItalic = Typeface.createFromAsset(getAssets(), DEFAULT_BOLD_ITALIC_FONT_FILENAME);
        final Typeface regular = Typeface.createFromAsset(getAssets(),DEFAULT_NORMAL_FONT_FILENAME);

        Field DEFAULT = Typeface.class.getDeclaredField("DEFAULT");
        DEFAULT.setAccessible(true);
        DEFAULT.set(null, regular);

        Field DEFAULT_BOLD = Typeface.class.getDeclaredField("DEFAULT_BOLD");
        DEFAULT_BOLD.setAccessible(true);
        DEFAULT_BOLD.set(null, bold);

        Field sDefaults = Typeface.class.getDeclaredField("sDefaults");
        sDefaults.setAccessible(true);
        sDefaults.set(null, new Typeface[]{
                regular, bold, italic, boldItalic
        });

    } catch (NoSuchFieldException e) {
        logFontError(e);
    } catch (IllegalAccessException e) {
        logFontError(e);
    } catch (Throwable e) {
        //cannot crash app if there is a failure with overriding the default font!
        logFontError(e);
    }
}

আরও সম্পূর্ণ উদাহরণের জন্য, http://github.com/perchrh/FontOverrideExample দেখুন


এটি আমার পক্ষে সেরা সমাধান।
ইগোর কে

2
ডিফল্ট আমার জন্য কাজ করে না। যদি আমি মনোস্পেস ব্যবহার করি এবং তারপরে code<শৈলীর নাম = "অ্যাপপ্লেম" প্যারেন্ট = "অ্যাপবেস থেম"> <আইটেম নাম = "অ্যান্ড্রয়েড: টাইপফেস"> মনোস্পেস </item> </style> সেট codeকরে তবে এটি সাহসের জন্য নয়। আমি এই কোডটি এমন একটি ক্লাসে যুক্ত করেছি যা অ্যাপ্লিকেশন প্রসারিত করে। এটা কি সঠিক জায়গা? @ পি-চ্যান
ক্রিস্টোফার রিভেরা

2
@ খ্রিস্টোফেরিভেরা হ্যাঁ, এটি আপনার অ্যাপ্লিকেশনটির ক্লাসে যুক্ত করুন, নিশ্চিত করুন যে এটি অনক্রিটে চলছে। গ্রিপকোড . com/file/repository.grepcode.com/java/ext/ … এক নজরে রাখার জন্য আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি মনোস্পেসের জন্য অতিরিক্ত ক্ষেত্রের পাশাপাশি উপরের আমার নমুনা কোডের একটিটিকে ওভাররাইড করুন!
ক্রিশ্চিয়ান হেনডেন

2
ঠিক আছে, আমি সেরিফ ফিল্ডের জন্য পরিবর্তিত হয়েছি এবং এটি কাজ করেছে :)
আবদুল্লাহ উমার

3
এই উত্তরটি এই উত্তরটির উল্লেখ করে এবং একটি পরিষ্কার পরিচ্ছন্নতা সরবরাহ করে ho
অ্যাডামডপোর্ট

36

যদিও আমি মনিশের উত্তরটিকে দ্রুত এবং সর্বাধিক লক্ষ্যযুক্ত পদ্ধতি হিসাবে উজ্জীবিত করছি, আমি এমন নিষ্পাপ সমাধানও দেখেছি যা কেবলমাত্র ভিউ হায়ারার্কির মাধ্যমে পুনরাবৃত্তভাবে পুনরাবৃত্তি করে এবং সমস্ত উপাদানগুলির টাইপফেসগুলি পরিবর্তে আপডেট করে। এটার মতো কিছু:

public static void applyFonts(final View v, Typeface fontToSet)
{
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                applyFonts(child, fontToSet);
            }
        } else if (v instanceof TextView) {
            ((TextView)v).setTypeface(fontToSet);
        }
    } catch (Exception e) {
        e.printStackTrace();
        // ignore
    }
}

লেআউট স্ফীত করার পরে এবং আপনার ক্রিয়াকলাপের onContentChanged()পদ্ধতিগুলিতে আপনার নিজের মতামতগুলিতে এই ফাংশনটি কল করতে হবে ।


যথেষ্ট. তখন প্রকল্পের সময়সীমার মধ্যে এটি করার একমাত্র উপায় ছিল। প্রয়োজনে একটি সহজ শর্টকাট (:
pospi

23

আমি এটি কেন্দ্রীয়ভাবে করতে পেরেছি, ফলাফল এখানে:

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

আমার Activityকাস্টম ফন্টগুলির প্রয়োজন হলে আমার নিম্নলিখিতগুলি রয়েছে এবং আমি এটি থেকে প্রসারিত করব:

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater.Factory;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

public class CustomFontActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    getLayoutInflater().setFactory(new Factory() {

        @Override
        public View onCreateView(String name, Context context,
                AttributeSet attrs) {
            View v = tryInflate(name, context, attrs);
            if (v instanceof TextView) {
                setTypeFace((TextView) v);
            }
            return v;
        }
    });
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

private View tryInflate(String name, Context context, AttributeSet attrs) {
    LayoutInflater li = LayoutInflater.from(context);
    View v = null;
    try {
        v = li.createView(name, null, attrs); 
    } catch (Exception e) {
        try {
            v = li.createView("android.widget." + name, null, attrs);
        } catch (Exception e1) {
        }
    }
    return v;
}

private void setTypeFace(TextView tv) {
    tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}

তবে যদি আমি সমর্থন প্যাকেজ থেকে কোনও ক্রিয়াকলাপ FragmentActivityব্যবহার করি যেমন, তবে আমি এটি ব্যবহার করি Activity:

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

public class CustomFontFragmentActivity extends FragmentActivity {

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

// we can't setLayout Factory as its already set by FragmentActivity so we
// use this approach
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
    View v = super.onCreateView(name, context, attrs);
    if (v == null) {
        v = tryInflate(name, context, attrs);
        if (v instanceof TextView) {
            setTypeFace((TextView) v);
        }
    }
    return v;
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public View onCreateView(View parent, String name, Context context,
        AttributeSet attrs) {
    View v = super.onCreateView(parent, name, context, attrs);
    if (v == null) {
        v = tryInflate(name, context, attrs);
        if (v instanceof TextView) {
            setTypeFace((TextView) v);
        }
    }
    return v;
}

private View tryInflate(String name, Context context, AttributeSet attrs) {
    LayoutInflater li = LayoutInflater.from(context);
    View v = null;
    try {
        v = li.createView(name, null, attrs);
    } catch (Exception e) {
        try {
            v = li.createView("android.widget." + name, null, attrs);
        } catch (Exception e1) {
        }
    }
    return v;
}

private void setTypeFace(TextView tv) {
    tv.setTypeface(FontUtils.getFonts(this, "MTCORSVA.TTF"));
}
}

আমি এই কোডটির সাথে Fragmentএখনও পরীক্ষা করিনি, তবে আশা করি এটি কার্যকর হবে।

আমার FontUtilsসহজ, যা এখানে বর্ণিত প্রাক-আইসিএস সমস্যাটিও সমাধান করে https://code.google.com/p/android/issues/detail?id=9904 :

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.graphics.Typeface;

public class FontUtils {

private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();

public static Typeface getFonts(Context context, String name) { 
    Typeface typeface = TYPEFACE.get(name);
    if (typeface == null) {
        typeface = Typeface.createFromAsset(context.getAssets(), "fonts/"
                + name);
        TYPEFACE.put(name, typeface);
    }
    return typeface;
}
}

2
এটি আরও ভোট পেতে হবে। এটি কাজ করে এবং এর প্রদর্শনের জন্য একটি স্ক্রিনশট রয়েছে
এরিকান

10

আরে আমারও আলাদা আলাদা উইজেডের জন্য আমার অ্যাপে 2 টি আলাদা ফন্টের প্রয়োজন! আমি এইভাবে ব্যবহার করি:

আমার অ্যাপ্লিকেশন শ্রেণিতে আমি একটি স্থিতিশীল পদ্ধতি তৈরি করি:

public static Typeface getTypeface(Context context, String typeface) {
    if (mFont == null) {
        mFont = Typeface.createFromAsset(context.getAssets(), typeface);
    }
    return mFont;
}

স্ট্রিং টাইপফেসটি সম্পদ ফোল্ডারে xyz.ttf উপস্থাপন করে। (আমি একটি কনস্ট্যান্ট ক্লাস তৈরি করেছি) এখন আপনি এটি আপনার অ্যাপ্লিকেশানের যেকোন জায়গায় ব্যবহার করতে পারেন:

mTextView = (TextView) findViewById(R.id.text_view);
mTextView.setTypeface(MyApplication.getTypeface(this, Constants.TYPEFACE_XY));

একমাত্র সমস্যা হ'ল প্রতিটি উইজেটের জন্য আপনার এটি দরকার যেখানে আপনি ফন্টটি ব্যবহার করতে চান! তবে আমি মনে করি এটিই সেরা উপায়।


4

পোস্টপির পরামর্শটি ব্যবহার করে এবং রিচার্ডের মতো 'ট্যাগ' সম্পত্তি নিয়ে কাজ করা , আমি একটি কাস্টম ক্লাস তৈরি করেছি যা আমার কাস্টম ফন্টগুলি লোড করে এবং তাদের ট্যাগ অনুসারে দৃশ্যে প্রয়োগ করে।

সুতরাং প্রাথমিকভাবে, অ্যানড্রয়েড: ফন্টফ্যামিলি বৈশিষ্ট্যটিতে টাইপফেস সেট করার পরিবর্তে আপনি অ্যান্ড্রয়েড: ট্যাগ অ্যাট্রিটিউব ব্যবহার করছেন এবং এটি নির্ধারিত এনামগুলির একটিতে সেট করুন।

public class Fonts {
    private AssetManager mngr;

    public Fonts(Context context) {
        mngr = context.getAssets();
    }
    private enum AssetTypefaces {
        RobotoLight,
        RobotoThin,
        RobotoCondensedBold,
        RobotoCondensedLight,
        RobotoCondensedRegular
    }

    private Typeface getTypeface(AssetTypefaces font) {
        Typeface tf = null;
        switch (font) {
            case RobotoLight:
                tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Light.ttf");
                break;
            case RobotoThin:
                tf = Typeface.createFromAsset(mngr,"fonts/Roboto-Thin.ttf");
                break;
            case RobotoCondensedBold:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Bold.ttf");
                break;
            case RobotoCondensedLight:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Light.ttf");
                break;
            case RobotoCondensedRegular:
                tf = Typeface.createFromAsset(mngr,"fonts/RobotoCondensed-Regular.ttf");
                break;
            default:
                tf = Typeface.DEFAULT;
                break;
        }
        return tf;
    }
    public void setupLayoutTypefaces(View v) {
        try {
            if (v instanceof ViewGroup) {
                ViewGroup vg = (ViewGroup) v;
                for (int i = 0; i < vg.getChildCount(); i++) {
                    View child = vg.getChildAt(i);
                    setupLayoutTypefaces(child);
                }
            } else if (v instanceof TextView) {
                if (v.getTag().toString().equals(AssetTypefaces.RobotoLight.toString())){
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoLight));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedRegular.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedRegular));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedBold.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedBold));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoCondensedLight.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoCondensedLight));
                }else if (v.getTag().toString().equals(AssetTypefaces.RobotoThin.toString())) {
                    ((TextView)v).setTypeface(getTypeface(AssetTypefaces.RobotoThin));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            // ignore
        }
    }
}

আপনার ক্রিয়াকলাপ বা খণ্ডে আপনি কেবল কল করেন

Fonts fonts = new Fonts(getActivity());
fonts.setupLayoutTypefaces(mainLayout);

4

লিসা ওয়ারের ব্লগে আমি একটি দুর্দান্ত সমাধান পেয়েছি । নতুন ডেটা বাইন্ডিংয়ের সাহায্যে আপনার এক্সএমএল ফাইলগুলিতে ফন্ট সেট করা সম্ভব।

@BindingAdapter({"bind:font"})
public static void setFont(TextView textView, String fontName){
    textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}

এক্সএমএলে:

<TextView
app:font="@{`Source-Sans-Pro-Regular.ttf`}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

আপনি ডেটা বাঁধাই ব্যবহার করে একটি উদাহরণ প্রস্তাব করতে পারেন? যে অনেক প্রশংসা হবে।
শ্রী কৃষ্ণ

3

আমি মনে করি এটি করার একটি আরও সহজ উপায় হতে পারে। নিম্নলিখিত ক্লাসটি আপনার অ্যাপ্লিকেশনের সমস্ত উপাদানগুলির জন্য কাস্টম ধরণের মুখ সেট করবে (প্রতি ক্লাসে একটি সেটিং সহ)।

/**
 * Base Activity of our app hierarchy.
 * @author SNI
 */
public class BaseActivity extends Activity {

    private static final String FONT_LOG_CAT_TAG = "FONT";
    private static final boolean ENABLE_FONT_LOGGING = false;

    private Typeface helloTypeface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        helloTypeface = Typeface.createFromAsset(getAssets(), "fonts/<your type face in assets/fonts folder>.ttf");
    }

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        View view = super.onCreateView(name, context, attrs);
        return setCustomTypeFaceIfNeeded(name, attrs, view);
    }

    @Override
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        View view = super.onCreateView(parent, name, context, attrs);
        return setCustomTypeFaceIfNeeded(name, attrs, view);
    }

    protected View setCustomTypeFaceIfNeeded(String name, AttributeSet attrs, View view) {
        View result = null;
        if ("TextView".equals(name)) {
            result = new TextView(this, attrs);
            ((TextView) result).setTypeface(helloTypeface);
        }

        if ("EditText".equals(name)) {
            result = new EditText(this, attrs);
            ((EditText) result).setTypeface(helloTypeface);
        }

        if ("Button".equals(name)) {
            result = new Button(this, attrs);
            ((Button) result).setTypeface(helloTypeface);
        }

        if (result == null) {
            return view;
        } else {
            if (ENABLE_FONT_LOGGING) {
                Log.v(FONT_LOG_CAT_TAG, "A type face was set on " + result.getId());
            }
            return result;
        }
    }

}

2

লেআউটআইনফ্লেটারের ডিফল্ট প্রয়োগগুলি এক্সএমএল থেকে ফন্ট টাইপফেস নির্দিষ্ট করে সমর্থন করে না। তবে আমি এটি XML এ সম্পন্ন লেআউটআইনফ্লেটারের জন্য একটি কাস্টম কারখানা সরবরাহ করে দেখেছি যা এক্সএমএল ট্যাগ থেকে এই জাতীয় বৈশিষ্ট্যগুলি বিশ্লেষণ করে।

প্রাথমিক কাঠামো এটি পছন্দ করবে।

public class TypefaceInflaterFactory implements LayoutInflater.Factory {

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        // CUSTOM CODE TO CREATE VIEW WITH TYPEFACE HERE
        // RETURNING NULL HERE WILL TELL THE INFLATER TO USE THE
        // DEFAULT MECHANISMS FOR INFLATING THE VIEW FROM THE XML
    }

}

public class BaseActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LayoutInflater.from(this).setFactory(new TypefaceInflaterFactory());
    }
}

এই নিবন্ধটি এই প্রক্রিয়াগুলির আরও গভীরভাবে ব্যাখ্যা সরবরাহ করে এবং লেখক কীভাবে এইভাবে টাইপফেসগুলির জন্য এক্সএমএল লেআউট সমর্থন সরবরাহ করার চেষ্টা করে। লেখকের বাস্তবায়নের জন্য কোডটি এখানে পাওয়া যাবে


1

একটি নিয়মিত অগ্রগতি ডায়ালগ / সতর্কতা ডায়ালগ এ একটি কাস্টম ফন্ট সেট করা:

font=Typeface.createFromAsset(getAssets(),"DroidSans.ttf");

ProgressDialog dialog = ProgressDialog.show(this, "titleText", "messageText", true);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("message", "id", "android"))).setTypeface(font);
((TextView)dialog.findViewById(Resources.getSystem().getIdentifier("alertTitle", "id", "android"))).setTypeface(font);

1

হ্যাঁ এটি ডিফল্ট টাইপফেসে ওভাররাইড করেই সম্ভব। আমি এই সমাধানটি অনুসরণ করেছি এবং এটি একক পরিবর্তন সহ সমস্ত টেক্সটভিউ এবং অ্যাকশনবার পাঠ্যের জন্য আকর্ষণীয় কাজ করেছে।

public class MyApp extends Application {

  @Override
  public void onCreate() {
    TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/Roboto-Regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
  }
}

styles.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/pantone</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
    <item name="android:windowDisablePreview">true</item>
    <item name="android:typeface">serif</item>
</style>

উপরের লিঙ্কটিতে উল্লিখিত থিমস.এক্সএমএল পরিবর্তে আমি আমার ডিফল্ট অ্যাপ্লিকেশন থিম ট্যাগে আমার স্টাইলস.এক্সএমএলকে ওভাররাইড করতে ডিফল্ট ফন্ট উল্লেখ করেছি mentioned ওভাররাইট করা যায় এমন ডিফল্ট টাইপফেসগুলি হ'ল সেরিফ, সানস, মনোস্পেস এবং সাধারণ।

TypefaceUtil.java

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     * @param context to work with assets
     * @param defaultFontNameToOverride for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
        try {
            final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

            final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
            defaultFontTypefaceField.setAccessible(true);
            defaultFontTypefaceField.set(null, customFontTypeface);
        } catch (Exception e) {
            Log.e("Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
        }
    }
}

প্রথমদিকে, আমি জানতাম না যে ওভাররাইট করা টাইপফেসগুলি স্থির এবং সংজ্ঞায়িত মানগুলির সেট করা যায় তবে শেষ পর্যন্ত এটি আমাকে বুঝতে সাহায্য করেছিল যে অ্যান্ড্রয়েড কীভাবে ফন্ট এবং টাইপফেসগুলি এবং তাদের ডিফল্ট মানগুলির সাথে ডিল করে, যা একটি ভিন্ন পয়েন্ট অফকোর্স।


0

আমি জানি না এটি পুরো অ্যাপটি পরিবর্তন করে কিনা, তবে আমি এমন কিছু উপাদান পরিবর্তন করতে পরিচালিত করেছি যা অন্যথায় এটি করে পরিবর্তন করা যায় না:

Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Lucida Sans Unicode.ttf");
Typeface.class.getField("DEFAULT").setAccessible(true);
Typeface.class.getField("DEFAULT_BOLD").setAccessible(true);
Typeface.class.getField("DEFAULT").set(null, tf);
Typeface.class.getField("DEFAULT_BOLD").set(null, tf);

2
দুর্ভাগ্যক্রমে এটি আর কাজ করে না: java.lang.IllegalAccessException: java.lang.reflect.Field.setField (নেটিভ মেথড) এ জাভা.লাং.রেফলেট.ফিল্ড.সেট (ফিল্ড.জভা: 556)
BoD

0

আমি পোসপির পরামর্শটি পছন্দ করি। আপনি এক্সএমএলে যে কোনও অতিরিক্ত স্টাইলিং করতে পারবেন না তা নির্দিষ্ট করার জন্য কেন কোনও ভিউয়ের 'ট্যাগ' সম্পত্তি (যা আপনি এক্সএমএল - 'অ্যান্ড্রয়েড: ট্যাগ' এ নির্দিষ্ট করতে পারেন) ব্যবহার করে কেন অল-আউট হয়ে যান না। আমি JSON পছন্দ করি তাই আমি কী / মান সেট নির্দিষ্ট করতে একটি JSON স্ট্রিং ব্যবহার করব। এই শ্রেণিটি কাজ করে - কেবল Style.setContentView(this, [resource id])আপনার ক্রিয়াকলাপে কল করুন।

public class Style {

  /**
   * Style a single view.
   */
  public static void apply(View v) {
    if (v.getTag() != null) {
      try {
        JSONObject json = new JSONObject((String)v.getTag());
        if (json.has("typeface") && v instanceof TextView) {
          ((TextView)v).setTypeface(Typeface.createFromAsset(v.getContext().getAssets(),
                                                             json.getString("typeface")));
        }
      }
      catch (JSONException e) {
        // Some views have a tag without it being explicitly set!
      }
    }
  }

  /**
   * Style the passed view hierarchy.
   */
  public static View applyTree(View v) {
    apply(v);
    if (v instanceof ViewGroup) {
      ViewGroup g = (ViewGroup)v;
      for (int i = 0; i < g.getChildCount(); i++) {
        applyTree(g.getChildAt(i));
      }
    }
    return v;
  }

  /**
   * Inflate, style, and set the content view for the passed activity.
   */
  public static void setContentView(Activity activity, int resource) {
    activity.setContentView(applyTree(activity.getLayoutInflater().inflate(resource, null)));
  }
}

স্পষ্টতই আপনি JSON ব্যবহার করে সার্থক করার জন্য টাইপফেসের চেয়ে বেশি কিছু পরিচালনা করতে চান।

'ট্যাগ' সম্পত্তিটির একটি সুবিধা হ'ল আপনি এটিকে একটি বেস স্টাইলে সেট করতে পারেন যা আপনি থিম হিসাবে ব্যবহার করেন এবং এটি আপনার সমস্ত দর্শনে স্বয়ংক্রিয়ভাবে প্রয়োগ করতে পারেন। সম্পাদনা করুন: অ্যান্ড্রয়েড inflation.০.৩ এ মুদ্রাস্ফীতি চলাকালীন ক্রাশের ফলাফল হিসাবে এটি করা। আপনি এখনও একটি স্টাইল ব্যবহার করতে পারেন এবং স্বতন্ত্রভাবে পাঠ্য দর্শনে এটি প্রয়োগ করতে পারেন।

আপনি কোডটিতে একটি জিনিস দেখতে পাবেন - কিছু মতামতের একটি ট্যাগ রয়েছে যা স্পষ্টভাবে সেট না করেই থাকে - উদ্ভটভাবে এটি স্ট্রিং 'Αποκοπή' - যা গ্রীক ভাষায় 'কাটা' হয়, গুগল অনুবাদ অনুসারে! কি খারাপ অবস্থা...?


0

@ মজিনবু'র উত্তরটি কর্মক্ষমতা এবং মেমরি পরিচালনার জন্য সংশোধিত হয়েছে। একাধিক ফন্টের সম্পর্কিত যে কোনও ক্রিয়াকলাপ কনস্ট্রাক্টরকে প্যারামিটার হিসাবে দেওয়ার মাধ্যমে এই ফন্ট শ্রেণিটি ব্যবহার করতে পারে।

@Override
public void onCreate(Bundle savedInstanceState)
{
    Font font = new Font(this);
}

সংশোধিত ফন্টের শ্রেণিটি নীচে রয়েছে:

public class Fonts
{
    private HashMap<AssetTypefaces, Typeface> hashMapFonts;

    private enum AssetTypefaces
    {
        RobotoLight,
        RobotoThin,
        RobotoCondensedBold,
        RobotoCondensedLight,
        RobotoCondensedRegular
    }

    public Fonts(Context context)
    {
        AssetManager mngr = context.getAssets();

        hashMapFonts = new HashMap<AssetTypefaces, Typeface>();
        hashMapFonts.put(AssetTypefaces.RobotoLight, Typeface.createFromAsset(mngr, "fonts/Roboto-Light.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoThin, Typeface.createFromAsset(mngr, "fonts/Roboto-Thin.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedBold, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Bold.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedLight, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Light.ttf"));
        hashMapFonts.put(AssetTypefaces.RobotoCondensedRegular, Typeface.createFromAsset(mngr, "fonts/RobotoCondensed-Regular.ttf"));
    }

    private Typeface getTypeface(String fontName)
    {
        try
        {
            AssetTypefaces typeface = AssetTypefaces.valueOf(fontName);
            return hashMapFonts.get(typeface);
        }
        catch (IllegalArgumentException e)
        {
            // e.printStackTrace();
            return Typeface.DEFAULT;
        }
    }

    public void setupLayoutTypefaces(View v)
    {
        try
        {
            if (v instanceof ViewGroup)
            {
                ViewGroup vg = (ViewGroup) v;
                for (int i = 0; i < vg.getChildCount(); i++)
                {
                    View child = vg.getChildAt(i);
                    setupLayoutTypefaces(child);
                }
            }
            else if (v instanceof TextView)
            {
                ((TextView) v).setTypeface(getTypeface(v.getTag().toString()));
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            // ignore
        }
    }
}

0

জামারিন.এন্ড্রয়েডের জন্য কাজ করা:

ক্লাস:

public class FontsOverride
{
    public static void SetDefaultFont(Context context, string staticTypefaceFieldName, string fontAssetName)
    {
        Typeface regular = Typeface.CreateFromAsset(context.Assets, fontAssetName);
        ReplaceFont(staticTypefaceFieldName, regular);
    }

    protected static void ReplaceFont(string staticTypefaceFieldName, Typeface newTypeface)
    {
        try
        {
            Field staticField = ((Java.Lang.Object)(newTypeface)).Class.GetDeclaredField(staticTypefaceFieldName);
            staticField.Accessible = true;
            staticField.Set(null, newTypeface);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

প্রয়োগ বাস্তবায়ন:

namespace SomeAndroidApplication
{
    [Application]
    public class App : Application
    {
        public App()
        {

        }

        public App(IntPtr handle, JniHandleOwnership transfer)
            : base(handle, transfer)
        {

        }

        public override void OnCreate()
        {
            base.OnCreate();

            FontsOverride.SetDefaultFont(this, "MONOSPACE", "fonts/Roboto-Light.ttf");
        }
    }
}

শৈলী:

<style name="Theme.Storehouse" parent="Theme.Sherlock">
    <item name="android:typeface">monospace</item>
</style>

0

দেখে মনে হচ্ছে অ্যান্ড্রয়েড ওয়ের সাহায্যে কাস্টম ফন্টগুলি ব্যবহার করা সহজ হয়েছে, আপনি এটি অর্জনের জন্য মূলত xML ব্যবহার করতে পারেন। আমি রেফারেন্সের জন্য অ্যান্ড্রয়েড অফিসিয়াল ডকুমেন্টেশনের সাথে একটি লিঙ্ক সংযুক্ত করেছি এবং আশা করি এটি এখনও এই সমাধানগুলির প্রয়োজন এমন লোকদের সহায়তা করবে। অ্যান্ড্রয়েডে কাস্টম ফন্টের সাথে কাজ করা


0

এটি জেনে রাখা কার্যকর হতে পারে যে অ্যান্ড্রয়েড 8.0 (এপিআই স্তর 26) থেকে শুরু করে আপনি এক্সএমএলে একটি কাস্টম ফন্ট ব্যবহার করতে পারেন

সহজ কথায় বলতে গেলে, আপনি এটি নিম্নলিখিত উপায়ে করতে পারেন।

  1. ফোল্ডারে ফন্টটি রাখুন res/font

  2. হয় এটি কোনও উইজেটের বৈশিষ্ট্যে ব্যবহার করুন

<Button android:fontFamily="@font/myfont"/>

বা এটি করা res/values/styles.xml

<style name="MyButton" parent="android:Widget.Button">
    <item name="android:fontFamily">@font/myfont</item>
</style>

এবং এটি একটি শৈলী হিসাবে ব্যবহার করুন

<Button style="@style/MyButton"/>

0

এক্সএমএল ফাইলে সরাসরি "হরফপথ" বৈশিষ্ট্যটি ব্যবহার করুন।

স্টাইল.এক্সএমএল ব্যবহারের জন্য

<আইটেমের নাম = "ফন্টপথ"> হরফ / প্রক্সিমানোভা সিমিবোল্ড.টিফ </ i>

সরাসরি লেআউট ফাইল ব্যবহার করার জন্য

ফন্টপাথ = "ফন্ট / ProximaNovaBold.ttf"

(দ্রষ্টব্য: প্রিফিক্সে অ্যাপ / অ্যান্ড্রয়েড অ্যাট্রিবিউট ব্যবহার করার দরকার নেই)


-6

একেবারে সম্ভব। এটি করার অনেক উপায়। দ্রুততম উপায়, চেষ্টা-ক্যাপচার পদ্ধতিতে শর্ত তৈরি করুন .. আপনার নির্দিষ্ট ফন্ট শৈলীর শর্তটি চেষ্টা করুন, ত্রুটিটি ধরুন এবং অন্য ফন্ট শৈলীর সংজ্ঞা দিন।


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