欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > Android >内容正文

Android

Android Preference 须知

发布时间:2025/3/15 Android 50 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Android Preference 须知 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

Android Preference 须知

一、理论

 

1.前言

在Android的应用开发中经常会涉及到设置界面的设计开发,为此Android提供了名为Preference的设置处理机制,沿用这种机制的话能省去开发者很多不必要的时间开支。

那Preference究竟是什么呢?看一下你Android手机里的“设置”这个应用就知道了,大体界面如下:


这个设置界面就是通过Preference构建的,可能有些同学会说,这不就是一个普通的LinearLayout吗?有什么特别的?下面我们就开具体说说什么是Preference。

 

2.什么是Preference?

Preference翻译过来是“偏爱,爱好”的意思,在Android中Preference是一个具体的类,它代表着一个最基本的UI块(可以理解为ListView中的一个item),并且显示在Activity或Fragment内置的ListView上面,如图1-1中的“声音”选项,就是一个Preference的UI块表现(这里为什么要说表现呢?因为Preference本身并不是继承View的视图类,它只是代表着一个偏好选项然后通过提供UI块来展示这些偏好选项)。并且每一个UI块都会和一个SharePreferences关联来保存或恢复偏好设置。

 

3.Preference从何而来?

得到Preference的方法有两种:一种是从Xml文件中获取,在Xml文件中每一个节点都能指定特定的Preference的子类。另外一种方法就是在代码中动态的创建。为了处理好Preference与SharePreferences的关联,Preference类提供了一个Key来作为使用SharePreferences时的Key。


4.Preference的子类们



开关类型:

TwoStatePreference是一个抽象类,它下面的两个子类CheckBoxPreference和SwitchPreference。

 

弹出框类型:

弹出框类型的都继承子虚拟类DialogPreference,分别是EditPreference,MultiCheckPreference,ListPreference,MultiSelectListPreference,SeekBarDialogPreference,VolumePreferenc。

 

特殊:

RingtonePreference和SeekBarPreference分别是铃声选择和滑块。

 

组类型:

组类型都继承子抽象类PreferenceGroup,其中PreferenceCategory表示分类,PreferenceScreen主要用来表示一个设置界面中的根节点。


5.Preference其他相关类介绍:

GenericInflater:用于解析xml文件

 

PreferenceInflater:继承自GenericInflater用于解析包含Preference的xml

 

PreferenceActivity:在kk和之前的版本上用于显示一系列Preference的Header(标头,用于跳转到对应的PreferenceFragment),从L开始PreferenceActivity的功能被PreferenceFragment集成了。

 

PreferenceFragment:用ListView来显示一系列Preference的层次结构。

 

PreferenceManager:用于帮助从xml或代码中创建Preference的层次结构。


二、实践

 

1.从xml文件中构建Preference ,主要代码如下:

----PreferencesFromXml.java----

