Android -PreferenceFragment 对ListView自动添加和移除Preference数据对象

哼着小曲 听着田馥甄的《小幸运》。--遇见你是注定,也许当时忙着微笑和哭泣,离别之后只会流泪和哭泣。当我没听见你声音,我又重新做回我自己,她会有多幸运。哎....抒发下半年以来的压抑和哭泣。让我看着你们手中的亮光好吧!---在Android原生系统中所看到的设置界面,使用的是与Preference相关的视图完成的。使用Preference相关的视图能较好地进行了文字的分类和排版。而原生的preference基本很难满足我们的需求开发,所以自定义preference必不可缺。而为了使应用更轻量更碎片化,preferencefragment也是需要的。
本篇文章防谷歌样式的自定义preference结合preferencefragment的体现来讲解:主要通过key_values健值对ListViw里面自动添加和移除。
class Settings extends PreferenceFragment
private SwitchPreference mApSwitch;

  @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    init();
    mContext = getActivity().getBaseContext();
    mApSwitch = (SwitchPreference)    buildPreference(R.string.title_network_hot_post, 0, true, isWifiApEnable());
    buildPreference(R.string.input_ap_password,  mWifiAP.getPreSharedKey(), false, false); //自动添加
}
    //ListViw里面移除
    List list =getPrefeerences();
    Iterator iterator = list.iterator();
    while(iterator.hashNext()){
          Preference preference =iterator.next();
          if(preference.getId() == R.string.input_ap_password){
               iterator.remove();
          }
     }

2.第二部就是自定义Preference的文件啦!
、、、
public abstract class Preference {
private View rootView;

protected int id;

protected int iconId = 0;

private PreferenceFragment fragment;

protected String title;

private String key;

protected String summary;
protected TextView titleView, summaryView;

protected OnPreferenceClickListener mOnClickListener;

protected OnPreferenceChangeListener mOnChangeListener;

protected boolean isShowIcon = true;

protected boolean isEnable = true;

protected Context mContext;

public abstract View buildView(Context context, View view);

public Preference(Context context, String title) {
    this(context, title, null);
}

public Preference(Context context, String title, String summary) {
    this.title = title;
    this.summary = summary;
    mContext = context;
}

public int getId() {
    return id;
}

public void setKey(String key) {
    this.key = key;
}

public String getKey(){
    return key;
}

public void setId(int id) {
    this.id = id;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
    if (titleView != null) {
        titleView.setText(title);
    }
}

public String getSummary() {
    return summary;
}

public void setSummary(String summary) {
    this.summary = summary;
    if (rootView != null){
        summaryView = (TextView) rootView.findViewById(R.id.summary);
        if (summaryView != null) {
            summaryView.setText(summary);
            summaryView.setVisibility(TextUtils.isEmpty(summary) ? View.GONE
                    : View.VISIBLE);
        }
    }
}

public PreferenceFragment getFragment() {
    return fragment;
}

public void setFragment(PreferenceFragment fragment) {
    this.fragment = fragment;
}

public void initView(View view) {
    Log.i(TAG , "preference init View title = " + title + " summary = " + summary);
    rootView = view;
    titleView = (TextView) view.findViewById(R.id.title);
    summaryView = (TextView) view.findViewById(R.id.summary);
    
    if (!TextUtils.isEmpty(title)) {
        titleView.setText(title);
        titleView.setVisibility(View.VISIBLE);
    } else {
        titleView.setVisibility(View.GONE);
    }
    
    Log.i(TAG , "preference init summaryView = " + summaryView + " summary = " + summary);
    if (!TextUtils.isEmpty(summary)) {
        summaryView.setText(summary);
        summaryView.setVisibility(View.VISIBLE);
    } else {
        summaryView.setVisibility(View.GONE);
    }
    
    titleView.setTextColor(isEnable ? mContext.getResources().getColor(android.R.color.white)
            : mContext.getResources().getColor(R.color.setting_line_color));
}

public void setEnabled(boolean enabled) {
    isEnable = enabled;
    if (titleView != null) {
        titleView.setTextColor(enabled ? mContext.getResources().getColor(
                android.R.color.white) : mContext.getResources().getColor(
                R.color.setting_line_color));
    }
}

public boolean getEnable() {
    return isEnable;
}

/**
 * Interface definition for a callback to be invoked when the value of this
 * {@link Preference} has been changed by the user and is about to be set
 * and/or persisted. This gives the client a chance to prevent setting
 * and/or persisting the value.
 */
public interface OnPreferenceChangeListener {
    /**
     * Called when a Preference has been changed by the user. This is called
     * before the state of the Preference is about to be updated and before
     * the state is persisted.
     * 
     * @param preference
     *            The changed Preference.
     * @param newValue
     *            The new value of the Preference.
     * @return True to update the state of the Preference with the new
     *         value.
     */
    boolean onPreferenceChange(Preference preference, Object newValue);
}

/**
 * Interface definition for a callback to be invoked when a
 * {@link Preference} is clicked.
 */
public interface OnPreferenceClickListener {
    /**
     * Called when a Preference has been clicked.
     * 
     * @param preference
     *            The Preference that was clicked.
     * @return True if the click was handled.
     */
    void onPreferenceClick(Preference preference);
}

/**
 * Sets the callback to be invoked when this Preference is clicked.
 * 
 * @param onPreferenceClickListener
 *            The callback to be invoked.
 */
public void setOnPreferenceClickListener(
        OnPreferenceClickListener onPreferenceClickListener) {
    mOnClickListener = onPreferenceClickListener;
}

/**
 * Sets the callback to be invoked when this Preference is changed by the
 * user (but before the internal state has been updated).
 * 
 * @param onPreferenceChangeListener
 *            The callback to be invoked.
 */
public void setOnPreferenceChangeListener(
        OnPreferenceChangeListener onPreferenceChangeListener) {
    mOnChangeListener = onPreferenceChangeListener;
}

public void performClick() {
    if (isEnable){
        if (mOnClickListener != null) {
            mOnClickListener.onPreferenceClick(this);
        }
    }
}

/**
 * Call this method after the user changes the preference, but before the
 * internal state is set. This allows the client to ignore the user value.
 * 
 * @param newValue
 *            The new value of this Preference.
 * @return True if the user value should be set as the preference value (and
 *         persisted).
 */
protected void callChangeListener(Object newValue) {
    if (mOnChangeListener != null) {
        mOnChangeListener.onPreferenceChange(this, newValue);
    }
}

}
、、、
该类主要介绍 titleView, summaryView两个TextView的添加、以及设置 OnPreferenceClickListener,setOnPreferenceChangeListener两个点击事件接口回调,内容比较简单就
不过多的介绍了。
3.第三部让我们来看看PreferenceFragment的精妙的写法吧!该类继承了Preference类里面的两个监听回调的接口OnPreferenceClickListener, OnPreferenceChangeListener
、、、
public abstract class PreferenceFragment extends SubFragment implements OnPreferenceClickListener,
OnPreferenceChangeListener{

private static final String TAG = PreferenceFragment.class.getSimpleName();
private ListView mListView;
private List mList = new ArrayList();
private PreferenceAdapter adapter;

/** 默认选中项 */
private int mCurSelected = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mList.clear();
}

