当前位置: 移动技术网 > IT编程>移动开发>Android > Android中删除Preference详解

Android中删除Preference详解

2019年07月24日  | 移动技术网IT编程  | 我要评论

柯南世界的大后宫,有妻足焉,战狼2 bt

android的设置界面实现比较简单,有时甚至只需要使用一个简单的xml文件即可.声明简单,但是如何从preferencescreen或者preferencecategory中删除一个preference会简单么.为什么有些人写的就无法删除成功呢?本文将从android源码实现来分析一下.

声明文件

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<preferencescreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="root">

  <preferencecategory
      android:key="theme"
      android:title="theme"
      android:summary="theme settings"
      >
      <checkboxpreference
          android:key="holo_theme"
          android:title="holo theme"
          android:summary="use holo theme"
          />
     
  </preferencecategory>
 
  <checkboxpreference
      android:key="rmcache"
      android:title="auto clear cache"
      android:summary="enable auto clear cache "
      />
</preferencescreen>

层级关系

删除preference

删除key为rmcache的preference,这个preference是preferencescreen root的子节点.

复制代码 代码如下:

preferencescreen screen = getpreferencescreen();
checkboxpreference autoclearcheckboxpref = (checkboxpreference) screen.findpreference("rmcache");
screen.removepreference(autoclearcheckboxpref);

删除key为holo_theme的preference,其为preferencescreen root的孙子节点,非直接关系.

复制代码 代码如下:

preferencecategory themeprefcategory = (preferencecategory) screen.findpreference("theme");
checkboxpreference holocheckboxpref = (checkboxpreference)themeprefcategory.findpreference("holo_theme");
themeprefcategory.removepreference(holocheckboxpref);

为什么删除失败

很多人出现了删除失败的问题,主要原因是使用了非父亲节点来删除,比如这样

复制代码 代码如下:

preferencescreen screen = getpreferencescreen();
checkboxpreference holocheckboxpref = (checkboxpreference)screen.findpreference("holo_theme");
screen.removepreference(holocheckboxpref);

preferencegroup删除实现,其实preferencescreen和preferencecategory都是preferencegroup的子类.

复制代码 代码如下:

/**
     * removes a {@link preference} from this group.
     *
     * @param preference the preference to remove.
     * @return whether the preference was found and removed.
     */
    public boolean removepreference(preference preference) {
        final boolean returnvalue = removepreferenceint(preference);
        notifyhierarchychanged();
        return returnvalue;
    }

    private boolean removepreferenceint(preference preference) {
        synchronized(this) {
            preference.onprepareforremoval();
            return mpreferencelist.remove(preference);
        }
    }

而mpreferencelist中存放的都是当前preferencegroup的直接子preference.

findpreference实现

findpreference查找不仅仅限于直接子preference,会遍历其所有的子preference.

所以代码中同样有root preferencegroup和直接父preferencegroup引用时,通常后者效率会高.

复制代码 代码如下:

/**
 * finds a {@link preference} based on its key. if two {@link preference}
 * share the same key (not recommended), the first to appear will be
 * returned (to retrieve the other preference with the same key, call this
 * method on the first preference). if this preference has the key, it will
 * not be returned.
 * <p>
 * this will recursively search for the preference into children that are
 * also {@link preferencegroup preferencegroups}.
 *
 * @param key the key of the preference to retrieve.
 * @return the {@link preference} with the key, or null.
 */
public preference findpreference(charsequence key) {
    if (textutils.equals(getkey(), key)) {
        return this;
    }
    final int preferencecount = getpreferencecount();
    for (int i = 0; i < preferencecount; i++) {
        final preference preference = getpreference(i);
        final string curkey = preference.getkey();

        if (curkey != null && curkey.equals(key)) {
            return preference;
        }

        if (preference instanceof preferencegroup) {
            final preference returnedpreference = ((preferencegroup)preference)
                    .findpreference(key);
            if (returnedpreference != null) {
                return returnedpreference;
            }
        }
    }

    return null;
}

findpreference和removepreference实现比较

为什么findpreference遍历所有的子节点,而removepreference不会,只会删除直接子preference

原因有以下几点:

1.findpreference支持遍历查找,减少了声明诸多的中间preferencegroup代码.而findpreference属于常用接口方法.
2.removepreference调用较少.
3.当存在key相同的preference时,如果removepreference不限定直接子preference,那么无法准确删除哪一个.

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网