Android中删除Preference详解
Android的设置界面实现比较简单,有时甚至只需要使用一个简单的xml文件即可.声明简单,但是如何从PreferenceScreen或者PreferenceCategory中删除一个Preference会简单么.为什么有些人写的就无法删除成功呢?本文将从Android源码实现来分析一下.
声明文件
<?xmlversion="1.0"encoding="utf-8"?>
<PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android"
android:key="root">
<PreferenceCategory
android:key="theme"
android:title="Theme"
android:summary="ThemeSettings"
>
<CheckBoxPreference
android:key="holo_theme"
android:title="HoloTheme"
android:summary="UseHoloTheme"
/>
</PreferenceCategory>
<CheckBoxPreference
android:key="rmcache"
android:title="AutoClearCache"
android:summary="EnableAutoClearCache"
/>
</PreferenceScreen>
层级关系
删除Preference
删除key为rmcache的Preference,这个Preference是PreferenceScreenroot的子节点.
PreferenceScreenscreen=getPreferenceScreen();
CheckBoxPreferenceautoClearCheckboxPref=(CheckBoxPreference)screen.findPreference("rmcache");
screen.removePreference(autoClearCheckboxPref);
删除key为holo_theme的Preference,其为PreferenceScreenroot的孙子节点,非直接关系.
为什么删除失败 很多人出现了删除失败的问题,主要原因是使用了非父亲节点来删除,比如这样 PreferenceGroup删除实现,其实PreferenceScreen和PreferenceCategory都是PreferenceGroup的子类. privatebooleanremovePreferenceInt(Preferencepreference){ 而mPreferenceList中存放的都是当前PreferenceGroup的直接子Preference. findPreference实现 findPreference查找不仅仅限于直接子Preference,会遍历其所有的子Preference. 所以代码中同样有rootPreferenceGroup和直接父PreferenceGroup引用时,通常后者效率会高. if(curKey!=null&&curKey.equals(key)){ if(preferenceinstanceofPreferenceGroup){ returnnull; findPreference和removePreference实现比较 为什么findPreference遍历所有的子节点,而removePreference不会,只会删除直接子Preference 原因有以下几点: 1.findPreference支持遍历查找,减少了声明诸多的中间PreferenceGroup代码.而findPreference属于常用接口方法.
PreferenceCategorythemePrefCategory=(PreferenceCategory)screen.findPreference("theme");
CheckBoxPreferenceholoCheckboxPref=(CheckBoxPreference)themePrefCategory.findPreference("holo_theme");
themePrefCategory.removePreference(holoCheckboxPref);
PreferenceScreenscreen=getPreferenceScreen();
CheckBoxPreferenceholoCheckboxPref=(CheckBoxPreference)screen.findPreference("holo_theme");
screen.removePreference(holoCheckboxPref);
/**
*Removesa{@linkPreference}fromthisgroup.
*
*@parampreferenceThepreferencetoremove.
*@returnWhetherthepreferencewasfoundandremoved.
*/
publicbooleanremovePreference(Preferencepreference){
finalbooleanreturnValue=removePreferenceInt(preference);
notifyHierarchyChanged();
returnreturnValue;
}
synchronized(this){
preference.onPrepareForRemoval();
returnmPreferenceList.remove(preference);
}
}
/**
*Findsa{@linkPreference}basedonitskey.Iftwo{@linkPreference}
*sharethesamekey(notrecommended),thefirsttoappearwillbe
*returned(toretrievetheotherpreferencewiththesamekey,callthis
*methodonthefirstpreference).Ifthispreferencehasthekey,itwill
*notbereturned.
*<p>
*Thiswillrecursivelysearchforthepreferenceintochildrenthatare
*also{@linkPreferenceGroupPreferenceGroups}.
*
*@paramkeyThekeyofthepreferencetoretrieve.
*@returnThe{@linkPreference}withthekey,ornull.
*/
publicPreferencefindPreference(CharSequencekey){
if(TextUtils.equals(getKey(),key)){
returnthis;
}
finalintpreferenceCount=getPreferenceCount();
for(inti=0;i<preferenceCount;i++){
finalPreferencepreference=getPreference(i);
finalStringcurKey=preference.getKey();
returnpreference;
}
finalPreferencereturnedPreference=((PreferenceGroup)preference)
.findPreference(key);
if(returnedPreference!=null){
returnreturnedPreference;
}
}
}
}
2.removePreference调用较少.
3.当存在key相同的Preference时,如果removePreference不限定直接子Preference,那么无法准确删除哪一个.相关文章