Ekrandan bir tercihi kaldırma / gizleme


134

PreferenceActivity'yi genişleten bir etkinliğim var. Tercihleri ​​xml dosyasından yüklüyorum. Ancak bazı durumlarda, uygulama durumuma göre tercihlerden birini ekrandan tamamen gizlemem gerekiyor. Bir setEnabled yöntemi var, ama tam olarak istediğim şey değil. Bu tercihi ekrandan tamamen kaldırmak istiyorum. Mümkün mü ?

Yanıtlar:


171

Evet, hem Preferenceüst öğeye hem de üst öğeye (a PreferenceCategoryveya veya PreferenceScreen) ilişkin bir referansınız varsa

myPreferenceScreen.removePreference(myPreference);

Harika! Teşekkürler! Çalışır ve mantıklıdır
Bostone

Kendi sorumu bu şekilde cevaplamış olabilir miyim? stackoverflow.com/a/4704360/956975
marienke

2
Ne yazık ki, tercihi kalıcı olarak kaldırıyor. Sadece gizlemek mümkün mü?
Dmitry

Benim için de işe yaramıyor. Tercih devam ediyor!
Dmitry

@Dmitry Sadece gri renkte görebilirsinizsetEnabled()
JakeD

212

Eğer a'nız Preferenceiçindeyse PreferenceCategory, bunu yapmanız gerekir:

XML:

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

    <CheckBoxPreference
        android:key="checkPref" />

Java:

CheckBoxPreference mCheckBoxPref = (CheckBoxPreference) findPreference("checkPref");
PreferenceCategory mCategory = (PreferenceCategory) findPreference("category_foo");
mCategory.removePreference(mCheckBoxPref);

5
Adil olmak gerekirse, yukarıdaki cevap ebeveyne ihtiyacınız olduğunu söylüyor PreferenceCategory.
matt

49

Tercih'in tercih ekranının doğrudan bir alt öğesi olması durumunda, bazı bağımsız kodlar şunlardır:

PreferenceScreen screen = getPreferenceScreen();
Preference pref = getPreferenceManager().findPreference("mypreference");
screen.removePreference(pref);

4
Tercih kategori içinde yer alıyorsa bu çalışmaz. Mecbur findPreferencekategori için ve kategoriden tercih kaldırmak
MBH

1
@MBH: Bu uyarıdan bahsettiğiniz için teşekkürler!
1 ''

9

Bir SwitchPreference gibi tercihleri ​​dinamik olarak değiştirecek bir şey istiyorsanız, en iyi yolu tüm alt seçeneklerimi iki kategori kapsayıcılarına koymak olduğunu buldum. Başlangıçta her şey gösterilir, daha sonra istemediğiniz bitleri kaldırırsınız. Zekice biraz, sadece bir şey değiştiğinde yeniden oluşturmayı tetiklersiniz ve sonra elle bir şey oluşturmak veya işleri doğru sıraya koymak konusunda endişelenmenize gerek yoktur.

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();
    }
}

Bununla görebildiğim tek dezavantajı, ekran sıfırdan yeniden oluşturulduğu için bir flaş var.


Dava en azından 22'de çalışmıyor. Ama bunu bir Tercih olarak değiştirmek (bir grup tercih olmasına rağmen) işe yarıyor.
Rob

Rob, yukarıdaki kodu bir API22 AVD'de test ettim ve gayet iyi çalışıyor. Tercih ettiğiniz XML içeriğinin kodunuzla eşleştiğinden emin olun. Yukarıdaki örnek için SwitchPreference herhangi bir yerde olabilir, ancak PreferenceScreen'in doğrudan alt öğeleri olması için PreferenceCategorys'e ihtiyacınız vardır.
James

Kategoriyi bir Tercih olarak aldım, oyuncu seçmedim ve kaldırdım. Çalışmış.
Rob

8

XML dosyanızda:

<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>

Kodunuzda:

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

8

PreferenceFragmentCompat kullanıyorsanız , görünürlüğü xml olarak ayarlayabilirsiniz.

Xml'nizdeki tercihler otomatik olarak AppCompat sürümlerine dönüştürülecektir. Daha sonra xml'nizdeki ' app: isPreferenceVisible ' özelliğini kullanabilirsiniz

preferences.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" />

...

Özellik https://developer.android.com/guide/topics/ui/settings/components-and-attributes adresinde belgelenmiştir.

Ekleme https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy adresindePreferenceFragmentCompat belgelenmiştir.

Misal:

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();
    }
} 


3

XML dosyasında başlık ve özet etiketlerini boş bırakarak gizli bir tercih yapabilirsiniz.

<EditTextPreference
    android:defaultValue="toddlerCam"
    android:key="save_photo_dir"
/>

Bu benim için mükemmel bir cevap. Bunu arıyordum. Teşekkür ederim!
劇場 期 劇場

2

İşte tercihin bir PreferenceCategoryveya altında olup olmadığına bakılmaksızın çalışan genel bir yol 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;
}


0

Bunu 2 şekilde yapabilirsiniz:

Destek kütüphanesini kullanıyorsanız, tercihler ağacının ve ebeveynlerinin bir haritasını oluşturabilir ve ardından üst öğesini kullanarak bir tercihi kaldırabilirsiniz. İşte böyle bir harita oluşturmak için bir fonksiyon:

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. Yeni android-x tercih API'sini kullanıyorsanız, setVisible işlevini kullanarak görünürlüğü ayarlayabilirsiniz .

Dokümanlara göre ve Tea'nin cevabı setVisible() Destek kütüphanesinin 24.1.0 sürümünden beri mevcuttur.
JJD

Yazdıklarıma baktın mı? Ben özellikle şimdi mümkün olduğunu yazdı ... Ayrıca, ilk çözüm gizleme biraz farklı kaldırma, yardımcı olur ..
android geliştirici

Evet, cevabını okudum. 2. noktanızdan bahsediyordum. Bu setVisibile()yöntem açıklığa kavuşturmaya çalıştığım android-x'den geliyormuş gibi okuyor . Suçlama lütfen.
JJD

Tüm destek kitaplıklarının yerini Android-X alır. Destek kütüphanesinin bildiğimiz yeni sürümleri olmayacak.
android geliştirici

Doğru. Bunun farkındayım . Yine de, eski sürümlere yapışmış kişiler bu yöntemi kullanabilir.
JJD

0

Değerlendirmek ve bu maskeye dayanmak istiyorsanız, alternatif olabilir.

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);
}

Bütün bunlar içinde olmalı

public static class PrefsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

1
Üzgünüm, ama bu bir İngiliz sitesi. İngilizce cevap verebilir misiniz?
Dave Schweisguth

Tabii ki niyetim İngilizce bilmeyen insanlara da sunmaktı
Gustavo Eduardo Belduma

3
@GustavoEduardoBelduma o zaman bu okumak gerekebilir meta.stackoverflow.com/a/297680/545026
Leo Monica CELLIO destekler

0

Yapmaya çalıştığımı düşündüğüm şeyi yapıyorsanız (şimdi yapmaya çalışıyorum çünkü) tercihi etkinleştirmek / devre dışı bırakmak daha iyi olabilir. Çünkü bunu kaldırmak ekrandan çıkarır ve ekranı programlı olarak yaptıysanız, istediğiniz yere geri ekleyemeyebilirsiniz.

pref.setEnabled (yanlış); (Doğru) pref.setEnabled;

ancak bu onaylanmamış olabilir. Şu anda yaşadığım kullanım durumu için çalışıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.