美文网首页Android车机版知识
Android -PreferenceFragment 对Li

Android -PreferenceFragment 对Li

作者: ZebraWei | 来源:发表于2017-03-14 12:17 被阅读329次

    哼着小曲 听着田馥甄的《小幸运》。--遇见你是注定,也许当时忙着微笑和哭泣,离别之后只会流泪和哭泣。当我没听见你声音,我又重新做回我自己,她会有多幸运。哎....抒发下半年以来的压抑和哭泣。让我看着你们手中的亮光好吧!---在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<Preference> list =getPrefeerences();
        Iterator<Preference> 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<Preference> mList = new ArrayList<Preference>();
    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<Preference> 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<Preference> 集合中。
    4.其中fragment_preference布局如下就是一个ListView 哈哈:
    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <ListView
    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"
    >
    </ListView>
    </RelativeLayout>
    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 的布局:

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:paddingRight="15dp"
             >
    
            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:textColor="@android:color/white"
                android:textSize="@dimen/title_text_size" />
    
            <TextView
                android:id="@+id/summary"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/title"
                android:gravity="center_vertical"
                android:textColor="@color/setting_line_color"
                android:textSize="16sp"
                android:visibility="gone" />
            
        </RelativeLayout>
       <com.ssdf.sdk.widgets.CheckSwitchButton
                android:id="@+id/switch_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_alignParentRight="true"
                />
    


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

    相关文章

      网友评论

        本文标题:Android -PreferenceFragment 对Li

        本文链接:https://www.haomeiwen.com/subject/sjxngttx.html