为片段设置主题

use*_*691 103 android android-theme android-fragments

我正在尝试为片段设置主题.

在清单中设置主题不起作用:

android:theme="@android:style/Theme.Holo.Light"
Run Code Online (Sandbox Code Playgroud)

通过查看以前的博客,似乎我必须使用ContextThemeWrapper.任何人都可以参考我的编码示例吗?我找不到任何东西.

Dav*_*vid 171

在清单中设置主题通常用于Activity.

如果要设置Theme for Fragment,请在Fragment的onCreateView()中添加下一个代码:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // create ContextThemeWrapper from the original Activity Context with the custom theme
    final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.yourCustomTheme);

    // clone the inflater using the ContextThemeWrapper
    LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);

    // inflate the layout using the cloned inflater, not default inflater
    return localInflater.inflate(R.layout.yourLayout, container, false);
}
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用.片段仍具有清单文件中指定的相同主题. (24认同)
  • @David"在清单中设置主题用于活动".这不完全正确.如果您使用FragmentTransaction在运行时添加Fragment,那么主题也应用于Fragments. (8认同)
  • 这似乎不适用于ActionBarSherlock库中的SherlockFragmentActivity. (3认同)

Poi*_*ull 14

Fragment以其Activity为主题.每个片段都被分配了它所在的Activity的主题.

该主题应用于Fragment.onCreateView方法,其中您的代码创建视图,这些视图实际上是使用主题的对象.

在Fragment.onCreateView中,您获得了LayoutInflater参数,该参数可以扩展视图,并且它保存用于主题的Context,实际上这是Activity.因此,您的虚增视图使用Activity的主题.

要覆盖主题,您可以调用LayoutInflater.cloneInContext,在Docs中提到它可以用于更改主题.您可以在此处使用ContextThemeWrapper.然后使用克隆的inflater创建片段的视图.


Bru*_*ill 12

我还试图让我的片段对话框显示与其活动不同的主题,并遵循此解决方案.就像评论中提到的一些人一样,我没有让它工作,对话框一直显示清单中指定的主题.问题原来是我AlertDialog.BuilderonCreateDialog方法中使用构建对话框,因此没有使用onCreateView我链接到的答案中显示的方法.当我实例化时,AlertDialog.Builder我正在使用getActivity()当我应该使用实例化的时候传递上下文ConstextThemeWrapper.

这是我的onCreateDialog的代码:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    // Create ContextThemeWrapper from the original Activity Context
    ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(getActivity(), android.R.style.Theme_DeviceDefault_Light_Dialog);
    LayoutInflater inflater =   getActivity().getLayoutInflater().cloneInContext(contextThemeWrapper);
    // Now take note of the parameter passed into AlertDialog.Builder constructor
    AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);
    View view = inflater.inflate(R.layout.set_server_dialog, null);
    mEditText = (EditText) view.findViewById(R.id.txt_server);
    mEditText.requestFocus();  // Show soft keyboard automatically
    mEditText.setOnEditorActionListener(this);
    builder.setView(view);
    builder.setTitle(R.string.server_dialog);
    builder.setPositiveButton(android.R.string.ok, this);
    Dialog dialog = builder.create();
    dialog.setCanceledOnTouchOutside(false);
    return dialog;
}
Run Code Online (Sandbox Code Playgroud)

我最初的AlertDialog.Builder实例化如下:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
Run Code Online (Sandbox Code Playgroud)

我改为:

AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);
Run Code Online (Sandbox Code Playgroud)

在此更改后,片段对话框显示正确的主题.因此,如果其他人遇到类似的问题并且正在使用,AlertDialog.Builder则检查传递给构建器的上下文.希望这可以帮助!:)


Nir*_*ula 12

android:theme = "@style/myTheme"我使用片段的布局文件解决了这个问题。例如,这会改变 的样式及其LinearLayout内容,但不会改变 之外的任何内容LinearLayout。因此,为了用任何样式装饰整个片段,请将主题应用于其最外层的父布局。

注意:如果您还没有找到解决方案,可以尝试一下。

<LinearLayout 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:theme = "@style/myTheme" >

    <TextView
        android:id="@+id/tc_buttom_text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Time elapsed"/>

    <TextView
        android:id="@+id/tc_buttom_text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="00:00:00 00"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)


seb*_*ter 9

确保已android:minSdkVersion="11"在清单中设置.这可能是大卫的榜样不适合你的原因.

此外,设置android:theme="@android:style/Theme.Holo.Light"该属性<application>标签和NOT<activity>标签.

另一个可能的问题可能是您在使用时获取Context的方式ContextThemeWrapper().如果您使用的话getActivity().getApplicationContext()只需替换它getActivity().

通常,Theme.Holo应该应用于链接到MainActivity的Fragments.

请注意,如果要为Fragment 应用不同的主题,请使用ContextThemeWrapper .如果您在MainActivity中提供添加片段的代码,这可能会有所帮助.


一些有用的链接:

Fragment中的自定义ListView不遵循父主题


Tom*_*ask 9

对于应用我曾经使用过的单一风格

getContext().getTheme().applyStyle(styleId, true);
Run Code Online (Sandbox Code Playgroud)

onCreateView()该片段的膨胀所述片段的根视图,它为我工作.


小智 8

我尝试了大卫建议它确实有效的解决方案,但并非在所有情况下:
1.对于添加到堆栈的第一个片段具有活动的主题而不是在onCrateView中定义的那个,但在第二个片段上我添加到堆栈正确它们应用于片段.

2.在正确显示它们的第二个片段上,我做了以下操作,我通过清理内存强制关闭App,重新打开App,当用片段重新创建Activity时片段改变了它们错误的它们活动,而不是片段的onCrateView中设置的活动.

为了解决这个问题,我做了一个小改动,并用inflater.inflate替换了容器参数.

我不知道inflater在某些情况下使用容器视图中的上下文.

注意 - 即时通讯使用android.support.v4.app.Fragment和android.support.v7.app.AppCompatActivity.

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle   savedInstanceState) {

// create ContextThemeWrapper from the original Activity Context with the custom theme 
final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.yourCustomTheme);

// clone the inflater using the ContextThemeWrapper 
LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);

// inflate the layout using the cloned inflater, not default inflater 
return localInflater.inflate(R.layout.yourLayout, null, false);
} 
Run Code Online (Sandbox Code Playgroud)


小智 8

我知道它有点晚了,但它可能会帮助其他人,因为这对我有帮助。您也可以尝试在片段的 onCreatView 函数中添加下面的代码行

    inflater.context.setTheme(R.style.yourCustomTheme)
Run Code Online (Sandbox Code Playgroud)

  • 它对我有用,但我想知道这种方法是否会对其他视图产生副作用。就我而言,上下文是 MainActivity,然后我将覆盖 MainActivity 的主题。是否有意义? (3认同)