PreferenceActivity源码分析

Android PreferenceActivity 源码分析

PreferenceActivity 的继承关系,

public abstract class PreferenceActivity extends ListActivity implements
    PreferenceManager.OnPreferenceTreeClickListener,
    PreferenceFragment.OnPreferenceStartFragmentCallback {
    。。。
}

从上面可以看出,preferenceActivity 其实是listActivity。

onCreate 初始关布局

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

    // Theming for the PreferenceActivity layout and for the Preference Header(s) layout
    TypedArray sa = obtainStyledAttributes(null,
            com.android.internal.R.styleable.PreferenceActivity,
            com.android.internal.R.attr.preferenceActivityStyle,
            0);

    final int layoutResId = sa.getResourceId(
            com.android.internal.R.styleable.PreferenceActivity_layout,
            com.android.internal.R.layout.preference_list_content);

    mPreferenceHeaderItemResId = sa.getResourceId(
            com.android.internal.R.styleable.PreferenceActivity_headerLayout,
            com.android.internal.R.layout.preference_header_item);
    mPreferenceHeaderRemoveEmptyIcon = sa.getBoolean(
            com.android.internal.R.styleable.PreferenceActivity_headerRemoveIconIfEmpty,
            false);

    sa.recycle();

    setContentView(layoutResId);

    ...

Activity 在oncreate 时,先将com.android.internal.R.layout.preferenc_list_content 作为默认的layout。

layout的具体定义如下:

addPreferencesFromResource

    @Deprecated
public void addPreferencesFromIntent(Intent intent) {
    if (DBG) {
        Log.d(TAG, "addPreferencesFromIntent, intent = " + intent);
    }

    requirePreferenceManager();

    setPreferenceScreen(mPreferenceManager.inflateFromIntent(intent, getPreferenceScreen()));
}

setPreferenceScreen

    /**
 * Sets the root of the preference hierarchy that this activity is showing.
 *
 * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.
 *
 * @deprecated This function is not relevant for a modern fragment-based
 * PreferenceActivity.
 */
@Deprecated
public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
    requirePreferenceManager();

    if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {
        postBindPreferences();
        CharSequence title = getPreferenceScreen().getTitle();
        // Set the title of the activity
        if (title != null) {
            setTitle(title);
        }
    }
}

postBindPreferences

    /**
 * Posts a message to bind the preferences to the list view.
 * <p>
 * Binding late is preferred as any custom preference types created in
 * {@link #onCreate(Bundle)} are able to have their views recycled.
 */
private void postBindPreferences() {
    if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;
    mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
}

bindPreferences

    private void bindPreferences() {
    final PreferenceScreen preferenceScreen = getPreferenceScreen();
    if (preferenceScreen != null) {
        preferenceScreen.bind(getListView());
        if (mSavedInstanceState != null) {
            super.onRestoreInstanceState(mSavedInstanceState);
            mSavedInstanceState = null;
        }
    }

PreferenceScreen.java

    public void bind(ListView listView) {
    listView.setOnItemClickListener(this);
    listView.setAdapter(getRootAdapter());

    onAttachedToActivity();
}

PreferenceGroup.java

    @Override
protected void onAttachedToActivity() {
    super.onAttachedToActivity();

    // Mark as attached so if a preference is later added to this group, we
    // can tell it we are already attached
    mAttachedToActivity = true;

    // Dispatch to all contained preferences
    final int preferenceCount = getPreferenceCount();
    for (int i = 0; i < preferenceCount; i++) {
        getPreference(i).onAttachedToActivity();
    }
}

Preference.java

    protected void onAttachedToActivity() {
    // At this point, the hierarchy that this preference is in is connected
    // with all other preferences.
    registerDependency();
}

registerDependency

    private void registerDependency() {

    if (TextUtils.isEmpty(mDependencyKey)) return;

    Preference preference = findPreferenceInHierarchy(mDependencyKey);
    if (preference != null) {
        preference.registerDependent(this);
    } else {
        throw new IllegalStateException("Dependency \"" + mDependencyKey
                + "\" not found for preference \"" + mKey + "\" (title: \"" + mTitle + "\"");
    }

registerDependent

    private void registerDependent(Preference dependent) {
    if (mDependents == null) {
        mDependents = new ArrayList<Preference>();
    }

    mDependents.add(dependent);

    dependent.onDependencyChanged(this, shouldDisableDependents());
}

其中 private List mDependents;

对list 设置显示参数通过HeaderAdapter 完成的。

    private static class HeaderAdapter extends ArrayAdapter<Header> {
    private static class HeaderViewHolder {
        ImageView icon;
        TextView title;
        TextView summary;
    }

    private LayoutInflater mInflater;
    private int mLayoutResId;
    private boolean mRemoveIconIfEmpty;

    public HeaderAdapter(Context context, List<Header> objects, int layoutResId,
            boolean removeIconBehavior) {
        super(context, 0, objects);
        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mLayoutResId = layoutResId;
        mRemoveIconIfEmpty = removeIconBehavior;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        HeaderViewHolder holder;
        View view;

        if (convertView == null) {
            view = mInflater.inflate(mLayoutResId, parent, false);
            holder = new HeaderViewHolder();
            holder.icon = (ImageView) view.findViewById(com.android.internal.R.id.icon);
            holder.title = (TextView) view.findViewById(com.android.internal.R.id.title);
            holder.summary = (TextView) view.findViewById(com.android.internal.R.id.summary);
            view.setTag(holder);
        } else {
            view = convertView;
            holder = (HeaderViewHolder) view.getTag();
        }

        // All view fields must be updated every time, because the view may be recycled 
        Header header = getItem(position);
        if (mRemoveIconIfEmpty) {
            if (header.iconRes == 0) {
                holder.icon.setVisibility(View.GONE);
            } else {
                holder.icon.setVisibility(View.VISIBLE);
                holder.icon.setImageResource(header.iconRes);
            }
        } else {
            holder.icon.setImageResource(header.iconRes);
        }
        holder.title.setText(header.getTitle(getContext().getResources()));
        CharSequence summary = header.getSummary(getContext().getResources());
        if (!TextUtils.isEmpty(summary)) {
            holder.summary.setVisibility(View.VISIBLE);
            holder.summary.setText(summary);
        } else {
            holder.summary.setVisibility(View.GONE);
        }

        return view;
    }
}

在oncreate 中通过完成。

            setListAdapter(new HeaderAdapter(this, mHeaders, mPreferenceHeaderItemResId,
                mPreferenceHeaderRemoveEmptyIcon));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值