public void setSelect(int select){
    if (select >= 0 && select < mList.size() && mCurSelected != select) {
        mCurSelected = select;
        if (adapter != null) {
            adapter.setSelect(mCurSelected);
        }
        
        Log.i(TAG, "setSelect mCurSelected = " + mCurSelected);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View view = getCustomView();
    if (view == null) {
        view = inflater.inflate(R.layout.fragment_preference, null);
    }
    initView(view);
    return view;
}

/**
 * 如果子类想重写此fragment的布局 请重写此方法
 * @return 自定的PreferenceView 此View 必须包含一个ListView 并且ID为 item_list
 * 如果为null 将使用默认的Fragment
 */
protected View getCustomView() {
    return null;
}

private void initView(View view) {
    adapter = new PreferenceAdapter(mList, getActivity());
    adapter.setSelect(mCurSelected);    
    mListView = (ListView) view.findViewById(R.id.item_list);
    if (mListView == null) {
        throw new IllegalArgumentException("自定义的PreferenceFragment 必须包含一个ListView 并且id为 item_list");
    }
    
    mListView.setAdapter(adapter);
    mListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView viewGroup, View view, int position,
                long id) {
            adapter.getItem(position).performClick();
        }
    });
}

public void setVerticalScrollBarEnabled(boolean show){
    mListView.setVerticalScrollBarEnabled(show);
}

public void addPreference(Preference preference){ //在ListView里面添加Preference对象
    if (!mList.contains(preference)){
        mList.add(preference);
        preference.setFragment(this);
        
        if (mListView != null){
            adapter.notifyDataSetChanged();
        }
    }
}

public void removePreference(Preference preference){
    if (mList.contains(preference)){
        mList.remove(preference);
        
        if (mListView != null){
            adapter.notifyDataSetChanged();
        }
    }
}

public Preference findPrederenceById(int id){
    for (Preference preference : mList){
        if (preference.getId() == id){
            return preference;
        }
    }
    return null;
}

public void refresh(){
    if (mListView != null){
        adapter.notifyDataSetChanged();
    }
}

public void removeAllPreference(){
    mList.clear();
    
    if (mListView != null){
        adapter.notifyDataSetChanged();
    }
}

public int getPreferenceCount(){
    return mList.size();
}

public List getPreferences(){
    return mList;
}


/**
 * 向上移动一项
 */
public void onMoveToUp() {
    Log.i(TAG, "onMoveToUp ");
    setSelect(mCurSelected - 1);
}

/**
 * 向下移动一项
 */
public void onMoveToDown() {
    Log.i(TAG, "onMoveToDown ");
    setSelect(mCurSelected + 1);
}

