ลบ / ซ่อนค่ากำหนดจากหน้าจอ


135

ฉันมีกิจกรรมที่ขยาย PreferenceActivity ฉันกำลังโหลดค่ากำหนดจากไฟล์ xml แต่ในบางกรณีฉันต้องการซ่อนการตั้งค่าอย่างใดอย่างหนึ่งจากหน้าจอตามสถานะแอป มีเมธอด setEnabled แต่มันไม่ตรงกับที่ฉันต้องการ ฉันต้องการลบค่ากำหนดนั้นออกจากหน้าจอโดยสิ้นเชิง เป็นไปได้ไหม ?

คำตอบ:


172

ใช่ถ้าคุณมีการอ้างอิงถึงทั้งคู่Preferenceและพาเรนต์ (a PreferenceCategory, หรือPreferenceScreen)

myPreferenceScreen.removePreference(myPreference);

เยี่ยมมาก! ขอบคุณ! ใช้งานได้และสมเหตุสมผล
Bostone

ฉันอาจจะตอบคำถามของตัวเองผ่านทางนี้? stackoverflow.com/a/4704360/956975
marienke

2
ขออภัยลบค่ากำหนดอย่างถาวร เป็นไปได้ไหมที่จะซ่อนมัน?
Dmitry

มันยังไม่ได้ผลสำหรับฉัน ความชอบยังคงอยู่!
Dmitry

@Dmitry คุณสามารถเป็นสีเทาได้ด้วยsetEnabled()
JakeD

212

หากคุณPreferenceอยู่ภายใน a PreferenceCategoryคุณต้องทำสิ่งนี้:

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
เพื่อความเป็นธรรม, PreferenceCategoryคำตอบข้างต้นไม่บอกว่าคุณแม่ต้อง
แมตต์

50

ในกรณีที่ Preference เป็นลูกโดยตรงของหน้าจอการตั้งค่านี่คือรหัสแบบสแตนด์อโลน:

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

4
สิ่งนี้จะไม่ได้ผลหากความชอบอยู่ในหมวดหมู่ คุณต้องfindPreferenceสำหรับหมวดหมู่และลบการตั้งค่าออกจากหมวดหมู่
MBH

1
@MBH: ขอบคุณที่พูดถึงข้อแม้!
1 ''

10

หากคุณใช้PreferenceFragmentCompatคุณสามารถตั้งค่า visiblity เป็น xml

ค่ากำหนดใน xml ของคุณจะถูกแปลงเป็นเวอร์ชัน AppCompat โดยอัตโนมัติ จากนั้นคุณสามารถใช้แอตทริบิวต์" app: isPreferenceVisible " ใน xml ของคุณ

การตั้งค่า. 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" />

...

แอตทริบิวต์ได้รับการบันทึกไว้ที่https://developer.android.com/guide/topics/ui/settings/components-and-attributes

บันทึกการเพิ่มPreferenceFragmentCompatไว้ที่https://developer.android.com/guide/topics/ui/settings/#inflate_the_hierarchy

ตัวอย่าง:

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

9

หากคุณต้องการบางสิ่งที่จะเปลี่ยนคำนำหน้าแบบไดนามิกเช่นใน SwitchPreference ฉันพบวิธีที่ดีที่สุดคือใส่ตัวเลือกย่อยทั้งหมดลงในคอนเทนเนอร์สองหมวดหมู่ เริ่มแรกคุณจะมีทุกอย่างที่แสดงจากนั้นคุณเพียงแค่ลบบิตที่คุณไม่ต้องการ บิตที่ชาญฉลาดคือคุณเพียงแค่เรียกสร้างขึ้นใหม่เมื่อมีการเปลี่ยนแปลงบางอย่างจากนั้นคุณไม่จำเป็นต้องสร้างอะไรด้วยตนเองหรือกังวลเกี่ยวกับการวางสิ่งต่างๆในลำดับที่ถูกต้อง

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

ข้อเสียเพียงอย่างเดียวที่ฉันเห็นจากสิ่งนี้คือมีแฟลชเนื่องจากหน้าจอถูกสร้างขึ้นใหม่ตั้งแต่ต้น


กรณีนี้ใช้ไม่ได้อย่างน้อยก็ไม่ใช่ใน 22 แต่การเปลี่ยนเป็นค่ากำหนด (แม้ว่าจะเป็นการจัดกลุ่มความชอบ) ก็ใช้งานได้
Rob

Rob ฉันเพิ่งทดสอบโค้ดด้านบนใน API22 AVD และใช้งานได้ดี ตรวจสอบให้แน่ใจว่าเนื้อหา XML การตั้งค่าของคุณตรงกับรหัสของคุณ สำหรับตัวอย่างข้างต้น SwitchPreference สามารถอยู่ที่ใดก็ได้ แต่คุณต้องการ PreferenceCategorys เพื่อเป็นลูกโดยตรงของ PreferenceScreen
James

ฉันเพิ่งได้หมวดหมู่เป็นค่ากำหนดไม่มีนักแสดงและลบออก ทำงานแล้ว.
Rob

