Hapus / sembunyikan preferensi dari layar

135

Saya memiliki aktivitas yang memperluas PreferenceActivity. Saya memuat preferensi dari file xml. Tetapi dalam beberapa kasus saya perlu menyembunyikan sepenuhnya salah satu preferensi dari layar berdasarkan status aplikasi saya. Ada metode setEnabled, tetapi itu bukan yang saya inginkan. Saya ingin menghapus preferensi itu dari layar sepenuhnya. Apa itu mungkin ?

Alex Volovoy
sumber

Jawaban:

172

Ya, jika Anda memiliki referensi ke Preference, dan induknya (a PreferenceCategory, atau PreferenceScreen)

myPreferenceScreen.removePreference(myPreference);
David Hedlund
sumber
Bagus! Terima kasih! Bekerja dan masuk akal
Bostone
Saya mungkin telah menjawab pertanyaan saya sendiri melalui ini? stackoverflow.com/a/4704360/956975
marienke
2
Sayangnya, ini secara permanen menghapus preferensi. Apakah mungkin hanya untuk menyembunyikannya?
Dmitry
Itu juga tidak berhasil untuk saya. Preferensi tetap ada!
Dmitry
@Dmitry Anda bisa membuatnya abu-abu dengansetEnabled()
JakeD
212

Jika Anda Preferenceberada dalam a PreferenceCategory, Anda harus melakukan ini:

XML:

<PreferenceCategory
    android:key="category_foo"
    android:title="foo">

    <CheckBoxPreference
        android:key="checkPref" />

Jawa:

CheckBoxPreference mCheckBoxPref = (CheckBoxPreference) findPreference("checkPref");
PreferenceCategory mCategory = (PreferenceCategory) findPreference("category_foo");
mCategory.removePreference(mCheckBoxPref);
Kavi
sumber
5
Agar adil, jawaban di atas memang mengatakan bahwa Anda membutuhkan orang tua PreferenceCategory.
matt
50

Jika Preferensi adalah turunan langsung dari layar preferensi, berikut beberapa kode yang berdiri sendiri:

PreferenceScreen screen = getPreferenceScreen();
Preference pref = getPreferenceManager().findPreference("mypreference");
screen.removePreference(pref);
1 ''
sumber
4
Ini tidak akan berfungsi jika preferensi terletak di dalam kategori. Anda harus findPreferenceuntuk kategori tersebut, dan menghapus preferensi dari kategori
MBH
1
@MBH: Terima kasih telah menyebutkan peringatan itu!
1 ''
10

Jika Anda menggunakan PreferenceFragmentCompat, Anda dapat menyetel visiblity dalam xml.

Preferensi di xml Anda akan dikonversi ke versi AppCompat secara otomatis. Anda kemudian dapat menggunakan atribut ' app: isPreferenceVisible ' di xml Anda

preferensi.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <CheckBoxPreference
        android:defaultValue="false"
        android:key="show.navigation"
        android:title="Show navigation"
        app:isPreferenceVisible="false" />

...

Atribut tersebut didokumentasikan di https://developer.android.com/guide/topics/ui/settings/components-and-attributes

Penambahan PreferenceFragmentCompatdidokumentasikan di https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy

Contoh:

public class MySettingsActivity extends AppCompatActivity {

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.settings_container, new MySettingsFragment())
                .commit();
    }
} 
aaronvargas
sumber
9

Jika Anda menginginkan sesuatu yang secara dinamis akan mengubah preferensi misalnya pada SwitchPreference, saya telah menemukan cara terbaik adalah dengan meletakkan semua sub opsi saya ke dalam dua wadah kategori. Awalnya Anda akan melihat semuanya, lalu Anda cukup menghapus bit yang tidak Anda inginkan. Bagian yang cerdas, adalah Anda hanya memicu pembuatan ulang ketika sesuatu berubah dan kemudian Anda tidak perlu membuat apa pun secara manual atau khawatir tentang meletakkan kembali semuanya dalam urutan yang benar.

protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  addPreferencesFromResource(R.xml.preferences);
  PreferenceCategory prefCatOne= (PreferenceCategory)findPreference("prefCatOne");
  PreferenceCategory prefCatTwo= (PreferenceCategory)findPreference("prefCatTwo");
  SwitchPreference mySwitchPref= (SwitchPreference)findPreference("mySwitchPref");
  PreferenceScreen screen = getPreferenceScreen();
  if (mySwitchPref.isChecked()) {
    screen.removePreference(prefCatOne);
  } else {
    screen.removePreference(prefCatTwo);
  }
}

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    if (key.equals("mySwitchPref")) {
        this.recreate();
    }
}

Satu-satunya downside yang dapat saya lihat dengan ini, adalah ada flash saat layar dibuat ulang dari awal.

James
sumber
Kasus tidak bekerja, setidaknya tidak di 22. Tetapi mengubahnya menjadi Preferensi (meskipun itu adalah pengelompokan preferensi) berhasil.
Rob
Rob, saya baru saja menguji kode di atas dalam API22 AVD dan berfungsi dengan baik. Pastikan konten XML preferensi Anda cocok dengan kode Anda. Untuk contoh di atas, SwitchPreference bisa berada di mana saja, tetapi Anda memerlukan PreferenceCategorys untuk menjadi turunan langsung dari PreferenceScreen.
Yakobus
Saya baru saja mendapatkan Kategori sebagai Preferensi, tanpa pemeran, dan menghapusnya. Bekerja.
Rob
8

Di file XML Anda:

<PreferenceScreen 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:key="preferenceScreen">

    <PreferenceCategory
        android:key="personalisation"
        android:title="your title here">

        <ThemedPreference
            android:key="animation" />

</PreferenceScreen>

Dalam kode Anda:

PreferenceScreen pPreferenceScreen = (PreferenceScreen) findPreference("preferenceScreen");

PreferenceCategory pCategory = (PreferenceCategory) findPreference("personalisation");
ThemedPreference pThemePref = (ThemedPreference) findPreference("animation");

pPreferenceScreen.removePreference(pCategory); //remove category
pCategory.removePreference(pThemePref);   // remove preference
pengguna3165739
sumber
5

Saya merekomendasikan menggunakan preferensi v7, ini memiliki setVisible()metode. Tapi saya belum mencobanya. Dengan demikian Anda harus menggunakan PreferenceFragmentbukan PreferenceActivity.

teh
sumber
Jawaban yang diterima tidak akan berfungsi untuk V7. Menggunakan setVisible tidak berfungsi untuk V7
m12lrpv
V7 juga memiliki getParent(), jadi Anda benar-benar dapat menghapus preferensi seperti yang dijelaskan dalam jawaban ini .
pengguna905686
3

Dalam file XML Anda dapat membuat preferensi tersembunyi dengan mengosongkan tag judul dan ringkasan.

<EditTextPreference
    android:defaultValue="toddlerCam"
    android:key="save_photo_dir"
/>
Al Ro
sumber
Ini adalah jawaban yang sempurna untuk saya. Saya sudah mencari ini. Terima kasih!
夏 期 劇場
2

Berikut adalah cara umum untuk melakukan ini yang berhasil terlepas dari apakah preferensinya di bawah PreferenceCategoryatau PreferenceScreen.

private void removePreference(Preference preference) {
    PreferenceGroup parent = getParent(getPreferenceScreen(), preference);
    if (parent == null)
        throw new RuntimeException("Couldn't find preference");

    parent.removePreference(preference);
}

private PreferenceGroup getParent(PreferenceGroup groupToSearchIn, Preference preference) {
    for (int i = 0; i < groupToSearchIn.getPreferenceCount(); ++i) {
        Preference child = groupToSearchIn.getPreference(i);

        if (child == preference)
            return groupToSearchIn;

        if (child instanceof PreferenceGroup) {
            PreferenceGroup childGroup = (PreferenceGroup)child;
            PreferenceGroup result = getParent(childGroup, preference);
            if (result != null)
                return result;
        }
    }

    return null;
}
Sam
sumber
0

