android preference自定义

1、对于一些简单的preference布局可以仿照frameworks\base\core\res\res\layout文件夹下面的preference相关的布局文件进行布局,但是在书写的时候要注意关于每一个id的名称一定要使用preference系统文件里面的,不可以自己定义,否则会出现异常


2、android中自定义preference,自定义的流程是:首先是在onCreateView的方法中加载布局文件,然后在onBIndView中进行操作,其源代码如下:

/**
     * Creates the View to be shown for this Preference in the
     * {@link PreferenceActivity}. The default behavior is to inflate the main
     * layout of this Preference (see {@link #setLayoutResource(int)}. If
     * changing this behavior, please specify a {@link ViewGroup} with ID
     * {@link android.R.id#widget_frame}.
     * 

* Make sure to call through to the superclass's implementation. * * @param parent The parent that this View will eventually be attached to. * @return The View that displays this Preference. * @see #onBindView(View) */ protected View onCreateView(ViewGroup parent) { final LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View layout = layoutInflater.inflate(mLayoutResId, parent, false); final ViewGroup widgetFrame = (ViewGroup) layout .findViewById(com.android.internal.R.id.widget_frame); if (widgetFrame != null) { if (mWidgetLayoutResId != 0) { layoutInflater.inflate(mWidgetLayoutResId, widgetFrame); } else { widgetFrame.setVisibility(View.GONE); } } return layout; }


此时会返回你加载的布局文件,然后再onBindView方法中添加一些处理的逻辑源代码如下:
/**
     * Binds the created View to the data for this Preference.
     * 

* This is a good place to grab references to custom Views in the layout and * set properties on them. *

* Make sure to call through to the superclass's implementation. * * @param view The View that shows this Preference. * @see #onCreateView(ViewGroup) */ protected void onBindView(View view) { TextView textView = (TextView) view.findViewById(com.android.internal.R.id.title); if (textView != null) { textView.setText(getTitle()); } textView = (TextView) view.findViewById(com.android.internal.R.id.summary); if (textView != null) { final CharSequence summary = getSummary(); if (!TextUtils.isEmpty(summary)) { if (textView.getVisibility() != View.VISIBLE) { textView.setVisibility(View.VISIBLE); } textView.setText(getSummary()); } else { if (textView.getVisibility() != View.GONE) { textView.setVisibility(View.GONE); } } } ImageView imageView = (ImageView) view.findViewById(com.android.internal.R.id.icon); if (imageView != null) { if (mIconResId != 0 || mIcon != null) { if (mIcon == null) { mIcon = getContext().getResources().getDrawable(mIconResId); } if (mIcon != null) { imageView.setImageDrawable(mIcon); } } imageView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE); } if (mShouldDisableView) { setEnabledStateOnViews(view, isEnabled()); } }

下面说一下在preference中上面两个方法的调用逻辑:他们的调用逻辑是在方法getView中进行处理的,代码如下:

    /**
     * Gets the View that will be shown in the {@link PreferenceActivity}.
     * 
     * @param convertView The old View to reuse, if possible. Note: You should
     *            check that this View is non-null and of an appropriate type
     *            before using. If it is not possible to convert this View to
     *            display the correct data, this method can create a new View.
     * @param parent The parent that this View will eventually be attached to.
     * @return Returns the same Preference object, for chaining multiple calls
     *         into a single statement.
     * @see #onCreateView(ViewGroup)
     * @see #onBindView(View)
     */
    public View getView(View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = onCreateView(parent);
        }
        onBindView(convertView);
        return convertView;
    }
写到这里你也许就会问这个getView是在哪里调用的呢?调用代码如下,是在PreferenceGroupAdapter里面的getView中,这个很好理解其实每一个PrefrenceGroup都是一个listview,故是在getView中来操作:

public View getView(int position, View convertView, ViewGroup parent) {
        final Preference preference = this.getItem(position);
        // Build a PreferenceLayout to compare with known ones that are cacheable.
        mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout);

        // If it's not one of the cached ones, set the convertView to null so that 
        // the layout gets re-created by the Preference.
        if (Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout) < 0) {
            convertView = null;
        }

        return preference.getView(convertView, parent);
    }


综上所述其实在在自定义一个preference的时候只需要覆盖createView和onBindView两个方法即可。例子就不写了,只分析一下源代码吧。

在看preference的源代码的时候顺便看了一下,checkboxpreference的实现原理,一开始没有弄明白每次点击时保存状态是在哪里执行的,后来详细看了一下代码发现实现的地方是在persistXXX里面进行之星的,而checkboxpreference在onclick事件里面会进行调用persistBoolean方法进行写入文件中,下面是题外话了。





你可能感兴趣的:(android)