Android: Adını kullanarak kaynaklardan dize nasıl alabilirim?


553

Kaynak dosyamda kullanıcı arayüzü için 2 dilde ve ayrı dize değerlerine sahip olmak istiyorum res\values\strings.xml:

<string name="tab_Books_en">Books</string>
<string name="tab_Quotes_en">Quotes</string>
<string name="tab_Questions_en">Questions</string>
<string name="tab_Notes_en">Notes</string>
<string name="tab_Bookmarks_en">Bookmarks</string>

<string name="tab_Books_ru">Книги</string>
<string name="tab_Quotes_ru">Цитаты</string>
<string name="tab_Questions_ru">Вопросы</string>
<string name="tab_Notes_ru">Заметки</string>
<string name="tab_Bookmarks_ru">Закладки</string>

Şimdi bu değerleri uygulamamda dinamik olarak almam gerekiyor:

spec.setContent(R.id.tabPage1);
String pack = getPackageName();
String id = "tab_Books_" + Central.lang;
int i = Central.Res.getIdentifier(id, "string", pack);
String str = Central.Res.getString(i);

Benim sorunum bu i = 0.

Benim durumumda neden çalışmıyor?


1
Central.lang'ın ya enda olduğundan emin misiniz ru?
K-ballo

1
Kodunuzu incelemek için daha fazla bilgi gerekiyor. i almadan önce her bir varlığın durumu nedir? Her neyse, işleri basitleştirmek için Android'deki varsayılan yerelleştirme desteğini kullanmalısınız.
Alin

Yanıtlar:


1069

Bahsettiğiniz bağlantı, çalışma zamanında oluşturulan dizelerle çalışıyor gibi görünüyor. Strings.xml dosyasından dizeler çalışma zamanında oluşturulmaz. Onları şu yolla alabilirsiniz:

String mystring = getResources().getString(R.string.mystring);

getResources()Contextsınıfın bir yöntemidir . Bir Activityveya bir Service(İçeriği genişleten) içindeyseniz , bu snippet'teki gibi kullanabilirsiniz.

Ayrıca , tüm dil bağımlılığının android çerçevesi tarafından ele alınabileceğini unutmayın . Her dil için farklı klasörler oluşturun. Varsayılan diliniz ingilizce ise, ingilizce dizgilerini girin res/values/strings.xml. Ardından yeni bir klasör oluşturun values-ruve aynı adlara sahip rus dizelerini ekleyin res/values-ru/strings.xml. Bu noktadan itibaren android, aradığınızda getString()veya XML'deki dizelere başvururken sizin için cihazın yerel ayarına bağlı olarak doğru olanı seçer @string/mystring. Bunların res/values/strings.xmlyedeği, kullanıcıların yerel ayarlarını kapsayan bir klasörünüz yoksa, bu varsayılan değerler olarak kullanılacaktır.

Daha fazla bilgi için Yerelleştirme ve Kaynak Sağlama konusuna bakın .


23
Eğer bir android.support.v4.app.Fragmentyerdeyseniz, getString(R.string.mystring)doğrudan arayabilirsiniz .
JaKXz

3
Sadece wodering yapıyordum. Neden (google tarafından) bu kadar karmaşık bir şekilde yapılır? Önce mystring (R nesnesinden) sayısal kimliğini almak ve sonra bu kimliğe göre dizeyi almak? Ve "ID-of-mystring => actualValue" çifti aslında nerede? Bildiğim kadarıyla mystring => mystring kimliği R.java'da, ama bu kadar :)
Lukáš Řádek

2
"R" projenizin R varsayılan android R değil emin olun
ralphgabb

2
Bu gerekli olan cevap olabilir ama istenen cevap bu değildi! Bir dizgi kaynağına dinamik olarak adıyla erişmek için, kabul edilen bir IMO olması gereken @leonvian'dan gelen cevaba bakın
Chris Hatton

321

Aynı problemim var. Ancak aşağıdaki kod benim için çalışıyor: packageName'inizin doğru olup olmadığını kontrol edin. Android uygulamanızın kök paketine başvurmanız gerekir.

private String getStringResourceByName(String aString) {
      String packageName = getPackageName();
      int resId = getResources().getIdentifier(aString, "string", packageName);
      return getString(resId);
    }

9
Birinin bunu yapmak için iyi bir nedeni varsa (örneğin, veri dosyaları hangi kaynak dizesinin görüntülenmesi gerektiğine karar veren özel bir dize içerir veya bu dize Internet'ten getirilirse) - o zaman şunu belirtmek isterim bu çözüm doğru çözümdür. Özellikle kaynak türünün olduğu stringve değil olduğu kısmı düzeltin strings. Çünkü bu mantıklı (Android'in geri kalanı gibi). Bunun için teşekkürler (ve daha fazlası), @leonvian. :-)
Ivan Vučica

2
@Sizeer Dizeler tarafından bir dizi almak için sadece kullanın: res.getStringArray (R.array.planets_array); Bu resmi bağlantıya bir göz atın: developer.android.com/guide/topics/resources/…
leonvian

3
Güzel. Ayrı bir yöntem bildiriminde kurtulmak için, bu şekilde "basitleştirilmiş" olabilir: String someStringFromXML = getString(getResources().getIdentifier("some_string_name", "string", getPackageName()));.
Nörotransmitter