Anda dapat melakukannya dengan 2 cara:

1. Jika Anda menggunakan pustaka dukungan, Anda bisa membuat peta pohon preferensi dan orang tuanya, lalu menghapus preferensi dengan menggunakan induknya. Berikut fungsi untuk menghasilkan peta seperti itu:

public static Map<Preference, PreferenceGroup> buildPreferenceParentTree(@NonNull final PreferenceScreen preferenceScreen) {
    final Map<Preference, PreferenceGroup> result = new HashMap<>();
    final Stack<PreferenceGroup> curParents = new Stack<>();
    curParents.add(preferenceScreen);
    while (!curParents.isEmpty()) {
        final PreferenceGroup parent = curParents.pop();
        final int childCount = parent.getPreferenceCount();
        for (int i = 0; i < childCount; ++i) {
            final Preference child = parent.getPreference(i);
            result.put(child, parent);
            if (child instanceof PreferenceGroup)
                curParents.push((PreferenceGroup) child);
        }
    }
    return result;
}
  1. Jika Anda menggunakan API preferensi android-x baru, Anda cukup menyetel visibilitasnya, dengan menggunakan fungsi setVisible di atasnya.
pengembang android
sumber
Menurut dokumen dan jawaban Teh setVisible() tersedia sejak versi 24.1.0 dari perpustakaan Dukungan.
JJD
Pernahkah Anda melihat apa yang saya tulis? Saya secara khusus menulis bahwa itu mungkin sekarang ... Selain itu, solusi pertama membantu penghapusan, yang sedikit berbeda dari menyembunyikan ..
pengembang android
Ya, saya membaca jawaban Anda. Saya mengacu pada poin ke-2 Anda. Bunyinya seolah-olah setVisibile()metode ini tersedia dari android-x yang saya coba klarifikasi. Jangan tersinggung.
JJD
Android-X adalah yang menggantikan semua pustaka dukungan. Tidak akan ada versi baru pustaka dukungan seperti yang kita kenal.
Pengembang android
Benar. Saya sadar akan hal ini . Namun, orang-orang yang kesulitan dengan versi sebelumnya dapat menggunakan metode ini.
JJD
0

Jika Anda ingin mengevaluasi, dan berdasarkan topeng itu, mungkin ada alternatif lain

SwitchPreference autenticacionUsuario = 
    (SwitchPreference) findPreference("key_autenticacion_usuario");

final EditTextPreference Username = 
    (EditTextPreference) findPreference("key_username_mqtt");
final EditTextPreference Password = 
    (EditTextPreference) findPreference("key_password_mqtt");

if (!autenticacionUsuario.isChecked()) {
    PreferenceCategory preferenceCategory = 
        (PreferenceCategory) findPreference("category_mqtt");
    preferenceCategory.removePreference(Username);
    preferenceCategory.removePreference(Password);
}

Semua ini harus ada di dalam

public static class PrefsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
Gustavo Eduardo Belduma
sumber
1
Maaf, tapi ini situs berbahasa Inggris. Bisakah kamu menjawab dalam bahasa inggris
Dave Schweisguth
Tentu saja niat saya juga untuk menyediakan bagi orang-orang yang tidak bisa berbahasa Inggris
Gustavo Eduardo Belduma
3
@GustavoEduardoBelduma maka Anda mungkin perlu membaca meta.stackoverflow.com/a/297680/545026
Leo mendukung Monica Cellio
0

Jika Anda melakukan apa yang menurut saya Anda coba lakukan (karena saya mencoba melakukannya sekarang) mungkin lebih baik mengaktifkan / menonaktifkan preferensi. Karena menghapusnya akan mengeluarkannya dari layar preferensi dan Anda mungkin tidak dapat menambahkannya kembali ke tempat yang Anda inginkan jika Anda membuat layar secara terprogram.

pref.setEnabled (false); pref.setEnabled (true);

meskipun ini mungkin sudah usang. Ini berfungsi untuk kasus penggunaan yang saya alami sekarang.

RCB
sumber