使用ApplicationContext的inflater时不应用主题/样式

我有主题,指定为TextView TextColor红色。

我正在使用LayoutInflater来实例化TextView。 问题是当使用ApplicationContext创build的inflater时,样式不适用于TextView – 颜色不是红色。 当使用活动创buildLayoutInflater时,所有工作正常。

为什么会发生这种情况,如何解决?

/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" > 

码:

 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> 

解决scheme#1

inflate方法接受可选的“ViewGroup root”参数:

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

如果我们有作为'root'parameter passing的值,那么我们可以使用它来从'我们可以得到正确的'LayoutInflater'获得'activity context'

 ViewGroup root > activity context > LayoutInflater 

所以我的代码可能是:

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

解决scheme#2

只是尝试以编程方式设置应用程序上下文主题,它的工作原理

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

我认为期待这个标记是合乎逻辑的:

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

自动设置它,但它不会。

切勿使用应用程序上下文来膨胀视图,因为样式不适用于此上下文。 玩视图时总是使用一个Activity的上下文。 唯一的例外是当您需要从服务创buildRemoteViews。

关于上下文的不同types及其function的更多信息可以在这篇优秀的文章中find。

我通常在夸大自定义视图时遇到这个问题。 以下是我亲自做的保持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 } }