/**
 * ok键被按下
 */
public void onCenterSure() {
    Log.i(TAG, "onCenterSure mCurSelected = " + mCurSelected);
    adapter.getItem(mCurSelected).performClick();
}

/**
 * 
 * @param titleId  标题
 * @param summayId 简要信息
 * @param isCheckPreference  是否是带check功能的Preference
 * @param isChecked 初始值
 * @return
 */
protected Preference buildPreference(int titleId, int summayId, boolean isSwitchPreference, boolean isChecked) {
    return buildPreference(titleId, summayId != 0 ? getString(summayId) : null, isSwitchPreference, isChecked);
}

/**
 * 
 * @param titleId  标题
 * @param summay 简要信息
 * @param isCheckPreference  是否是带check功能的Preference
 * @param isChecked 初始值
 * @return
 */
protected Preference buildPreference(int titleId, String summay, boolean isSwitchPreference, boolean isChecked) {
    Preference preference = null;
    if (isSwitchPreference){
        preference = new SwitchPreference(getActivity(), getString(titleId));
        ((SwitchPreference)preference).setChecked(isChecked, false);
        preference.setOnPreferenceChangeListener(this);
    }else{
        preference = new BasePreference(getActivity(), getString(titleId));
    }
    if (summay != null){
        preference.setSummary(summay);
    }
    
    preference.setOnPreferenceClickListener(this);
    preference.setId(titleId);
    addPreference(preference);
    return preference;
}

}
、、、
在该类中我们终于看见我们所关注的 buildPreference方法啦!是不是有点小激动。方法里面我们会看见addPreference(preference)的添加Preference对象的方法。再仔细
观察下你会发现该类已经写好Preference对象的添加、移除、刷新、全部移除等方法。同时Preference对象我们存储到 List 集合中。
4.其中fragment_preference布局如下就是一个ListView 哈哈:
android:layout_width="match_parent"
android:layout_height="match_parent"
>
android:id="@+id/item_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@drawable/menu_drivder"
android:dividerHeight="3dp"
android:listSelector="@android:color/transparent"
>


5.那我们Preference对象里面的数据布局怎么布局呢?俗话说“家有小妙招”请接下看小编的详解:自定义一个SwitchPreference类继承Preference类 代码如下:

public class SwitchPreference extends Preference{
protected static final String TAG = "Settings.SwitchPreference";
private CheckSwitchButton switchButton;

private boolean isChecked;

public SwitchPreference(Context context, String title) {
    this(context, title, null);
}

public SwitchPreference(Context context, String title, String summary) {
    super(context, title, summary);
}
public View buildView(Context context, View view) {
    if (view == null){
        view = View.inflate(context, R.layout.preference_switch_view, null);
        view.setTag(this);
    }else{
        Object tag = view.getTag();
        if (tag == null ||  !(tag instanceof SwitchPreference)){
            view = View.inflate(context, R.layout.preference_switch_view, null);
            view.setTag(this);
        }
    }
    initView(view, context);
    return view;
}

public void initView(View view, Context context) {
    super.initView(view);
    Log.i(TAG , " initView isChecked = " + isChecked + " title = " + title);
    switchButton = (CheckSwitchButton) view.findViewById(R.id.switch_button);
    switchButton.setOnSwitchChangeListener(new OnSwitchChangeListener() {
        
        @Override
        public void onCheckedChanged(CheckSwitchButton switchButton,
                boolean isChecked, boolean isTracking) {
            SwitchPreference.this.isChecked = isChecked;
            if (isTracking){
                callChangeListener(isChecked);
            }
        }
    });
    switchButton.setChecked(isChecked);
}

/**
 * 
 * @param isChecked 
 * @param isByUser ?????????????
 */
public void setChecked(boolean isChecked, boolean isByUser){
    if (switchButton != null){
        if (isByUser){
            switchButton.setCheckedByUser(isChecked);
        }else{
            switchButton.setChecked(isChecked);
        }
    }
    this.isChecked = isChecked;
}

public boolean isChecked(){
    if (switchButton != null){
        return switchButton.isChecked();
    }
    
    return isChecked;
}

@Override
public void performClick() {
    super.performClick();
}

}

在该子类 SwitchPreference中 加载布局layout.preference_switch_view就是Preference对象数据传递UI显示。用户可以根据自身需求改变布局,继承Preference类即可完成所需的功能,简单方便吧!
6.展示下layout.preference_switch_view 的布局:

    

        

        
        
    
   


OK ,《小幸运》单曲循环十几遍了 我也改收尾了!--本文终于写完了,翻看源码,查阅资料,画图花了两天时间,最后回顾一下,我们是如何通过key_values健值对ListViw里面自动添加和移除自定义Preference对象数据呢?下篇也是伴着小曲写着文章,忙着追逐天空中的流星吧!

你可能感兴趣的:(Android -PreferenceFragment 对ListView自动添加和移除Preference数据对象)