80

Yalnızca etkinliklerden değil:

    public static String getStringByIdName(Context context, String idName) {
        Resources res = context.getResources();
        return res.getString(res.getIdentifier(idName, "string", context.getPackageName()));
    }

harika çalıştı teşekkür ederim
Mosa

39
getResources().getString(getResources().getIdentifier("propertyName", "string", getPackageName()))

26

Leonvian çözümüne bir şey eklerdim, bu yüzden dize kaynaklar arasında (dönüş değeri 0, geçerli bir kaynak kodu değil) arasında bulunmazsa, işlev bir şey döndürebilir:

private String getStringResourceByName(String aString) {
    String packageName = getPackageName();
    int resId = getResources()
            .getIdentifier(aString, "string", packageName);
    if (resId == 0) {
        return aString;
    } else {
        return getString(resId);
    }
}

15

En İyi Yaklaşım

App.getRes().getString(R.string.some_id)

Her yerde çalışacaktır (Utils, Modeller de).

Tüm cevapları okudum, tüm cevaplar işinizi yapabilir.

  • Sen kullanabilirsiniz getString(R.string.some_string_id)hem Activityya Fragment.
  • Yönteme Context.getString(R.string.some_string_id)doğrudan erişiminizin olmadığı yerlerde kullanabilirsiniz getString(). Gibi Dialog.

Sorun

Ne zaman sende olmayan Contexterişimi sizin de bir yöntem gibi, Utilsınıfın.

Aşağıdaki yöntemi Bağlam olmadan varsayalım.

public void someMethod(){
    ...
    // can't use getResource() or getString() without Context.
}

Şimdi Contextbu yöntemde bir parametre olarak geçeceksiniz vegetString().

public void someMethod(Context context){
    ...
    context.getString(R.string.some_id);
}

Yaptığım şey

public void someMethod(){
    ...
    App.getAppResources().getString(R.string.some_id)
}

Ne? Uygulamanızın herhangi bir yerinde kullanmak çok basit!

İşte kaynaklara herhangi bir yerden erişebileceğiniz bir çözümUtil class .

import android.app.Application;
import android.content.res.Resources;

public class App extends Application {
    private static Resources resources;

    @Override
    public void onCreate() {
        super.onCreate();

        resources = getResources();
    }

    public static Resources getAppResources() {
        return resources;
    }

}

manifest.xml <applicationEtiketinize ad alanı ekleyin .

<application
        android:name=".App"
        ...
        >
        ...
    </application>

Şimdi gitmekte fayda var. App.getAppResources().getString(R.string.some_id)Uygulamada herhangi bir yerde kullanın .


+1 basit ve temiz bir çözüm. Kötü yazım dikkat edin getResourses, getResourcesgeçersiz kılma neden olur. Ayrıca singleton deseni gereksiz görünüyor, muhtemelen atlanabilir. Bu çözümde bellek sızıntısı var mı?
Xarvalus

@Xarvalus Bu bellek sızıntısı yapıyor mu?
Khemraj

benim app hepsi iyi :) sadece herkes onunla herhangi bir sorun olup olmadığını merak. Herhangi bir tuzakla karşılaşırsam haber vereceğim.
Xarvalus

1
@Xarvalus Bellek Sızıntısı genellikle, üst sınıf yok olsa bile bir değişkenin kullanıldığı yerde meydana gelir. Etkinlikler, Parçalar gibi. Bu durumda olacağını sanmıyorum.
Khemraj


14

Kaynak dizgiyi dizeden bir TextView içine almanın basit bir yolu. Burada resourceName kaynağın adıdır

int resID = getResources().getIdentifier(resourceName, "string", getPackageName());
textview.setText(resID);

7

Etkinlik referansınız yoksa, bağlamınızı şu şekilde kullanabilirsiniz:

getContext().getString(R.string.your_string_name);

4

Ayrıca "Tamam", "İptal" ve diğerleri gibi önceden tanımlanmış bir Android dizeleri de vardır - bu yüzden hepsini beyan etmek zorunda değilsiniz. Bunlar sadece şu şekilde kullanılabilir:

getString(android.R.string.ok)

(Bu durumda, "Tamam" dizesi). BTW, örneğin simge görüntüleri vb.Gibi diğer Android kaynakları da vardır.


2

Dize myString = getString (R.string.mystring);

kolay yol


1

Bunu bir Aktivitede deneyebilirsiniz:

getResources().getString(R.string.your string name);

Parçalar gibi diğer durumlarda ... kullanın

getContext().getResources().getString(R.string.your string name);

0

Güvenli olması için şunları eklemeniz gerekir: mContext.getResources (). GetString (R.string.your_string);

mContext şu olabilir: Fragment'ın onAttach () öğesinde veya bu Aktivitenin bağlamı.


0

Bir etkinliğin veya fragmnet'in içine girmezseniz, o zaman:

getContext().getResources().getString(R.string.string_name);

Etkinlik kapsamı olmayan etkinlik veya parça dışındaki bir sınıftan almak istiyorsanız uygulama bağlamını kullanın:

getApplicationContext().getResources().getString(R.string.string_name);

0
R.string.<string_name>

Bu satırı doğrudan java dosyanızda kullanın. Basit tutun.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.