[java] view plaincopy
  • @Override  
  •    protected void onCreate(BundlesavedInstanceState) {  
  •        super.onCreate(savedInstanceState);  
  •   
  •        // Load the preferences from an XMLresource  
  •        //这个方法在L上已经不被提倡使用  
  •        addPreferencesFromResource(R.xml.preferences);  
  •    }  

  • preferences文件内容如下:

    [html] view plaincopy
  • <?xml version="1.0" encoding="utf-8"?>  
  • <!--BEGIN_INCLUDE(preferences) -->  
  • <PreferenceScreen  
  •        xmlns:android="http://schemas.android.com/apk/res/android">  
  •    
  •     <PreferenceCategory  
  •            android:title="@string/inline_preferences">  
  •              
  •         <CheckBoxPreference  
  •                 android:key="checkbox_preference"  
  •                 android:title="@string/title_checkbox_preference"  
  •                 android:summary="@string/summary_checkbox_preference" />  
  •    
  •     </PreferenceCategory>  
  •                  
  •     <PreferenceCategory  
  •            android:title="@string/dialog_based_preferences">  
  •    
  •         <EditTextPreference  
  •                 android:key="edittext_preference"  
  •                 android:title="@string/title_edittext_preference"  
  •                 android:summary="@string/summary_edittext_preference"  
  •                 android:dialogTitle="@string/dialog_title_edittext_preference" />  
  •                  
  •         <ListPreference  
  •                 android:key="list_preference"  
  •                 android:title="@string/title_list_preference"  
  •                 android:summary="@string/summary_list_preference"  
  •                 android:entries="@array/entries_list_preference"  
  •                 android:entryValues="@array/entryvalues_list_preference"  
  •                 android:dialogTitle="@string/dialog_title_list_preference" />  
  •    
  •     </PreferenceCategory>  
  •    
  •     <PreferenceCategory  
  •            android:title="@string/launch_preferences">  
  •    
  •         <!-- This PreferenceScreen tag servesas a screen break (similar to page break  
  •              in word processing). Like forother preference types, we assign a key  
  •              here so it is able to save andrestore its instance state. -->  
  •         <PreferenceScreen  
  •                 android:key="screen_preference"  
  •                 android:title="@string/title_screen_preference"  
  •                 android:summary="@string/summary_screen_preference">  
  •              
  •             <!-- You can place morepreferences here that will be shown on the next screen. -->  
  •                       
  •             <CheckBoxPreference  
  •                     android:key="next_screen_checkbox_preference"  
  •                     android:title="@string/title_next_screen_toggle_preference"  
  •                     android:summary="@string/summary_next_screen_toggle_preference" />  
  •                  
  •         </PreferenceScreen>  
  •    
  •         <PreferenceScreen  
  •                 android:title="@string/title_intent_preference"  
  •                 android:summary="@string/summary_intent_preference">  
  •    
  •             <intent android:action="android.intent.action.VIEW"  
  •                     android:data="http://www.android.com" />  
  •    
  •         </PreferenceScreen>  
  •    
  •     </PreferenceCategory>  
  •      
  •     <PreferenceCategory  
  •            android:title="@string/preference_attributes">  
  •      
  •         <CheckBoxPreference  
  •                 android:key="parent_checkbox_preference"  
  •                 android:title="@string/title_parent_preference"  
  •                 android:summary="@string/summary_parent_preference" />  
  •    
  •         <!-- The visual style of a childis defined by this styled theme attribute. -->  
  •         <CheckBoxPreference  
  •                 android:key="child_checkbox_preference"  
  •                 android:dependency="parent_checkbox_preference"  
  •                 android:layout="?android:attr/preferenceLayoutChild"  
  •                 android:title="@string/title_child_preference"  
  •                 android:summary="@string/summary_child_preference" />  
  •              
  •     </PreferenceCategory>  
  •      
  • </PreferenceScreen>  
  • <!-- END_INCLUDE(preferences)-->  

  •  

    就是这么简单,只需要简单配置一下xml文件,一个设置界面就完成了,上面的xml文件对应的界面如下:



    我们来分析一下这个xml文件

    首先看它的根节点 PreferenceScreen 它对应的就是PreferenceScreen对象表示这一层次结构的最外层。接着是PreferenceCategory它表示一个分类的开始对应PreferenceCategory对象。在PreferenceCategory里可以看到一些节点如:CheckBoxPreference,EditTextPreference,ListPreference等,都是表示一个设置选项,其对应的也是名字与之相同的类。

     

    2.从代码中构建Preference

    代码如下:

    ----PreferencesFromCode.java----

     

    [java] view plaincopy
  • public classPreferencesFromCode extends PreferenceActivity {  
  •    
  •     private static final StringPARENT_CHECKBOX_PREFERENCE = "parent_checkbox_preference";  
  •    
  •     @Override  
  •     protected void onCreate(BundlesavedInstanceState) {  
  •         super.onCreate(savedInstanceState);  
  •    
  •         PreferenceScreen root =getPreferenceManager().createPreferenceScreen(this);  
  •         setPreferenceScreen(root);  
  •         populatePreferenceHierarchy(root);  
  •     }  
  •    
  •     private voidpopulatePreferenceHierarchy(PreferenceScreen root) {  
  •         // Inline preferences  
  •         PreferenceCategory inlinePrefCat = newPreferenceCategory(this);  
  •        inlinePrefCat.setTitle(R.string.inline_preferences);  
  •         root.addPreference(inlinePrefCat);  
  •    
  •         // Checkbox preference  
  •         CheckBoxPreference checkboxPref = newCheckBoxPreference(this);  
  •         checkboxPref.setKey("checkbox_preference");  
  •        checkboxPref.setTitle(R.string.title_checkbox_preference);  
  •        checkboxPref.setSummary(R.string.summary_checkbox_preference);  
  •        inlinePrefCat.addPreference(checkboxPref);  
  •    
  •         // Switch preference  
  •         SwitchPreference switchPref = newSwitchPreference(this);  
  •        switchPref.setKey("switch_preference");  
  •        switchPref.setTitle(R.string.title_switch_preference);  
  •        switchPref.setSummary(R.string.summary_switch_preference);  
  •         inlinePrefCat.addPreference(switchPref);  
  •    
  •         // Dialog based preferences  
  •         PreferenceCategory dialogBasedPrefCat =new PreferenceCategory(this);  
  •        dialogBasedPrefCat.setTitle(R.string.dialog_based_preferences);  
  •         root.addPreference(dialogBasedPrefCat);  
  •    
  •         // Edit text preference  
  •         EditTextPreference editTextPref = newEditTextPreference(this);  
  •        editTextPref.setDialogTitle(R.string.dialog_title_edittext_preference);  
  •        editTextPref.setKey("edittext_preference");  
  •         editTextPref.setTitle(R.string.title_edittext_preference);  
  •        editTextPref.setSummary(R.string.summary_edittext_preference);  
  •        dialogBasedPrefCat.addPreference(editTextPref);  
  •    
  •         // List preference  
  •         ListPreference listPref = newListPreference(this);  
  •        listPref.setEntries(R.array.entries_list_preference);  
  •        listPref.setEntryValues(R.array.entryvalues_list_preference);  
  •        listPref.setDialogTitle(R.string.dialog_title_list_preference);  
  •         listPref.setKey("list_preference");  
  •        listPref.setTitle(R.string.title_list_preference);  
  •        listPref.setSummary(R.string.summary_list_preference);  
  •        dialogBasedPrefCat.addPreference(listPref);  
  •    
  •         // Launch preferences  
  •         PreferenceCategory launchPrefCat = newPreferenceCategory(this);  
  •        launchPrefCat.setTitle(R.string.launch_preferences);  
  •         root.addPreference(launchPrefCat);  
  •    
  •         /* 
  •          * The Preferences screenPref serves asa screen break (similar to page 
  •          * break in word processing). Like forother preference types, we assign 
  •          * a key here so that it is able tosave and restore its instance state. 
  •          */  
  •         // Screen preference  
  •         PreferenceScreen screenPref =getPreferenceManager().createPreferenceScreen(this);  
  •        screenPref.setKey("screen_preference");  
  •        screenPref.setTitle(R.string.title_screen_preference);  
  •        screenPref.setSummary(R.string.summary_screen_preference);  
  •        launchPrefCat.addPreference(screenPref);  
  •    
  •         /* 
  •          * You can add more preferences toscreenPref that will be shown on the 
  •          * next screen. 
  •          */  
  •    
  •         // Example of next screen togglepreference  
  •         CheckBoxPreferencenextScreenCheckBoxPref = new CheckBoxPreference(this);  
  •        nextScreenCheckBoxPref.setKey("next_screen_toggle_preference");  
  •        nextScreenCheckBoxPref.setTitle(R.string.title_next_screen_toggle_preference);  
  •        nextScreenCheckBoxPref.setSummary(R.string.summary_next_screen_toggle_preference);  
  •         screenPref.addPreference(nextScreenCheckBoxPref);  
  •    
  •         // Intent preference  
  •         PreferenceScreen intentPref =getPreferenceManager().createPreferenceScreen(this);  
  •         intentPref.setIntent(newIntent().setAction(Intent.ACTION_VIEW)  
  •                .setData(Uri.parse("http://www.android.com")));  
  •        intentPref.setTitle(R.string.title_intent_preference);  
  •        intentPref.setSummary(R.string.summary_intent_preference);  
  •        launchPrefCat.addPreference(intentPref);  
  •    
  •         // Preference attributes  
  •         PreferenceCategory prefAttrsCat = newPreferenceCategory(this);  
  •        prefAttrsCat.setTitle(R.string.preference_attributes);  
  •         root.addPreference(prefAttrsCat);  
  •    
  •         // Visual parent toggle preference  
  •         CheckBoxPreference parentCheckBoxPref =new CheckBoxPreference(this);  
  •        parentCheckBoxPref.setTitle(R.string.title_parent_preference);  
  •        parentCheckBoxPref.setSummary(R.string.summary_parent_preference);  
  •         prefAttrsCat.addPreference(parentCheckBoxPref);  
  •        parentCheckBoxPref.setKey(PARENT_CHECKBOX_PREFERENCE);  
  •    
  •         // Visual child toggle preference  
  •         // See res/values/attrs.xml for the<declare-styleable> that defines  
  •         // TogglePrefAttrs.  
  •         TypedArray a = obtainStyledAttributes(R.styleable.TogglePrefAttrs);  
  •         CheckBoxPreference childCheckBoxPref =new CheckBoxPreference(this);  
  •        childCheckBoxPref.setTitle(R.string.title_child_preference);  
  •        childCheckBoxPref.setSummary(R.string.summary_child_preference);  
  •         childCheckBoxPref.setLayoutResource(  
  •                a.getResourceId(R.styleable.TogglePrefAttrs_android_preferenceLayoutChild,  
  •                         0));  
  •        prefAttrsCat.addPreference(childCheckBoxPref);  
  •         childCheckBoxPref.setDependency(PARENT_CHECKBOX_PREFERENCE);  
  •         a.recycle();  
  •     }  
  • }  
  •  

    动态构建Preference的过程是:构建PreferenceScreen,然后构建PreferenceCategory,并往PreferenceCategory中添加需要使用的Preference的子类,然后将PreferenceCategory添加到PreferenceScreen。

    上述代码效果图如下:



    三、Preference实现机制

     

    在讲机制之前我们来做一个简单的demo,通过这个demo来直击Preference的运行现场。

     

    demo很简单,有两个界面:

    MyPreferenceDemo.java (一个activity,显示从SharePreferences取key为my_demo_key的值)

    MySetting.java (一个key为my_demo_key的EditPreference)

    关键代码如下:

    ----MyPreferenceDemo.java

    [java] view plaincopy
  • public class MyPreferenceDemo extends Activity {  
  •    
  •     private TextView mTextView ;  
  •     @Override  
  •     protected void onCreate(BundlesavedInstanceState) {  
  •         super.onCreate(savedInstanceState);  
  •         setContentView(R.layout.activity_main);  
  •         mTextView = (TextView)findViewById(R.id.show_preferecne) ;  
  •     }  
  •    
  •     @Override  
  •     protected void onResume() {  
  •         super.onResume();  
  •         mTextView.setText(getPreferenceByKey());  
  •     }  
  •    
  •     private String getPreferenceByKey() {  
  •          
  •         String pref = "" ;  
  •         pref =PreferenceManager.getDefaultSharedPreferences(this).getString("my_demo_key","Hello") ;  
  •         return pref;  
  •     }  
  •    
  •     @Override  
  •     public boolean onCreateOptionsMenu(Menu menu){  
  •         // Inflate the menu; this adds itemsto the action bar if it is present.  
  •         getMenuInflater().inflate(R.menu.main, menu);  
  •         return true;  
  •     }  
  •    
  •     @Override  
  •     public boolean onOptionsItemSelected(MenuItemitem) {  
  •         if(item.getItemId() == R.id.action_settings){  
  •             Toast.makeText(this"settings", Toast.LENGTH_LONG).show() ;  
  •             Intent intent = new Intent() ;  
  •             intent.setClass(this, MySetting.class) ;  
  •             startActivity(intent) ;  
  •         }  
  •         return super.onOptionsItemSelected(item);  
  •     }  
  • }  


  •  

    ----MySetting.java

    [java] view plaincopy
  • public class MySetting extends PreferenceActivity {  
  •    
  •     @Override  
  •     protected void onCreate(BundlesavedInstanceState) {  
  •         super.onCreate(savedInstanceState);  
  •          
  •         PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);  
  •         setPreferenceScreen(root);  
  •         populatePreferenceHierarchy(root);  
  •     }  
  •      
  •     private void populatePreferenceHierarchy(PreferenceScreenroot) {  
  •         PreferenceCategory myCat = new PreferenceCategory(this);  
  •         myCat.setTitle("My PreferenceDemo");  
  •         root.addPreference(myCat);  
  •    
  •         EditTextPreference editTextPref = new EditTextPreference(this);  
  •         editTextPref.setDialogTitle("please inputsomething");  
  •         editTextPref.setKey("my_demo_key");  
  •         editTextPref.setTitle("settings");  
  •         editTextPref.setSummary("设置activity中需要显示的字符串");  
  •         myCat.addPreference(editTextPref);  
  •    
  •     }  
  • }  


  •  

    程序界面如下:


    点击“settings”输入“这是preference的demo”,然后返回第一个界面,就会显示 “这是preference的demo”。

     

    我们先来看看获得SharePreferences的这个方法:

     

    [java] view plaincopy
  • PreferenceManager.getDefaultSharedPreferences(this)  

  • 跟进源代码发现getDefaultSharedPreferences的实现如下:

    [java] view plaincopy
  • public static SharedPreferencesgetDefaultSharedPreferences(Context context)      {  
  •     returncontext.getSharedPreferences(getDefaultSharedPreferencesName(context),  
  •            getDefaultSharedPreferencesMode());  
  • }  
  •   
  • private static StringgetDefaultSharedPreferencesName(Context context) {  
  •     return context.getPackageName() + "_preferences";  
  • }  
  •   
  • private static intgetDefaultSharedPreferencesMode() {  
  •     return Context.MODE_PRIVATE;  
  • }  

  • 内部其实还是调用了 getSharedPreferences这个方法来获得SharePreferences,参数name和mode分别是:context.getPackageName() +"_preferences"和 Context.MODE_PRIVATE

     

    接着我们看看我们使用的 EditTextPreference是怎么将字符串保存到SharePreferences的,

     

    我们看到在EditTextPreference内部有这么一个回调方法:

     

      

    [java] view plaincopy
  • @Override  
  •    protected void onDialogClosed(boolean positiveResult) {  
  •        super.onDialogClosed(positiveResult);  
  •         
  •        if (positiveResult) {  
  •            String value = mEditText.getText().toString();  
  •            if (callChangeListener(value)) {  
  •                setText(value);  
  •            }  
  •        }  
  •    }  

  •  

    当设置好字符串关闭对话框时这个方法会被回调,获得输入的字符串value然后调用settext(value),

     

       

    [java] view plaincopy
  • public void setText(String text) {  
  •        final boolean wasBlocking =shouldDisableDependents();  
  •         
  •        mText = text;  
  •         
  •        persistString(text);  
  •         
  •        final boolean isBlocking =shouldDisableDependents();  
  •        if (isBlocking != wasBlocking) {  
  •            notifyDependencyChange(isBlocking);  
  •        }  
  •    }  

  •  

    我们接着看persistString(text);  这个方法,首先persist的意思是持久化,那我们可以很容易联想到本地文件或者数据库之类的,那这边到底会把text保存到哪里?我们接着看。

     

     

    [java] view plaincopy
  • protected boolean persistString(String value) {  
  •      if (shouldPersist()) {  
  •          // Shouldn't store null  
  •          if (value == getPersistedString(null)) {  
  •              // It's already there, so the sameas persisting  
  •              return true;  
  •          }  
  •           
  •          SharedPreferences.Editor editor = mPreferenceManager.getEditor();  
  •          editor.putString(mKey, value);  
  •          tryCommit(editor);  
  •          return true;  
  •      }  
  •      return false;  
  •  }  

  •  

    看到这里就就明了了,最终还是将value这个数据保存在了SharePreferences里面。

     

    最基本的Preference实现机制就到这里了,总结一句话:

    Preference设置属性的保存还是依赖于SharePreferences

    关于SharePreferences的运行机制,我会在后面在给出。


    pdf下载 http://pan.baidu.com/s/1o6p2dYi


    原文地址:http://blog.csdn.net/will_captain/article/details/40404523

    总结

    以上是生活随笔为你收集整理的Android Preference 须知的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。