Alternativas para PreferenceFragment com android-support-v4

90

Eu parei repentinamente no desenvolvimento do meu aplicativo quando percebi que PreferenceFragments não eram suportados nesta biblioteca. Existe alguma alternativa que um desenvolvedor Android iniciante possa usar para superar esse obstáculo?

Esta é a minha janela principal a partir de agora

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
<TabHost
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@+android:id/realtabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>

                <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            />

</TabHost>
</LinearLayout>

Para minha TabActivity, estou usando algo que encontrei online. Aqui está um snippet:

public class TabControlActivity extends FragmentActivity implements TabHost.OnTabChangeListener 
{
public static final int INSERT_ID = Menu.FIRST;
public static TabControlActivity thisCtx;
private TabHost mTabHost;
private HashMap mapTabInfo = new HashMap();
private TabInfo mLastTab = null;

private class TabInfo {
     private String tag;
     private Class clss;
     private Bundle args;
     private Fragment fragment;
     TabInfo(String tag, Class clazz, Bundle args) {
         this.tag = tag;
         this.clss = clazz;
         this.args = args;
     }

}

class TabFactory implements TabContentFactory 
{

    private final Context mContext;

    /**
     * @param context
     */
    public TabFactory(Context context) {
        mContext = context;
    }

    /** (non-Javadoc)
     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
     */
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }

}

...*snip*...

Existe algum para implementar algo que se pareça com um preferênciafragment (ou preferênciaActivity) usando a biblioteca de compatibilidade android-support-v4?

CodePrimate
fonte
Não é realmente uma duplicata, pois estou em uma situação em que "preciso" que essas preferências sejam mostradas em um host de tabulação. Ver minha edição
CodePrimate de
Veja minha resposta atualizada . PreferenceFragmentCompatfoi adicionado recentemente à biblioteca de suporte.
theblang

Respostas:

86

ATUALIZAÇÃO - 11/06/2015

A biblioteca Support-v7 agora inclui PreferenceFragmentCompat. Portanto, será uma ideia melhor usá-lo.


Adicione o seguinte projeto como um projeto de biblioteca ao seu aplicativo.

https://github.com/kolavar/android-support-v4-preferencefragment

Você pode manter tudo, incluindo sua transação de fragmento, como está. Ao importar a PreferenceFragmentclasse, certifique-se de que o cabeçalho de importação correto seja o usuário.

import android.support.v4.preference.PreferenceFragment;

ao invés de

import android.preference.PreferenceFragment;
Subin Sebastian
fonte
4
Esse código do github parece ter problemas sérios ... Não consigo usar RingtonePreferencee também OnSharedPreferenceChangeListenernão parece que recebo nenhuma alteração!
madlymad
2
Eu estava pensando que é uma boa ideia usar esta biblioteca. Mas percebi que não é tão bom quanto eu pensava. Tentar substituir o onPrepareOptionMenumétodo me mostra uma assinatura estranha (retorna void) diferente do padrão que todos nós conhecemos (retorna boolean) !!! um problema sério.
S.Thiongane
9
votou positivamente e você tem direito a um jantar grátis sempre que vier a Madrid ... essa questão estava me deixando louco!
rupps de
7
@mansoulx onPrepareOptionsMenu sempre tem um tipo de retorno void em fragmentos (ao contrário de Activities, para o qual é booleano), então essa assinatura é inteiramente conforme o esperado.
Cumbayah
3
Problemas com a biblioteca provavelmente devem ser relatados no projeto github.
Mathijs Segers
128

Eu sei que esta é uma pergunta antiga, mas agora você pode usar PreferenceFragmentCompatdecom.android.support:preference-v7:23.3.0

