当 Inflater 与 ApplicationContext 一起使用时,不应用主题/样式
我的主题将 TextView 的 textColor 指定为红色。
我正在使用 LayoutInflater 实例化 TextView。问题是,当使用 ApplicationContext 创建 inflater 时,样式不会应用于 TextView - 颜色不是红色。当使用 Activity 创建 LayoutInflater 时,一切正常。
为什么会发生这种情况,如何解决?
/res/values/styles.xml:AndroidManifest.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>
:
<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>
I have theme that specifies textColor for TextView as red.
I am using LayoutInflater to instantiate TextView. The problem is that styles are not applied to TextView when inflater created using ApplicationContext - the color is not red. All works fine when LayoutInflater created using activity.
Why this happens, and how can be fixed?
/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"
>
Code:
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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
解决方案#1
inflate 方法接受可选的“ViewGroup root”参数:
如果我们有值作为“root”参数传递,那么我们可以使用它来获取“活动上下文”,从中我们可以获取正确的 LayoutInflater:
所以我的代码可能是:
解决方案 # 2
只是尝试以编程方式设置应用程序上下文主题,并且它有效:
我认为期望此标记是合乎逻辑的
:自动设置它,但它没有。
Solution # 1
The inflate method accepts optional 'ViewGroup root' argument:
If we have value to pass as 'root' parameter, than hence we can use it to get 'activity context' from where we can get correct LayoutInflater:
So my code could be:
Solution # 2
Just tried to set Application Context theme programmatically, and it works:
I think it was logical to expect this markup:
to set it automatically, but it does not.
切勿使用应用程序上下文来扩充视图,因为样式不适用于此上下文。使用视图时始终使用 Activity 的上下文。唯一的例外是当您需要从服务创建 RemoteView 时。
有关不同类型的上下文及其功能的更多信息可以在中找到优秀的文章。
Never use an Application Context to inflate views, because styling doesn't work with this context. Always use an Activity's context when playing with views. The only exception is when you need to create RemoteViews from a Service.
More info about the different types of Contexts and their capabilities can be found in this excellent article.
您使用的上下文可能没有主题。
要解决此问题,请使用以下内容:
您可以阅读有关此内容的更多信息 这里
You probably use a context that isn't one that has a theme.
To solve it, use something as such:
You can read more about this here
我通常在膨胀自定义视图时遇到这个问题。这是我个人在 CustomView 中保持活动主题相同的方法
I usually come across this issue on inflating a custom view. Here is what I personally do to keep the same theme of the activity in the CustomView