8

ในไฟล์ XML ของคุณ:

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

ในรหัสของคุณ:

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

5

ฉันแนะนำให้ใช้การตั้งค่า v7 มันมีsetVisible()วิธีการ แต่ผมยังไม่เคยลอง ดังนั้นคุณต้องใช้PreferenceFragmentแทนPreferenceActivity.


คำตอบที่ยอมรับจะใช้ไม่ได้กับ V7 การใช้ setVisible ใช้งานได้กับ V7
m12lrpv

V7 ก็มีgetParent()เช่นกันดังนั้นคุณสามารถลบค่ากำหนดตามที่อธิบายไว้ในคำตอบนี้ได้
user905686

3

ในไฟล์ XML คุณสามารถสร้างการกำหนดลักษณะที่ซ่อนอยู่ได้โดยปล่อยให้หัวเรื่องและแท็กสรุปว่างเปล่า

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

นี่คือคำตอบที่สมบูรณ์แบบสำหรับฉัน ฉันกำลังมองหาสิ่งนี้ ขอบคุณ!
夏期劇場

2

นี่คือวิธีทั่วไปเพื่อทำเช่นนี้ที่ทำงานโดยไม่คำนึงว่าการตั้งค่าอยู่ภายใต้หรือPreferenceCategoryPreferenceScreen

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

2

เนื่องจากมีgetParent()วิธีAndroid API 26 : https://developer.android.com/reference/android/preference/Preference.html#getParent ()

แม้ว่าคุณจะทำสิ่งต่อไปนี้ได้:

preference.getParent().removePreference(preference);

นอกจากนี้ยังพร้อมใช้งานสำหรับ API 26 ด้านล่างพร้อมไลบรารีการสนับสนุน androidx
user905686

0

คุณสามารถทำได้ 2 วิธี:

1. หากคุณใช้ไลบรารีการสนับสนุนคุณสามารถสร้างแผนผังต้นไม้แห่งความชอบและพาเรนต์จากนั้นจึงลบการตั้งค่าโดยใช้พาเรนต์ นี่คือฟังก์ชั่นในการสร้างแผนที่ดังกล่าว:

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. หากคุณใช้ API การกำหนดลักษณะ android-x ใหม่คุณสามารถตั้งค่าการมองเห็นได้โดยใช้ฟังก์ชันsetVisible

ตามเอกสารและคำตอบของ Tea setVisible()มีให้ตั้งแต่เวอร์ชัน 24.1.0 ของไลบรารี Support
JJD

คุณดูสิ่งที่ฉันเขียนหรือยัง? ฉันเขียนโดยเฉพาะว่าเป็นไปได้แล้ว ... นอกจากนี้วิธีแก้ปัญหาแรกช่วยในการลบซึ่งแตกต่างจากการซ่อนเล็กน้อย ..
นักพัฒนา android

ใช่ฉันอ่านคำตอบของคุณ ฉันหมายถึงจุดที่ 2 ของคุณ มันอ่านราวกับว่าsetVisibile()วิธีนี้สามารถใช้ได้จากandroid-xซึ่งฉันพยายามชี้แจง กรุณาไม่มีความผิด
JJD

Android-X เป็นหนึ่งในการแทนที่ไลบรารีการสนับสนุนทั้งหมด จะไม่มีไลบรารีการสนับสนุนเวอร์ชันใหม่อย่างที่เรารู้จัก
นักพัฒนา Android

แก้ไข. ผมตระหนักถึงเรื่องนี้ ถึงกระนั้นผู้คนที่ติดอยู่กับเวอร์ชันเก่าสามารถใช้วิธีนี้ได้
JJD

0

หากคุณต้องการประเมินและอิงตามหน้ากากนั้นอาจมีทางเลือกอื่น

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

ทั้งหมดนี้ต้องอยู่ภายใน

public static class PrefsFragment extends PreferenceFragment {

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

1
ขออภัยนี่เป็นเว็บไซต์ภาษาอังกฤษ ตอบเป็นภาษาอังกฤษได้ไหม?
Dave Schweisguth

แน่นอน
ว่าความ

3
@GustavoEduardoBelduma ถ้าอย่างนั้นคุณอาจต้องอ่านmeta.stackoverflow.com/a/297680/545026
Leo สนับสนุน Monica Cellio

0

หากคุณกำลังทำในสิ่งที่ฉันคิดว่าคุณกำลังพยายามทำอยู่ (เพราะฉันกำลังพยายามทำอยู่ตอนนี้) การเปิด / ปิดการตั้งค่าอาจจะดีกว่า เนื่องจากการลบจะนำออกจากหน้าจอการตั้งค่าและคุณอาจไม่สามารถเพิ่มกลับในตำแหน่งที่คุณต้องการได้หากคุณสร้างหน้าจอโดยใช้โปรแกรม

pref.setEnabled (เท็จ); pref.setEnabled (จริง);

แม้ว่าอาจจะเลิกใช้งานไปแล้วก็ตาม ใช้ได้กับกรณีการใช้งานที่ฉันกำลังทำอยู่ตอนนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.