PreferenceActivity源码分析

    xiaoxiao2026-01-01  9

    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));
    转载请注明原文地址: https://ju.6miu.com/read-1305563.html
    最新回复(0)