2012-05-21 110 views
1

在這裏搜索了幾個小時並測試了這個,我既不能解決我的問題,也沒有發現任何問題/答案適用於我的問題 - 但也許我只使用錯誤的搜索條件 - 所以我很感謝任何提示正確的方向!如何應用主題特定樣式?

基本上它是關於使用2個主題(黑暗&光)的應用程序,其中一些TextView顯示狀態 - 狀態可以是開或關,爲了更好地識別狀態,文本的顏色應該反映狀態:紅色表示關閉,綠色表示打開。

當我沒有使用任何主題或風格,我只是用TextView的的.setColor(#FFFF0000)爲紅色,等等...

然後,我開始利用黑暗/輕量級主題可以在不同情況下提高可視性 - 例如在白色背景上的戶外黑色文本更容易閱讀。

所以我定義我的2個主題,覆蓋textAppearance:

<style name="Theme.MyApp" parent="Theme.Sherlock"> 
... 
<item name="android:textAppearance">@style/TextNormal</item> 
... 
</style> 

<style name="Theme.MyApp.Light" parent="Theme.Sherlock.Light"> 
... 
<item name="android:textAppearance">@style/TextNormalLight</item> 
... 

<style name="TextNormal"> 
    <item name="android:textColor">#ffffffff</item> 
</style> 

<style name="TextNormalLight"> 
    <item name="android:textColor">#ff000000</item> 
</style> 

這工作得很好,並且「正常」 textviews顯示在根據主題正確的顏色。到現在爲止還挺好!

而不是使用TextView的setColor,我切換到使用.setTextAppearance tv.setTextAppearance(getSherlockActivity(),R.style.TextRed);

,並定義了一些樣式(僅粘貼一個,其他都是TextGreen,...):

<style name="TextRed"> 
    <item name="android:textColor">#ffff0000</item> 
</style> 

這也能正常工作!

,並終於得到我的問題:

現在我想爲「紅」因主題不同的顏色...

,所以我保持TextRed風格,並添加樣式在燈光主題使用,用於測試,我只是做了一個奇怪的顏色,看看它的工作:

<style name="TextRedLight"> 
    <item name="android:textColor">#ffffff00</item> 
</style> 

這也是工作的,如果我把周圍的TextView的.setTextAppearance switch語句,並選擇正確的樣式取決於所選主題 - 僞代碼:

switch (currentheme) { 
    case Dark: tv.setTextAppearance(... R.style.TextRed); break; 
    case Light: tv.setTextAppearance(... R.style.TextRedLight); break; 
} 

和現在的挑戰/問題是 - 我如何避免switch語句?

當引用layout.xml文件中的樣式時,我們可以使用?引用榮譽當前主題...(而不是「@」)

在這種情況下,我需要在運行時設置樣式兌現主題:所以它必須由代碼完成而不是由xml - 但setTextAppearance只接受一個id的風格,而不是一個主題通配符+ id ...

和這個我在哪裏卡住了...是的,我可以包裝一個類,並保持它在代碼中的一行,並「隱藏」在這個類中的主題檢測/開關語句,但另一方面 - Android的複雜風格/主題架構應該也有這個問題的解決方案,不應該...... ?

使用的主題和風格似乎有點懵了,只要需要helperclasses或交換機/ if語句來完成一些增強的東西...

感謝任何提示/想法!

編輯1 - 托馬什回答後: 更新style.xml:

<style name="TextNormal" parent="Theme.ARMoDroid"> 
    <item name="android:textColor">#ffffffff</item> 
</style> 
<style name="TextNormal" parent="Theme.ARMoDroid.Light"> 
    <item name="android:textColor">#ff000000</item> 
</style> 
<style name="TextRed" parent="Theme.ARMoDroid"> 
    <item name="android:textColor">#ffff0000</item> 
</style> 
<style name="TextRed" parent="Theme.ARMoDroid.Light"> 
    <item name="android:textColor">#ffffff00</item> 
</style> 

在layout.xml的分配與TextNormal TextViews,或這兩個主題與參考TextNormal時:

<item name="android:textAppearance">@style/TextNormal</item> 

用紅色文字時也可以作爲之前(與此不同的方法)。

但在最初的問題仍然存在: 當我想改變(在運行時)文字爲紅色的顏色,使用

tv.setTextAppearance(getActivity(),R.style.TextRed) 

它總是使用TextRed的最後一個定義 - 因此與上述定義,文本將以黃色着色#ffffff00 - >。當我交換2個TextRed定義的順序時,它使用最後一個定義 - #ffff0000 - 並且文本是紅色的。

所以在運行時設置樣式時,setTextAppearance不是主題感知 - 它不會將當前的主題和2種定義的樣式區分。

我們可以根據主題定義一個具有不同textcolor值的樣式,並根據所選主題着色正確 - 只要它的樣式是在layout.xml中分配的,或者主題集的此樣式爲默認。

,但在運行時代碼動態切換的樣式時,我們仍然需要像上面的開關語句 - 檢測選擇了哪個主題,根據主題,採用不同的風格TextView的。

我想要實現的是,它應該選擇取決於當前的主題正確的「TextRed」的風格。所以沒有必要硬編碼的主題意識......一旦一個新的主題被添加提到的開關語句必須被更新...

編輯2:我目前的「解決方案」

我想我可能也會發布當前的解決方案,但這不是一個很好的解決方案 - 雖然它正在工作 - 但它是針對每種風格的自定義代碼,而與另一個主題相比,代碼更多...

輔助函數看起來像:

 public static int getThemedStyle(int normalStyle) { 
    if (prefs==null) { prefs = PreferenceManager.getDefaultSharedPreferences(appContext); } 
    int theme = Integer.valueOf(prefs.getString("GUI_Theme","0")); 
    if (theme==0) return normalStyle; //dark theme 
    else { //return correct Light-Theme Style 
     switch (normalStyle) { 
      case R.style.TextNormal: return R.style.TextNormalLight; 
      case R.style.TextRed: return R.style.TextRedLight; 
      case R.style.TextOrange: return R.style.TextOrangeLight; 
      case R.style.TextGreen: return R.style.TextGreenLight; 
      case R.style.TextYellow: return R.style.TextYellowLight; 
      case R.style.TextBlue: return R.style.TextBlueLight; 
      default: return normalStyle; 
     } //switch 
    } //else theme==0 
} //getThemedStyle 

片段中我通過調用上述功能上的onCreate緩存風格參考:

styleRed = preferences.getThemedStyle(R.style.TextRed); 
styleOrange = preferences.getThemedStyle(R.style.TextOrange); 
styleGreen = preferences.getThemedStyle(R.style.TextGreen); 

最後分配使用style:

tv.setTextAppearance(getSherlockActivity(), styleRed); 

工作,但複雜的,如果這就是它itended方式是,很傷心...;)

