it-swarm.com.de

Thema für ein Fragment festlegen

Ich versuche, das Thema für ein Fragment festzulegen.

Das Festlegen des Themas im Manifest funktioniert nicht:

Android:theme="@Android:style/Theme.Holo.Light"

Aus früheren Blogs geht hervor, dass ich einen ContextThemeWrapper verwenden muss. Kann mich jemand auf ein codiertes Beispiel verweisen? Ich kann nichts finden.

100
user1232691

Das Festlegen des Themas im Manifest wird normalerweise für die Aktivität verwendet.

Wenn Sie das Thema für das Fragment festlegen möchten, fügen Sie den nächsten Code in onCreateView () des Fragments hinzu:

@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);
}
166
David

Fragment nimmt sein Thema von seiner Tätigkeit. Jedem Fragment wird das Thema der Aktivität zugewiesen, in der es existiert.

Das Thema wird in der Fragment.onCreateView-Methode angewendet, in der der Code Ansichten erstellt, die eigentlich Objekte sind, in denen das Thema verwendet wird.

In Fragment.onCreateView erhalten Sie den Parameter LayoutInflater, der die Ansichten aufbläst und den für das Thema verwendeten Kontext enthält. Dies ist eigentlich die Aktivität. Ihre aufgeblasenen Ansichten verwenden also das Aktivitätsmotiv.

Um ein Thema zu überschreiben, können Sie LayoutInflater.cloneInContext aufrufen, das in Docs erwähnt, dass es zum Ändern eines Themas verwendet werden kann. Hier können Sie ContextThemeWrapper verwenden. Verwenden Sie dann den geklonten Inflater, um Fragmentansichten zu erstellen.

12
Pointer Null

Ich habe auch versucht, mein Fragmentdialogfeld mit einem anderen Thema als seiner Aktivität anzuzeigen, und bin diese Lösung gefolgt. Wie einige in den Kommentaren erwähnte Personen konnte ich es nicht zum Laufen bringen, und der Dialog wurde weiterhin mit dem im Manifest angegebenen Thema angezeigt. Das Problem stellte sich heraus, dass ich den Dialog mit AlertDialog.Builder In der onCreateDialog -Methode erstellte und daher nicht die onCreateView -Methode verwendete, wie in der Antwort gezeigt verbunden mit. Und als ich den AlertDialog.Builder Instanziierte, übergab ich den Kontext mit getActivity(), wenn ich stattdessen den instanziierten ConstextThemeWrapper hätte verwenden sollen.

Hier ist der Code für meinen 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;
}

Ich hatte ursprünglich den AlertDialog.Builder, Der wie folgt instanziiert wurde:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

was ich geändert habe:

AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);

Nach dieser Änderung wurde der Fragmentdialog mit dem richtigen Thema angezeigt. Wenn also eine andere Person ein ähnliches Problem hat und den AlertDialog.Builder Verwendet, prüfen Sie, ob der Kontext an den Builder übergeben wird. Hoffe das hilft! :)

11
BruceHill

Stellen Sie sicher, dass Sie Android:minSdkVersion="11" In Ihrem Manifest festgelegt haben. Dies könnte der Grund sein, warum Davids Beispiel für Sie nicht funktioniert hat.

