Farnad Tohidkhah
Farnad Tohidkhah

Reputation: 1269

How to display Persian(Farsi) numbers in views

I want to display Persian(Farsi) numbers on views. For example I calculated a date and converted it to Jalali calendar but how can I display it by Persian numbers?

Upvotes: 34

Views: 13314

Answers (13)

ZIRES
ZIRES

Reputation: 405

To manage the application language (English / Persian), the font used in the application must convert and display the numbers in Persian and English correctly.

That's why we use the setTypeface() method:

public class MyTextView extends TextView {
        public MyTextView (Context context, AttributeSet attrs) {
            super(context, attrs);
            Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/iransans_fa_number_regular.ttf");
            setTypeface(typeface);
        }
    }

And when the language of the application changes, we change the font used in MyTextView :

public static String iranSansRegular;

public static void setLocale(Resources res, Context context) {
        SharedPreferences sharedPreferences = context.getSharedPreferences("Configuration", 0);
        String appLang = sharedPreferences.getString("appLanguage", Locale.getDefault().getLanguage());

        if (appLang.equals("fa")) {
            iranSansRegular = "fonts/iransans_fa_number_regular.ttf";
        } else {
            iranSansRegular = "fonts/iransans_en_number_regular.ttf";
        }

        Locale myLocale = new Locale(appLang);
        DisplayMetrics dm = res.getDisplayMetrics();
        Configuration conf = res.getConfiguration();
        conf.locale = myLocale;
        Locale.setDefault(myLocale);
        conf.setLayoutDirection(myLocale);
        res.updateConfiguration(conf, dm);
    }

And use the iranSansRegular to set typeface:

public class MyTextView extends TextView {
        public MyTextView (Context context, AttributeSet attrs) {
            super(context, attrs);
            Typeface typeface = Typeface.createFromAsset(context.getAssets(), iranSansRegular);
            setTypeface(typeface);
        }
    }

Upvotes: 1

ParSa
ParSa

Reputation: 1436

The simplest and easiest way is using NumberFormat :

NumberFormat numberFormat = NumberFormat.getInstance(new Locale("fa","IR"));
textView.setText(numberFormat.format(15000))

Upvotes: 5

aminography
aminography

Reputation: 22832

Kotlin Version via Extension Property

If you want to show every type of numbers (e.g. Int, Double, Float, etc) in Persian or Arabic digits, using these extension properties really helps:


PersianUtils.kt

/**
 * @author aminography
 */

val Number.withPersianDigits: String
    get() = "$this".withPersianDigits

val String.withPersianDigits: String
    get() = StringBuilder().also { builder ->
        toCharArray().forEach {
            builder.append(
                when {
                    Character.isDigit(it) -> PERSIAN_DIGITS["$it".toInt()]
                    it == '.' -> "/"
                    else -> it
                }
            )
        }
    }.toString()

private val PERSIAN_DIGITS = charArrayOf(
    '0' + 1728,
    '1' + 1728,
    '2' + 1728,
    '3' + 1728,
    '4' + 1728,
    '5' + 1728,
    '6' + 1728,
    '7' + 1728,
    '8' + 1728,
    '9' + 1728
)


Usage:

println("Numerical 15   becomes: " + 15.withPersianDigits)
println("Numerical 2.75 becomes: " + 2.75.withPersianDigits)

println("Textual 470  becomes: " + "470".withPersianDigits)
println("Textual 3.14 becomes: " + "3.14".withPersianDigits)

Result:

Numerical 15   becomes: ۱۵
Numerical 2.75 becomes: ۲/۷۵

Textual 470  becomes: ۴۷۰
Textual 3.14 becomes: ۳/۱۴

Upvotes: 6

Farnad Tohidkhah
Farnad Tohidkhah

Reputation: 1269

Another way to show numbers with Persian font is the use of following Helper Class:

public class FormatHelper {

    private static String[] persianNumbers = new String[]{ "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" };


    public static String toPersianNumber(String text) {
        if (text.length() == 0) {
            return "";
        }
        String out = "";
        int length = text.length();
        for (int i = 0; i < length; i++) {
        char c = text.charAt(i);
        if ('0' <= c && c <= '9') {
            int number = Integer.parseInt(String.valueOf(c));
            out += persianNumbers[number];
        }
        else if (c == '٫') {
            out += '،';
        }
        else {
            out += c;
        }

        return out;
    }
}

Save this class as UTF8 format and use it like the following code

FormatHelper.toPersianNumber(numberString);

Upvotes: 25

Vahid Rajabi
Vahid Rajabi

Reputation: 359

you can use Time4J to display date and use ChronoFormatter to display :

ChronoFormatter<PersianCalendar> formatter= ChronoFormatter.setUp(PersianCalendar.axis(), PERSIAN_LOCALE)
.addPattern("dd", PatternType.CLDR).build();
// it will display day :  ۲۴

or

.addPattern("dd MMMM", PatternType.CLDR).build();
// مرداد ۲۴

and with defining patterns you can choose how date display : ChronoFormatter

Upvotes: 2

Criss
Criss

Reputation: 785

try this while Typing For EditText:

