PreferenceFragmentCompat requer que o priorityTheme seja definido


114

Com o novo PreferenceFragmentCompat da biblioteca de suporte de preferências v7: http://developer.android.com/tools/support-library/features.html#v7-preference , recebo este erro

E  java.lang.IllegalStateException: Must specify preferenceTheme in theme
E      at android.support.v7.preference.PreferenceFragmentCompat.onCreate(PreferenceFragmentCompat.java:202)

Qual tema deve ser definido?

Atualização: tentei usar

<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>

como sugerido por @Bogato, mas não parece certo e parece muito Holo mesmo no Lollipop.

Biblioteca de suporte:

insira a descrição da imagem aqui

Preferências nativas:

insira a descrição da imagem aqui


2
Há um bug sobre a documentação para este aqui: code.google.com/p/android/issues/...
Intrications

1
Pessoalmente, não acho que essas soluções valham a pena as soluções alternativas. Experimente github.com/kolavar/android-support-v4-preferencefragment
MidasLefko

1
Você pode marcar stackoverflow.com/a/44236460/238753 como a resposta aceita?
Sam

Respostas:


159

O projeto de amostra pode ser encontrado aqui

A correção de bug está disponível como uma dependência do Gradle

Baixar

Agora pode-se usar a biblioteca com bastante facilidade. Aqui está a maneira mais rápida de fazer isso, mas você deve verificar o README para obter mais informações.

1. Atualize o arquivo gradle do seu módulo:

compile 'com.takisoft.fix:preference-v7:27.0.0.0'

2. Use a classe apropriada como base do seu fragmento

Você pode usar PreferenceFragmentCompatou PreferenceFragmentCompatDividers.

( Cuidado com o nome do pacote apropriado ao importar PreferenceFragmentCompat! )

3. Use o tema apropriado

Defina o tema da atividade que o contém como uma variante de @style/PreferenceFixTheme, como NoActionBar, Light, etc.

Para mais informações e dicas de uso, acesse a página do projeto .


PS Nesta seção você pode encontrar a solução detalhada que levou à criação da biblioteca, mas decidi removê-la porque pode ser confuso. Se você está curioso sobre as etapas, ainda pode encontrá-las no histórico de revisão desta resposta.


6
O tamanho do texto padrão é muito grande, tentei modificá-lo usando esses estilos que você apontou, sem sucesso. Você conseguiu ajustar o tamanho do texto?
Tinashe de

4
Estou tentando colocar o material design lá, mas não obtive muito sucesso ... O que descobri durante o processo é que o pacote de preferência v7 não tem o estilo temático do material, layout e outros arquivos. Enquanto isso, o v14 contém alguns deles, mas o problema com o v14 é que ele estende o fragmento nativo, não o de suporte. Acho que o Google cometeu um grande erro aqui, espero que consertem o mais
rápido

1
Eu posso tentar colocar o design de material no lugar para dispositivos pré-21 também, eles parecem iguais ao original agora.
Gergely Kőrössy de

2
Você também deve mencionar que o PreferenceFragmentCompat trava se girado com uma caixa de diálogo aberta. code.google.com/p/android/issues/detail?id=186160
headsvk

21
Isto é ridículo. Eu levaria menos tempo para fazer um fragmento de preferência do zero do que para encontrar uma maneira de passar por todos os bugs, soluções alternativas e testes necessários para fazer isso funcionar 100% em todas as versões.
Edward van Raak

46

Você deve especificar preferredTheme no tema de sua atividade de preferência.

Por exemplo :

<style name="SettingsTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

PreferenceThemeOverlay é o tema padrão que vem com a biblioteca de suporte Preferences-v7.


14
Isso funciona, mas parece errado. As fontes dos elementos de preferência são muito grandes (testado no Android 4.1 e 5.1).

@ mus65 Esse é o problema. Eu tinha imaginado que deveria usar esse tema, mas parece ruim. Eu adicionei mais detalhes à pergunta original.
Intricações de

3
Selecionei esta como a resposta correta porque foi a primeira que disse o tema correto a definir. No entanto, a biblioteca de suporte não precisa ser corrigido para que as preferências de usar o projeto material de acordo com code.google.com/p/android/issues/detail?id=183376
Intrications

Como faço para que o tema pareça design de material? Atualmente ele mostra a aparência nativa para mim ...
desenvolvedor Android

1
Leia minha resposta abaixo.
Gergely Kőrössy

35

Parece que o Google corrigiu esse problema. Eu testei isso com a preferência v14-suporte versão 25.3.1

1) Adicione implementation 'com.android.support:preference-v14:25.3.1'ao seu Gradle.

2) Adicione PreferenceThemeOverlay.v14.Materialao estilo em vez de PreferenceThemeOverlay.

<style name="AppTheme.SettingsTheme" parent="AppTheme.NoActionBar">
    <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>

3) Por fim, adicione o estilo ao Manifesto

android:theme="@style/AppTheme.SettingsTheme"

O único problema com esta resposta é que o fragmento de preferência usará o tema material em sistemas que executam o KitKat e abaixo. Definir preferenceThemecomo PreferenceThemeOverlay.v14em styles.xmle PreferenceThemeOverlay.v14.Materialem styles-v21.xmlcorrige o problema.
Jack Meister