Setzen Sie außerdem das Attribut Android:theme="@Android:style/Theme.Holo.Light" Für das Tag <application> Und [~ # ~] nicht [~ # ~] . das <activity> - Tag.

Ein anderes mögliches Problem könnte sein, wie Sie Ihren Kontext erhalten, wenn Sie eine ContextThemeWrapper() verwenden. Wenn Sie etwas wie getActivity().getApplicationContext() verwenden, ersetzen Sie es stattdessen durch getActivity().

Normalerweise sollte das Theme.Holo auf Fragmente angewendet werden, die mit der MainActivity verknüpft sind.

Beachten Sie, dass Sie einen ContextThemeWrapper verwenden, wenn Sie ein anderes Thema für Ihr Fragment anwenden möchten. Es kann hilfreich sein, wenn Sie den Code aus Ihrer MainActivity bereitstellen, in dem Sie Ihre Fragmente hinzufügen.


Einige nützliche Links:

Benutzerdefinierte ListView in Fragment entspricht nicht dem übergeordneten Thema

9
sebster

Für die Anwendung eines einzelnen Stils habe ich gerade verwendet

getContext().getTheme().applyStyle(styleId, true);

in onCreateView() des Fragments vor Root-Ansicht des Fragments aufblasen und es funktioniert für mich.

9
Tomask

Ich habe die von David vorgeschlagene Lösung ausprobiert, die funktioniert, aber nicht in allen Szenarien:
1. Für das erste Fragment, das dem Stapel hinzugefügt wurde, wurde das Thema der Aktivität und nicht das Thema, das in onCrateView definiert wurde, sondern für das zweite Fragment, das ich dem Stapel hinzufüge und korrigiere, wurden sie auf das Fragment angewendet.

2. Auf dem zweiten Fragment, dass die sie korrekt angezeigt wurden, habe ich Folgendes getan: Ich habe die App gezwungen, geschlossen zu werden, indem der Speicher geleert wurde, die App erneut geöffnet wurde und als die Aktivität mit dem Fragment neu erstellt wurde und nicht dasselbe, das in onCrateView des Fragments festgelegt wurde.

Um das Problem zu beheben, habe ich eine kleine Änderung vorgenommen und das Container-Argument von inflater.inflate durch eine Null ersetzt.

ich weiß nicht, wie der Inflater in einigen Szenarien den Kontext aus der Containeransicht verwendet.

Beachten Sie, dass ich Android.support.v4.app.Fragment & Android.support.v7.app.AppCompatActivity verwende.

@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);
} 
7
avi

Erstellen Sie eine Java Klasse und verwenden Sie dann das Layout, dessen Design Sie in der onCreate-Methode ändern möchten. Erwähnen Sie es dann wie gewohnt im Manifest

2
Devam03

Ich habe das Problem mit Android:theme = "@style/myTheme" In der Layoutdatei des Fragments gelöst. Dies ändert zum Beispiel den Stil von LinearLayout und dessen Inhalt, jedoch nichts außerhalb von LinearLayout. Um das gesamte Fragment mit einem beliebigen Stil zu dekorieren, wenden Sie das Thema auf das äußerste übergeordnete Layout an.

Hinweis: Falls Sie noch keine Lösung gefunden haben, können Sie es versuchen.

           <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>
1
Niraj Niroula

Wenn Sie den Stil nur für ein bestimmtes Fragment anwenden möchten, fügen Sie einfach diese Zeilen hinzu, bevor Sie onCreateView() oder onAttach() des Fragments aufrufen.

getActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);

und Wenn Sie die transparente Statusleiste festlegen möchten, setzen Sie false auf die Eigenschaft fitsSystemWindows Ihres Stammlayouts.

Android:fitsSystemWindows="false"
1
Siddharth Sheth

Ich muss es schaffen, indem ich das Thema auf den Fragmentkontext einstelle, bevor ich den Inflator aufrufe.

HINWEIS: Dies ist ein Beispiel für Xamarin.Android in Kombination mit MvvmCross. Ich bin nicht zu 100% sicher, ob dies auch für die Java - Programmierer funktioniert Sie können versuchen:)

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    Context.SetTheme(Theme);

    base.OnCreateView(inflater, container, savedInstanceState);

    var view = this.BindingInflate(FragmentLayoutId, container, false);

    // Doing some other stuff

    return view;
}

Der Code der SetTheme-Erweiterungsmethode

public static void SetTheme(this Context context, AppThemeStyle themeStyle)
{
    var themeStyleResId = themeStyle == AppThemeStyle.Dark ? Resource.Style.AppTheme : Resource.Style.AppTheme_Light;

    context.SetTheme(themeStyleResId);
}

Ich hoffe, das hilft einigen Leuten, Prost!

0
Jop Middelkamp