Lucius
fonte
4
Ótimo achado, esta é uma das respostas corretas agora.
Mythul
Para mim, ele funciona apenas com com.android.support:preference-v7:23.0.1.
Felipe Mosso
1
Isso não parece estar nos servidores de dependência ao tentar adicioná-lo do Android Studio. Preciso adicionar um repositório para ele?
Brill Pappin
Não contém essa classe
JJ Ab
1
Eu acidentalmente votei a favor desta resposta e não posso desfazer agora, então, em vez disso, vou apenas observar que PreferenceFragmentCompathá alguns problemas importantes: veja este e este relatório de bug, por exemplo, e muitos mais aqui . Acabei usando o obsoleto PreferenceActivity. suspiro
Vicky Chijwani
16

Atualização importante: a revisão mais recente do v7 support libraryagora tem um PreferenceFragmentCompat nativo .

Estou usando esta biblioteca , que tem um AARin mavenCentralpara que você possa incluí-la facilmente se estiver usando Gradle.

compile 'com.github.machinarius:preferencefragment:0.1.1'

theblang
fonte
Você poderia compartilhar como importar e estender o fragmento de suporte? Obrigado
Steven
1
@Steve Sure! Eu fiz um Gist .
theblang
@mattblang Muito obrigado!
Steven
@mattblang Muito obrigado ... Sua ajuda realmente economizou meu tempo
Asad Ullah Rafiq
Exceção java.lang.RuntimeException: o conteúdo tem visualização com o atributo id 'android.R.id.list' que não é uma classe ListView
Abdul Rahman
10

Você pode usar o meu PreferenceFragment.

É simples e não tive problemas com isso até agora. Eu acho que você só pode exibir um deles por vez em uma única atividade, o que deve estar OK.

BladeCoder
fonte
9

Biblioteca de suporte de preferências: fragmentos de preferência para API 7 ou 7, independentemente da atividade

Uma implementação simples incluiria um PreferenceFragmentCompat, como:

public class PreferencesFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.preferences);
    }
}

Você também precisará definir preferênciasTheme em seu tema:

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

E adicione isso nas dependências: http://developer.android.com/tools/support-library/features.html

com.android.support:preference-v14:23.1.0
li2
fonte
7

Você pode talvez usar uma atividade real e usar fragmento, mas não acho que seja uma boa escolha. Você deve usar PreferenceActivity simples e aguardar melhorias nas bibliotecas de compatibilidade retro.

Snicolas
fonte
1
Não posso usar uma PreferenceActivity, pois o resto do meu aplicativo consiste em um tabwidget. O fragmento de preferência deve ser mostrado acima do tabwidget. Eu deveria fazer disso uma atividade em vez de ocupar a tela inteira.
CodePrimate de
2
Em seguida, use algum fragmento de lista personalizada
zapl
2

Você pode usar bibliotecas de terceiros, como UnifiedPreferences, para usar uma única API para todas as versões do Android.

MarcoDuff
fonte
0

Em vez disso, você pode estender a partir de PreferenceActivity e, se desejar ter uma ActionBar, pode adicioná-la usando uma barra de ferramentas como estando acima do ListView usado para as preferências.

Isso pode ser feito usando um LinearLayout vertical que contém a barra de ferramentas e um ListView com android: id = "@ android: id / list" .

Se desejar, você pode ver minha solução aqui .

desenvolvedor android
fonte
0

Como Lucius disse, você pode usar PreferenceFragmentCompat :

public class MyPreferenceFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle bundle, String s) {               
            PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);
            addPreferencesFromResource(R.xml.preferences);
       }
}

Você deve incluir sua dependência no gradle:

dependencies {
...
    compile 'com.android.support:preference-v7:23.1.X' (wherX = 0,1,...)
...
}

Dessa forma, você também pode usar FragmentTransaction de android.support.v4.app.FragmentTransaction e PrefernceFragment. No entanto, você pode ter problemas com temas. Se for o caso, você pode resolvê-lo tendo em conta este post:

Solução para fazer a lib funcionar na API 7 ou superior, mantendo o tema material na API 14+

vicasdia
fonte