2010-01-22 18 views
39

ile birlikte kullanıldığında uygulanmadı. TextViewStone for textView öğesini kırmızı olarak belirten bir temam var.Tema/Stil, ApplicationContext

TextView'ı başlatmak için LayoutInflater kullanıyorum. Sorun, infiltre ApplicationContext kullanılarak oluşturulduğunda stiller TextView'a uygulanmadığıdır - renk kırmızı değil. LayoutInflater, etkinlik kullanılarak oluşturulduğunda tüm işlemler düzgün çalışır.

Neden böyle olur ve nasıl düzeltilebilir?

/res/values/styles.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <style name="MyTheme"> 
     <item name="android:textViewStyle">@style/MyTextView</item> 
    </style> 

    <style name="MyTextView" parent="@android:style/Widget.TextView"> 
     <item name="android:textColor">#f00</item> 
    </style> 
</resources> 

AndroidManifest.xml:

<application 
    android:icon="@drawable/icon" 
    android:label="@string/app_name" 
    android:theme="@style/MyTheme" 
    > 

Kodu:

public class A extends Activity { 

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

     final LayoutInflater goodInflater = getInflater((Activity)this); 
     final LayoutInflater badInflater = getInflater(getApplicationContext()); 
     final LinearLayout container = (LinearLayout)findViewById(R.id.container); 

     findViewById(R.id.add_with_appContext).setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       add(container, badInflater); // Creates gray TextView 
      }    
     }); 

     findViewById(R.id.add_with_activity).setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       add(container, goodInflater); // Creates red TextView 
      }    
     }); 
    } 

    private LayoutInflater getInflater(Context context) { 
     return (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    private void add(LinearLayout container, LayoutInflater inflater) { 
     inflater.inflate(R.layout.my_template, container, true); 
    } 
} 

/res/layout/test_a.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical"> 

    <Button 
     android:text="Add with AppContext" 
     android:id="@+id/add_with_appContext" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     /> 

    <Button 
     android:text="Add with Activity" 
     android:id="@+id/add_with_activity" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     /> 

    <LinearLayout 
     android:id="@+id/container" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" 
     /> 

</LinearLayout> 

/res/layout/my_template.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    > 

    <TextView 
     android:id="@+id/text" 
     android:text="Some text..." 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
    /> 

</LinearLayout> 

cevap

45

Çözüm # 1

şişirmek yöntemi seçmeli 'ViewGroup kök' argümanını kabul eder:

public View inflate (int resource, ViewGroup root, boolean attachToRoot) 

biz değeri varsa 'root' parametresi olarak geçiş yapabilmemiz için, 'LayoutInflater'ı doğru olarak alabileceğimiz' etkinlik bağlamı 'almak için kullanabiliriz:

ViewGroup root > activity context > LayoutInflater 
Yani benim kod olabilir:

private void add(LinearLayout container) { 
    LayoutInflater inflater = getInflater(container.getContext()); 
    inflater.inflate(R.layout.my_template, container, true); 
} 

2 Sadece programlı Uygulama Bağlam tema ayarlamak için çalıştı ve çalışır Çözüm #:

getApplicationContext().setTheme(R.style.MyTheme); 

bence Bu biçimlendirmeyi beklemek mantıklıydı:

Otomatik olarak ayarlamak için

.

+0

Sir faaliyet aynı temaya tutmak için neler olduğunu. Teşekkürler –

+0

Bu çok yanlış. Çalıştığını düşündüğünüz şekilde çalışmadığının bir nedeni var: bu şekilde çalışması gerekmiyor. etiketindeki tema özelliği, tüm etkinliklere uygulanan varsayılan değerdir. Diğer pek çok şey uygulama bağlamında çalışmaz, örneğin, yapılandırma değişikliklerine karşılık olarak değişen kaynakları sızdırmazsınız vb. – dcow

+0

Çözüm # 2 bir çekicilik gibi çalıştı. Benim uygulama şimdi muhteşem görünüyor. Teşekkürler! – Mauker

31

Görünümleri şişirmek için hiçbir zaman bir Uygulama Bağlamı kullanmayın, çünkü stil bu bağlamda çalışmaz. Görünümlü oynatırken her zaman bir Etkinliğin içeriğini kullanın. Tek istisna bir Servis'ten RemoteViews oluşturmanız gerektiğidir.

Farklı türlerde Bağlamlar ve özellikleri hakkında daha fazla bilgiyi in this excellent article bulabilirsiniz.

+2

Bu gerçekten doğru değil, şu anda uğraştığım bellek sızıntılarını önlemek için görünüm oluşturmak için Uygulama Bağlamı'nı kullanmanız önerilir. – David

+2

Görünümlerinizin nasıl kullanıldığına bağlı olarak değişir. Görüşleriniz bir Etkinliğin parçası değilse, o zaman Etkinliğin bağlamını kullanmamalısınız. – BladeCoder

+0

Günümü kurtardın. Teşekkürler –

0

Genellikle bu sorunu özel bir görünüme şişirmekle karşılaşıyorum.İşte Şahsen benim günü kurtardı CustomView

public class CustomView extends ViewGroup{ 

public CustomView (Context context) { 
    super(context); 
    init(context); 
} 

public CustomView (Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(context); 
} 

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

@TargetApi(21) 
public CustomView (Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
    super(context, attrs, defStyleAttr, defStyleRes); 
    init(context); 
} 

private void init(Context context) { 
    LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View v = mInflater.inflate(R.layout.review_list_item, this, true); 
    //rest of view initialization  
} 
} 
İlgili konular