@JackMeister, você só deve usar a versão v14 se tiver como objetivo a API de nível 14 ou superior. A incompatibilidade de temas com versões mais antigas pode não ser seu único problema ao usar a v14 com níveis de API mais antigos.
Jelmer Brands de

@JelmerBrands Claro: você não deve usar uma biblioteca de suporte v14 em sistemas que executam níveis de API abaixo de 14. Meu comentário assume um minSdkVersionentre 14 e 20.
Jack Meister

Testado com 23.4.0, que funciona tão bem. Usar a preferência v14, não a preferência v7, é a chave.
user149408

14

Para usar o PreferenceFragmentCompat, você deve definir preferenceThemeem seu tema:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  ...
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

Desta forma, você pode personalizar o preferenceThemepara definir o estilo dos layouts usados ​​para cada tipo de preferência sem afetar outras partes de sua atividade.


Certifique-se de adicionar preferênciaTheme ao estilo certo, que é definido como tema para sua atividade stackoverflow.com/a/40736138/1572286
Youness

14

Acabei de adicionar esta linha no tema e está funcionando perfeitamente na API 19 e acima.

<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>

3
Esta é a solução mais simples e funcional, que não requer dependência adicional. Deve ser a resposta aceita IMHO, agora que a maioria dos aplicativos tem API mínima de 14+
Louis CAD

O Android Studio não consegue encontrar isso
Denny

3
add com.android.support:preference-v14: to build.gradle
Sofi Software LLC

3

Solução que funcionou para mim na API 25. Eu tinha este tema padrão:

<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

E adicionou esta linha a ele

<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

PreferenceThemeOverlay já estava definido, não precisei incluí-lo. Funcionou em dispositivos Android 4.xe 5.x meus


2

Adicione este código ao seu styles.xml e modifique-o de acordo. Deve funcionar bem.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

<style name="PreferenceThemeOverlay">
    <item name="preferenceScreenStyle">@style/Preference.PreferenceScreen</item>
    <item name="preferenceFragmentStyle">@style/PreferenceFragment</item>
    <item name="preferenceCategoryStyle">@style/Preference.Category</item>
    <item name="preferenceStyle">@style/Preference</item>
    <item name="preferenceInformationStyle">@style/Preference.Information</item>
    <item name="checkBoxPreferenceStyle">@style/Preference.CheckBoxPreference</item>
    <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat</item>
    <item name="dialogPreferenceStyle">@style/Preference.DialogPreference</item>
    <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference</item>
    <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList</item>
</style>


1

Eu adicionei o item "preferredTheme" ao meu estilo e isso pareceu resolver o problema:

   <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
     <item name="android:actionBarStyle">@style/MyActionBarTheme</item>
     <item name="colorPrimary">@color/ColorPrimary</item>
     <item name="colorPrimaryDark">@color/ColorPrimaryDark</item>
     <item name="preferenceTheme">@style/Preference</item>
 </style>

1

O site mais útil para mim: Médio

O autor mostra que precisamos adicionar dois pacotes: com.android.support:preference-v7ecom.android.support:preference-v14 , porque o primeiro está sendo distribuído sem estilos.

Me avise se funcionar



0

O problema ocorre porque o AAPT (Android Asset Packaging Tool) não consegue encontrar alguns recursos. Corrija esse problema da seguinte maneira:

1.Copie os recursos necessários para uma nova pasta de recursos de resposta, nomeada como res_fw_v7_preference ou qualquer outra coisa.

2. Usando gradle para construir seu aplicativo e adicionar algumas opções adicionais de AAPT em build.gradle (módulo) como este:

android {
    ...
    aaptOptions {
        additionalParameters '-S',
            'src/main/res_fw_v17_leanback',  // resources in frameworks/support/v17/leanback
            '-S',
            'src/main/res_fw_v7_preference',  // resources in frameworks/support/v7/preference
            '-S',
            'src/main/res_fw_v14_preference',  // resources in frameworks/support/v14/preference
            '-S',
            'src/main/res_fw_v17_preference-leanback',  // resources in frameworks/support/v17/preference-leanback
            '-S',
            'src/main/res_fw_v7_appcompat',  // resources in frameworks/support/v7/appcompat
            '-S',
            'src/main/res_fw_v7_recyclerview',  // resources in frameworks/support/v7/recyclerview
            '-S',
            'src/main/res',  // resources in your application
            '--auto-add-overlay',
            '--extra-packages',
            'android.support.v17.leanback:android.support.v7.preference:android.support.v14.preference:android.support.v17.preference:android.support.v7.appcompat:android.support.v7.recyclerview'
    noCompress 'foo', 'bar'
    ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~'
    }
    ...
}

Espero que isso seja útil :)


0

Obrigado @sergio pela resposta, usando em <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>vez de <item name="preferenceTheme">@style/Preference</item>funciona muito bem para mim.

<style name="IntentTheme" parent="Theme.AppCompat">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:actionModeBackground">@color/fulltransparent</item>
        <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>

-8

Apenas deixe ir e use a API 11+.

API 7 já tem quase sete anos.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.