回答

0

回答我的問題:

found this

所以不是我的 - 工作 - switchstatement,還是有必要對一些代碼,但它至少沒有主題ID的硬編碼,... - >更新我的getThemedStyle與此片段

public static int getThemedStyle(int normalStyle) { 
Resources.Theme theme = appContext.getTheme(); 
TypedValue styleID = new TypedValue(); 
if (theme.resolveAttribute(R.attr.TextAppRed, styleID, true)) return styleID.data; 
    else return normalStyle; 
} //getThemedStyle 
1

你試過這個嗎?

<style name="Theme.MyApp" parent="Theme.Sherlock"> 
... 
</style> 

<style name="Theme.MyApp.Light" parent="Theme.Sherlock.Light"> 
... 
</style> 

<style name="TextNormal" parent="Theme.MyApp"> 
    <item name="android:textColor">#ffffffff</item> 
</style> 

<style name="TextNormal" parent="Theme.MyApp.Light"> 
    <item name="android:textColor">#ff000000</item> 
</style> 

參考layout.xml是:

<TextView style="@style/TextNormal" .../> 
+0

Tomáš - 感謝您的回答!有一些希望我嘗試了你的想法,但它並沒有解決問題 - 爲了更好的可讀性,我編輯/添加了上述問題的結果。只要風格分配我靜態(通過layout.xml),但它失敗(像我的)時更改每個代碼的樣式:(你的方法是好的和工作(像我一樣):( – smartinick

相關問題