 public static void edtNumE2P(final EditText edt) {
    edt.addTextChangedListener(new TextWatcher() {

      @Override
      public void onTextChanged(CharSequence s, int pstart, int pbefore, int pcount) {
//        for (String chr : new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}) {
        for (char chr : "0123456789".toCharArray()) {
          if (s.toString().contains("" + chr)) {
            edt.setText(MyUtils.numE2P(edt.getText().toString()));
            edt.setSelection(edt.getText().length());
          }
        }
      }


      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after) {

      }


      @Override
      public void afterTextChanged(Editable s) {
      }
    });
  }

And Try This too :

    public static String numE2P(String str, boolean reverse) {
    String[][] chars = new String[][]{
      {"0", "۰"},
      {"1", "۱"},
      {"2", "۲"},
      {"3", "۳"},
      {"4", "۴"},
      {"5", "۵"},
      {"6", "۶"},
      {"7", "۷"},
      {"8", "۸"},
      {"9", "۹"}
    };

    for (String[] num : chars) {
      if (reverse) {
        str = str.replace(num[1], num[0]);
      } else {
        str = str.replace(num[0], num[1]);
      }
    }
//    Log.v("numE2P", str);
    return str;
  }

Upvotes: 2

Dariush Malek
Dariush Malek

Reputation: 914

The simple and correct way is to use Locale and String.format. You can simply use a Persian font for the view in case the default font does not support Persian numbers. Here's how I would do it.

Locale locale = new Locale("fa");
return String.format(locale, "%04d", year) + "/" + 
       String.format(locale, "%02d", month) + "/" + 
       String.format(locale, "%02d", day);

You could also use PersianCaldroid library, which not only provides you with simple APIs like PersianDate.toStringInPersian() but also lets you have Persian DatePicker and CalendarView.

Upvotes: 2

babak
babak

Reputation: 71

Simply do it in kotlin for unsigned integers

fun toPersian(n:Int) : String{
val p="۰۱۲۳۴۵۶۷۸۹"
return n.toString().trim().map{
    p[it.toString().trim().toInt()]
}.joinToString()
}
txt_view?.text=toPersian(12087)//۱۲۰۸۷

Upvotes: 1

Hossein Bagheri
Hossein Bagheri

Reputation: 21

You can use the following method to display the number in Persian :

 public String NumToPersion(String a){
    String[] pNum =new String[]{"۰","۱","۲","۳","۴","۵","۶","۷","۸","۹" };
    a=a.replace("0",pNum[0]);
    a=a.replace("1",pNum[1]);
    a=a.replace("2",pNum[2]);
    a=a.replace("3",pNum[3]);
    a=a.replace("4",pNum[4]);
    a=a.replace("5",pNum[5]);
    a=a.replace("6",pNum[6]);
    a=a.replace("7",pNum[7]);
    a=a.replace("8",pNum[8]);
    a=a.replace("9",pNum[9]);
   return a;
}

Upvotes: 1

Farnad Tohidkhah
Farnad Tohidkhah

Reputation: 1269

By using Typeface class the font type of a view can be changed to Farsi font so the numbers can be shown by Farsi fonts :

Typeface typeface = Typeface.createFromAsset(getAssets(), "FarsiFontName.ttf");
myView.setTypeface(typeface);

Upvotes: 16

you must add the persian standard keyboard in windows and change to this keyboard when you want to type persian digits and words. It is work for me

Upvotes: -1

SMahdiS
SMahdiS

Reputation: 940

set the locale to Arabic, Egypt

int i = 25;
NumberFormat nf = NumberFormat.getInstance(new Locale("ar","EG"));
nf.format(i);

Upvotes: 5

user4790312
user4790312

Reputation:

You can create custom view and attach farsi font on that, finally you can use that on xml views.most farsi font dont have english number in character map and you can use simply that without any problem. for example :

public class TextViewStyle extends TextView {

    public TextViewStyle(Context context) {
        super(context);
        init(context, null, 0);
    }


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


    public TextViewStyle(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle){
        try {
            TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.TextViewStyle, defStyle, 0);
            String str = a.getString(R.styleable.TextViewStyle_fonttype);
            switch (Integer.parseInt(str)) {
                case 0:
                    str = "fonts/byekan.ttf";
                    break;
                case 1:
                    str = "fonts/bnazanin.ttf";
                    break;
                case 2:
                    str = "fonts/btitr.ttf";
                    break;
                case 3:
                    str = "fonts/mjbeirut.ttf";
                    break;
                case 4:
                    str = "fonts/bnazanin_bold.ttf";
                    break;
                default:
                    str = "fonts/bnazanin.ttf";
                    break;
            }
            setTypeface(FontManager.getInstance(getContext()).loadFont(str));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

attr.xml :

<declare-styleable name="TextViewStyle">
    <attr name="selected_background" format="integer"/>
    <attr name="fonttype">
        <enum name="byekan" value="0"/>
        <enum name="bnazanin" value="1"/>
        <enum name="btitr" value="2"/>
        <enum name="mjbeirut" value="3"/>
        <enum name="bnazaninBold" value="4"/>
    </attr>
</declare-styleable>

Upvotes: 4

Related Questions