J'essaie de définir le thème d'un fragment.
La définition du thème dans le manifeste ne fonctionne pas:
Android:theme="@Android:style/Theme.Holo.Light"
En regardant les blogs précédents, il semble que je devrais utiliser un ContextThemeWrapper. Quelqu'un peut-il me renvoyer à un exemple codé? Je ne trouve rien.
La définition du thème dans le manifeste est généralement utilisée pour l'activité.
Si vous souhaitez définir un thème pour fragment, ajoutez le code suivant dans la onCreateView () du fragment:
@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);
}
Fragment tire son thème de son activité. Chaque thème se voit attribuer le thème de l'activité dans lequel il existe.
Le thème est appliqué dans la méthode Fragment.onCreateView, où votre code crée des vues, qui sont en réalité des objets dans lesquels thème est utilisé.
Dans Fragment.onCreateView, vous obtenez le paramètre LayoutInflater, qui gonfle les vues et contient le contexte utilisé pour le thème. Il s'agit en fait de l'activité. Ainsi, vos vues gonflées utilisent le thème d'Activité.
Pour remplacer le thème, vous pouvez appeler LayoutInflater.cloneInContext , qui indique dans Docs qu'il peut être utilisé pour changer de thème. Vous pouvez utiliser ContextThemeWrapper ici. Utilisez ensuite un inflateur cloné pour créer des vues de fragment.
J'essayais également de faire afficher mon dialogue de fragment avec un thème différent de son activité, et suivis cette solution . Comme certaines personnes mentionnées dans les commentaires, cela ne fonctionnait pas et le dialogue continuait de s'afficher avec le thème spécifié dans le manifeste. Le problème s'est avéré que je construisais le dialogue en utilisant AlertDialog.Builder
Dans la méthode onCreateDialog
et que je n'utilisais donc pas la méthode onCreateView
comme indiqué dans la réponse que j'ai lié à. Et lorsque j’ai instancié le AlertDialog.Builder
, Je passais dans le contexte en utilisant getActivity()
alors que j’aurais dû utiliser l’instance instanciée ConstextThemeWrapper
.
Voici le code de mon 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;
}
A l'origine, le AlertDialog.Builder
Était instancié comme suit:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
que j'ai changé pour:
AlertDialog.Builder builder = new AlertDialog.Builder(contextThemeWrapper);
Après cette modification, la boîte de dialogue de fragment était affichée avec le thème correct. Donc, si quelqu'un d'autre a un problème similaire et utilise AlertDialog.Builder
, Vérifiez le contexte transmis au générateur. J'espère que cela t'aides! :)
Assurez-vous que Android:minSdkVersion="11"
Est défini dans votre manifeste. Cela pourrait être la cause pour laquelle l'exemple de David n'a pas fonctionné pour vous.
Définissez également l'attribut Android:theme="@Android:style/Theme.Holo.Light"
Pour la balise <application>
Et [~ # ~] et non [~ # ~] . la balise <activity>
.
Un autre problème possible pourrait être la façon dont vous obtenez votre contexte lorsque vous utilisez un ContextThemeWrapper()
. Si vous utilisez quelque chose comme getActivity().getApplicationContext()
, remplacez-le simplement par getActivity()
.
Normalement, Theme.Holo devrait s’appliquer aux fragments liés à MainActivity.
Veuillez noter que vous utilisez un ContextThemeWrapper lorsque vous souhaitez appliquer un thème différent à votre fragment. Cela pourrait être utile si vous fournissez le morceau de code, à partir de votre MainActivity, où vous ajoutez vos Fragments.
Quelques liens utiles:
ListView personnalisé dans le fragment n'adhérant pas au thème parent
Pour appliquer un seul style, j'ai utilisé juste
getContext().getTheme().applyStyle(styleId, true);
dans onCreateView()
du fragment avant gonfler la vue racine du fragment et cela fonctionne pour moi.
J'ai essayé la solution suggérée par David, mais pas dans tous les scénarios:
1. pour le premier fragment ajouté à la pile, le thème de l'activité et non celui défini dans onCrateView, mais sur le deuxième fragment que j'ajoute à la pile, les corriger ont été appliqués sur le fragment.
2. Sur le deuxième fragment que les eux a été affiché correctement, j’ai fait ce qui suit: j’ai forcé l’application à être fermée en nettoyant la mémoire, à la rouvrir de l’application et lorsque l’Activité a été recréée avec le fragment Le fragment a été modifié pour les annuler et pas le même qui a été défini dans le onCrateView du fragment.
Pour résoudre le problème, j'ai fait un petit changement et remplacé l'argument conteneur de inflater.inflate par un null.
je ne sais pas comment inflater utilise dans certains scénarios le contexte de la vue conteneur.
Remarque - que je suis en utilisant 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);
}
Créez une classe Java), puis utilisez la présentation dont vous souhaitez modifier le thème dans la méthode onCreate.
J'ai résolu le problème en utilisant Android:theme = "@style/myTheme"
dans le fichier de mise en page du fragment. Par exemple, cela change le style de LinearLayout
et son contenu, mais pas n'importe quoi en dehors de LinearLayout
. Ainsi, afin de décorer le fragment entier avec n'importe quel style, appliquez le thème à sa mise en page la plus externe parente.
Note: Juste au cas où si vous n'avez pas encore trouvé de solution, vous pouvez l'essayer.
<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>
Si vous souhaitez simplement appliquer un style à un fragment particulier, ajoutez-y simplement ces lignes avant d'appeler onCreateView()
ou onAttach()
du fragment,
getActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);
et Si vous souhaitez définir une barre d’état transparente, définissez false sur fitsSystemWindows
propriété de votre mise en page racine,
Android:fitsSystemWindows="false"
Je dois le faire fonctionner en plaçant le thème sur le fragment fragment avant d'appeler l'inflateur.
REMARQUE: ceci est un exemple pour Xamarin.Android associé à MvvmCross. Je ne suis pas sûr à 100% si cela fonctionnera également pour les programmeurs Java. Mais vous pouvez essayer:)
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;
}
Le code de la méthode d'extension SetTheme
public static void SetTheme(this Context context, AppThemeStyle themeStyle)
{
var themeStyleResId = themeStyle == AppThemeStyle.Dark ? Resource.Style.AppTheme : Resource.Style.AppTheme_Light;
context.SetTheme(themeStyleResId);
}
J'espère que cela aide certaines personnes, bravo!