Estou procurando escrever preferências que possam ser aplicadas aos dispositivos 3.0 e pré-3.0. Descobrindo que PreferenceActivity
contém métodos obsoletos (embora estes sejam usados no código de exemplo que acompanha), observei PreferenceFragement
e o pacote de compatibilidade para resolver meus problemas.
Parece, porém, que PreferenceFragment
não está no pacote de compatibilidade. Alguém pode me dizer se isso foi intencional? Em caso afirmativo, posso segmentar facilmente uma variedade de dispositivos (por exemplo, <3.0 e> = 3.0) ou terei que pular os bastidores? Se não foi intencionalmente excluído, podemos esperar um novo lançamento do pacote de compatibilidade? Ou existe outra solução alternativa que é segura de usar?
Felicidades
James
PreferenceFragment
que você esquecerá que está lá. Veja minha resposta ."Because most of Preferences' implementation is hidden, therefore impossible to backport without lots of hackery."
PreferenceFragmentCompat
foi adicionado recentemente à biblioteca de suporte.Respostas:
Os métodos obsoletos estão obsoletos no Android 3.0. Eles estão perfeitamente bem em todas as versões do Android, mas a direção é usar
PreferenceFragment
no Android 3.0 e superior.Meu palpite é que é uma questão de tempo de engenharia, mas isso é apenas um palpite.
Considero que seja feito "facilmente". Tenha duas
PreferenceActivity
implementações separadas , uma usando cabeçalhos de preferência ePreferenceFragments
a outra usando a abordagem original. Escolha o caminho certo no momento em que você precisa (por exemplo, quando o usuário clica no item de menu Opções). Aqui está um projeto de amostra demonstrando isso. Ou escolha umPreferenceActivity
que lide com os dois casos, como neste projeto de exemplo .Você descobrirá quando o resto de nós descobrir, ou seja, se e quando ele será enviado.
Veja acima.
fonte
<include>
funciona com XML preferencial. BTW, se você é um assinante, a atualização do livro referente a este projeto foi anunciada minutos atrás.A implicação sutil da resposta do @CommonsWare é a seguinte: seu aplicativo deve escolher entre a API de compatibilidade ou a API de fragmento interna (desde o SDK 11). De fato, foi o que a recomendação "fácil" fez. Em outras palavras, se você quiser usar o PreferenceFragment, seu aplicativo precisará usar a API de fragmento interna e lidar com os métodos descontinuados no PreferenceActivity. Por outro lado, se é importante que seu aplicativo use o compat. API com a qual você não terá uma classe PreferenceFragment. Portanto, os dispositivos de segmentação não são um problema, mas o salto em arco acontece quando você precisa escolher uma ou outra API e, assim, enviar seu design para soluções imprevistas. Eu preciso do compat. API, então eu vou criar minha própria classe PreferenceFragment e ver como isso funciona. No pior cenário, eu
EDIT: Depois de tentar e ver o código em http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/preference/PreferenceFragment.java? av = h - criar meu próprio PreferenceFragment não acontecerá. Parece que o uso liberal de package-private no PreferenceManager em vez de 'protected' é o principal bloqueador. Realmente não parece que haja alguma segurança ou motivação muito boa para fazer isso e não é ótimo para testes de unidade, mas tudo bem ... menos digitação, eu acho ...
EDIT v2: Na verdade, aconteceu e funcionou. Definitivamente, foi uma dor de cabeça fazer o código funcionar com o JAR da API de compatibilidade. Tive que copiar cerca de 70% do pacote com.android.preference do SDK para o meu aplicativo e depois lutar com o código Java de qualidade medíocre no Android. Eu usei a v14 do SDK. Teria sido muito mais fácil para um engenheiro da Goog fazer o que eu fiz, ao contrário do que ouvi alguns engenheiros líderes do Android dizerem sobre esse tópico.
BTW - eu disse "segmentar dispositivos não é um problema"? É totalmente ... se você usar com.android.preference, não poderá trocar com a API de compatibilidade sem grandes refatorações. Log divertido!
fonte
Com base na resposta do CommonsWare e nas observações do Tenacious, criei uma solução de classe descendente capaz de direcionar todas as versões atuais da API Android com um mínimo de barulho e sem duplicação de código ou recurso. Por favor, veja minha resposta para a pergunta relacionada aqui: PreferenceActivity Android 4.0 e versões anteriores
ou no meu blog: http://www.blackmoonit.com/2012/07/all_api_prefsactivity/
Testado em dois tablets executando 4.0.3 e 4.0.4, bem como em um telefone executando 4.0.4 e 2.3.3 e também em um emulador executando 1.6.
fonte
Veja Compatibilidade com PreferenceFragment de Machinarius. Foi fácil entrar com o gradle e eu esqueço que ele está lá.
compile 'com.github.machinarius:preferencefragment:0.1.1'
Atualização importante: A revisão mais recente do
v7 support library
agora tem um PreferenceFragmentCompat nativo .fonte
Em agosto de 2015, o Google lançou a nova Biblioteca de Suporte de Preferências v7 .
Agora você pode usar o PreferenceFragmentCompat com qualquer
Activity
ouAppCompatActivity
Você precisa definir o
preferenceTheme
seu tema:Dessa forma, você pode personalizar o
preferenceTheme
estilo dos layouts usados para cada tipo de preferência sem afetar outras partes da sua Atividade.fonte
A resposta de Tenacious está correta, mas aqui estão mais alguns detalhes.
O motivo pelo qual você não pode "criar um layout normal e vincular os componentes de exibição aos compartilhados manualmente" é que existem algumas omissões surpreendentes na API android.preferences. PreferenceActivity e PreferenceFragment têm acesso a métodos PreferenceManager não públicos críticos, sem os quais você não pode implementar uma interface de usuário de preferência.
Em particular, para construir uma hierarquia de preferências a partir de um arquivo XML, você precisa usar um PreferenceManager, mas todos os construtores do PreferenceManager são privados ou ocultos por pacotes. O método de anexar os ouvintes do Preference onClick à sua atividade também é privado do pacote.
E você não pode contornar isso colocando sua implementação sorrateiramente no pacote android.preferences, porque métodos não públicos nas APIs do Android são realmente omitidas no SDK. Com um pouco de criatividade envolvendo reflexão e proxies dinâmicos, você ainda pode alcançá-los. A única alternativa, como diz Tenacious, é dividir o pacote android.preference inteiro, incluindo pelo menos 15 classes, 5 layouts e um número semelhante de elementos style.xml e attrs.xml.
Portanto, para responder à pergunta original, o motivo pelo qual o Google não incluiu o PreferenceFragment no pacote de compatibilidade é que eles teriam exatamente a mesma dificuldade que o Tenacious e eu. Mesmo o Google não pode voltar no tempo e tornar esses métodos públicos nas plataformas antigas (embora eu espero que eles façam isso em versões futuras).
fonte
Meu destino de aplicativo é a API +14, mas devido ao uso da biblioteca de suporte para uma navegação sofisticada, eu não podia usar o
android.app.Fragment
e precisava usá-loandroid.support.v4.app.Fragment
, mas também precisavaPreferenceFragment
implementá-lo sem grandes alterações no código.Portanto, minha solução fácil para ter os dois mundos da biblioteca de suporte e
PreferenceFragment
:fonte
Eu precisava integrar Preferências no design do aplicativo e manter o suporte para o Android 2.3. Então, eu ainda precisava do PreferencesFragment.
Após alguma pesquisa, encontrei a biblioteca android-support-v4-preferênciafragment . Essa lib economiza muito tempo para copiar e refatorar o PreferencesFragment original, como disse Tenacious. Funciona bem e os usuários desfrutam de preferências.
fonte