2011-10-05 26 views
2

我正在爲此SO問題找到接受的答案和討論getString Outside of a Context or Activity不清楚。在模型對象中引用Strings.XML以支持本地化

我是新來的Android,我想了解如何在模型類中引用我的資源字符串,以便我可以正確支持本地化。

具體來說,我的模型有一個位置屬性,我希望能夠返回一個字符串作爲方位的指南針序號。因爲像「北」這樣的指南針序號需要進行本地化,所以我試圖將它們存儲在我的strings.xml中。

我想我明白我需要應用程序上下文來獲取資源對象,但我想知道這是不可能的,而不必傳遞上下文。在模型中存儲UI上下文似乎違反了MVC 。

爲了達到這個目的,我希望在我的模型中包含一個像這樣的方法。第一個if顯示我如何使用strings.xml條目。

public String compassOrdinalForBearing(float bearing) { 

assert bearing >= 0.0 && bearing <= 360.0; 

if ((bearing > 336.5) && (bearing <= 360.0)) 
    //Problem here 
    return Context.getResources().getString(R.string.compass_ordinal_north); 
else if ((bearing >= 0) && (bearing <= 22.5)) 
    return "North"; 
else if ((bearing > 22.5) && (bearing <= 67.5)) 
    return "Northeast"; 
else if ((bearing > 67.5) && (bearing <= 112.5)) 
    return "East"; 
else if ((bearing > 112.5) && (bearing <= 157.5)) 
    return "Southeast"; 
else if ((bearing > 157.5) && (bearing <= 202.5)) 
    return "South"; 
else if ((bearing > 202.5) && (bearing <= 247.5)) 
    return "Southwest"; 
else if ((bearing > 247.5) && (bearing <= 292.5)) 
    return "West"; 
else if ((bearing > 292.5) && (bearing <= 337.5)) 
    return "Northwest"; 
else 
    assert false; 
    return null; 
} 

回答

3

通常做的是子類化Application類,它保證只有一個實例。

Application子類:

public class MyApplication extends Application { 
    private static Context mContext; 

    @Override 
    public void onCreate(){ 
     super.onCreate(); 
     mContext = this; 
    } 

    public static Context getContext(){ 
     return mContext; 
    } 
} 

你的類:

public String compassOrdinalForBearing(float bearing) { 
    Context context = MyApplication.getContext(); 

    String north = context.getResources().getString(R.string.compass_ordinal_north);) 
} 

但是不要忘記更改清單:

<application android:name="com.example.myapp.MyApplication"> 

或者你可以在剛剛通過的情況下實例化,而不保留一個指針,因爲幾乎肯定這些對象將從一個實例化上下文。

private Static string NORTH = null; 

public MyClass(Context context){ 
    initializeDirections(context); 
} 

private static void initializeDirections(Context context){ 
    if(NORTH == null){ 
     NORTH = context.getResources().getString(R.string.compass_ordinal_north); 
    } 
} 

最後一種兩者的雜亂組合以防萬一你真的不能在實例上下文傳遞,你不希望保留在應用程序子類的應用程序上下文:

public class MyApplication extends Application { 
    @Override 
    public void onCreate(){ 
     super.onCreate(); 
     MyClass.initializeDirections(this); 
    } 
} 

public class MyClass{ 
    private static String NORTH = null; 

    public static final void initializeDirections(Context context){ 
     NORTH = context.getResources().getString(R.string.compass_ordinal_north); 
    } 
} 

編輯:在一個不相關的說明中,至少從這個唯一的片段中,可以殺死所有的第一個條件。如果它已經達到那個特定的「其他」,那麼第一個條件必然是真的。

例如:

else if ((bearing >= 0) && (bearing <= 22.5)) 
    return "North"; 
else if ((bearing > 22.5) && (bearing <= 67.5)) 
    return "Northeast"; 

可能是:

else if (bearing <= 22.5) 
    return "North"; 
else if (bearing <= 67.5) 
    return "Northeast"; 

彷彿bearing是! < = 22.5,它必然> 22.5。

這可能會也可能不會提高您的可讀性,並且可能會或可能不需要您。只是一些可能不需要兩美分:)

+0

這可能是我在SO上收到的最有幫助的答案。感謝您詳細介紹不同的方法。應用程序子類化現在完全適合我的需求。在If塊中,我只是明確地將範圍拼出來,但是這不是評估事物的最有效方式 - 可讀性和效率之間的平衡總是很棘手,所以將其最小化是一個很好的觀點。再次感謝優秀的寫作。 – Nick

0

但我不知道這是否可能,而不必通過上下文

不,您需要通過上下文英寸

我想唯一的您需要本地化字符串資源的地方就是一些用戶界面。 UI始終是某個Activity(也是Context)的一部分,所以當您需要爲模型獲取本地化字符串時,有一個Context實例應該不成問題。

+0

所以,如果我創建說500模型實例。在每個存儲上下文實例是正常的? – Nick

+0

@Nick:當然,您不應該在模型中保留對Context實例的引用。您只需要爲模型生成UI表示。因此,Activity中的一些代碼應該能夠從模型中獲得本地化的UI表示。要獲得'Resources'實例,你需要'Context'實例。爲了優化代碼,您可以將'Resources'實例傳遞給Model而不是'Context'實例。 –