2014-01-05 71 views
2
我使用 PreferenceFragment其XML文件

的背景色如下更改PreferenceFragment

public class ReaderPreferences extends PreferenceFragment { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    addPreferencesFromResource(R.xml.preference); 
} 
} 

preference.xml:

<PreferenceCategory 
    android:key="general" 
    android:title="General" > 

    <CheckBoxPreference 
     android:defaultValue="true" 
     android:key="notify_me" 
     android:summary="Notify me about quote of the day in notifications" 
     android:title="Get notification" /> 

    <Preference 
     android:defaultValue="" 
     android:key="time" 
     android:summary="Change time to receive quote of the day" 
     android:title="Time of Quote of the day" /> 

</PreferenceCategory> 

<PreferenceCategory 
    android:key="socials" 
    android:title="Socials and sharing" > 

    <Preference 
     android:defaultValue="" 
     android:key="facebook_login" 
     android:summary="Sign in with your facebook account" 
     android:title="Facebook login" /> 

    <Preference 
     android:defaultValue="" 
     android:key="facebook_logout" 
     android:summary="Sign out facebook " 
     android:title="Facebook logout" /> 

    <CheckBoxPreference 
     android:defaultValue="" 
     android:key="facebook_qotd" 
     android:summary="Share the quote of the day on facebook once it is updated" 
     android:title="Share QOTD on facebook" /> 

    <Preference 
     android:defaultValue="" 
     android:key="twitter_login" 
     android:summary="Sign in with your twitter account" 
     android:title="Twitter login" /> 

    <Preference 
     android:defaultValue="" 
     android:key="twitter_logout" 
     android:summary="Sign out twitter" 
     android:title="Twitter logout" /> 

    <CheckBoxPreference 
     android:defaultValue="" 
     android:key="twitter_qotd" 
     android:summary="Share the quote of the day on twitter once it is updated" 
     android:title="Share QOTD on twitter" /> 
</PreferenceCategory> 

<PreferenceCategory 
    android:key="other" 
    android:title="Other" > 

    <Preference 
     android:defaultValue="" 
     android:key="about" 
     android:title="About" /> 
</PreferenceCategory> 

我怎樣才能改變這個偏好的背景顏色? 如何從.ttf文件設置字體?

希望任何人都可以幫助我。 在此先感謝。

回答

4

這是一種方法:您可以使用自定義佈局和ListView創建自己的PrefrenceFragment。基本上它是一個簡單的Fragment,它返回包含ListView的View。通過調用PreferenceScreen bind()方法可以PreferenceScreen內容膨脹到自己的ListView

公共無效綁定(ListView控件ListView控件)

在API級別1綁定一個ListView中包含的喜好 這個PreferenceScreen通過getRootAdapter()。它還處理將 列表項目單擊到此 PreferenceScreen包含的相應首選項。參數listView要附加到的列表視圖。

public class CustomPreferenceFragment extends Fragment { 
    CustomPreferenceFragment.java 

    private PreferenceManager mPreferenceManager; 

     /** 
     * The starting request code given out to preference framework. 
     */ 
     private static final int FIRST_REQUEST_CODE = 100; 

     private static final int MSG_BIND_PREFERENCES = 0; 
     private Handler mHandler = new Handler() { 
      @Override 
      public void handleMessage(Message msg) { 
       switch (msg.what) { 

        case MSG_BIND_PREFERENCES: 
         bindPreferences(); 
         break; 
       } 
      } 
     }; 
     private ListView lv; 
     private int xmlId; 


     //must be provided 
     public CustomPreferenceFragment(){ 

     } 



     @Override 
     public void onDestroyView(){ 
      super.onDestroyView(); 
      ViewParent p = lv.getParent(); 
      if(p != null) 
       ((ViewGroup)p).removeView(lv); 
     } 


     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup root, Bundle savedInstanceState){ 
      Bundle bundle = getArguments(); 
      if(bundle != null){ 
       xmlId = bundle.getInt("xml"); 
      } 
      View mView = inflater.inflate(R.layout.preference_list_content, null); 
      mPreferenceManager = onCreatePreferenceManager(); 
      lv = (ListView)mView.findViewById(R.id.listView1); 
      lv.setBackgroundColor(Color.WHITE); 
      lv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); 

      addPreferencesFromResource(xmlId); 
      setHasOptionsMenu(true); 
      postBindPreferences(); 
      return mView; 
     } 

     @Override 
     public void onStop(){ 
      super.onStop(); 
      try{ 
       Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop"); 
       m.setAccessible(true); 
       m.invoke(mPreferenceManager); 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void onDestroy() { 
      super.onDestroy(); 
      lv = null; 
      try{ 
       Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy"); 
       m.setAccessible(true); 
       m.invoke(mPreferenceManager); 
       }catch(Exception e){ 
        e.printStackTrace(); 
       } 
     } 

     @Override 
     public void onSaveInstanceState(Bundle outState) { 
      outState.putInt("xml", xmlId); 
      super.onSaveInstanceState(outState); 

     } 

     @Override 
     public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) { 
      inflater.inflate(R.menu.main, menu); 
      super.onCreateOptionsMenu(menu, inflater); 
     } 

     @Override 
     public void onActivityResult(int requestCode, int resultCode, Intent data) { 
      super.onActivityResult(requestCode, resultCode, data); 
      try{ 
       Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class); 
       m.setAccessible(true); 
       m.invoke(mPreferenceManager, requestCode, resultCode, data); 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 

     /** 
     * 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(); 
     } 

     private void bindPreferences() { 
      final PreferenceScreen preferenceScreen = getPreferenceScreen(); 
      if (preferenceScreen != null) { 
       preferenceScreen.bind(lv); 
      } 
     } 

     /** 
     * Creates the {@link PreferenceManager}. 
     * 
     * @return The {@link PreferenceManager} used by this activity. 
     */ 
     private PreferenceManager onCreatePreferenceManager() { 
      try{ 
       Constructor<PreferenceManager> c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class); 
       c.setAccessible(true); 
       PreferenceManager preferenceManager = c.newInstance(this.getActivity(), FIRST_REQUEST_CODE); 
       return preferenceManager; 
      }catch(Exception e){ 
       e.printStackTrace(); 
       return null; 
      } 
     } 

     /** 
     * Returns the {@link PreferenceManager} used by this activity. 
     * @return The {@link PreferenceManager}. 
     */ 
     public PreferenceManager getPreferenceManager() { 
      return mPreferenceManager; 
     } 

     /** 
     * Sets the root of the preference hierarchy that this activity is showing. 
     * 
     * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. 
     */ 
     public void setPreferenceScreen(PreferenceScreen preferenceScreen){ 
      try{ 
       Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class); 
       m.setAccessible(true); 
       boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen); 
       if (result && preferenceScreen != null) { 
        postBindPreferences(); 
       } 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 

     /** 
     * Gets the root of the preference hierarchy that this activity is showing. 
     * 
     * @return The {@link PreferenceScreen} that is the root of the preference 
     *   hierarchy. 
     */ 
     public PreferenceScreen getPreferenceScreen(){ 
      try{ 
       Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen"); 
       m.setAccessible(true); 
       return (PreferenceScreen) m.invoke(mPreferenceManager); 
      }catch(Exception e){ 
       e.printStackTrace(); 
       return null; 
      } 
     } 



     /** 
     * Inflates the given XML resource and adds the preference hierarchy to the current 
     * preference hierarchy. 
     * 
     * @param preferencesResId The XML resource ID to inflate. 
     */ 
     public void addPreferencesFromResource(int preferencesResId) { 
      try{ 
       Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class); 
       m.setAccessible(true); 
       PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(mPreferenceManager, getActivity(), preferencesResId, getPreferenceScreen()); 
       setPreferenceScreen(prefScreen); 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 

     /** 
     * Finds a {@link Preference} based on its key. 
     * 
     * @param key The key of the preference to retrieve. 
     * @return The {@link Preference} with the key, or null. 
     * @see PreferenceGroup#findPreference(CharSequence) 
     */ 
     public Preference findPreference(CharSequence key) { 
      if (mPreferenceManager == null) { 
       return null; 
      } 
      return mPreferenceManager.findPreference(key); 
     } 




    } 

preference_list_content.xml //您的自定義的ListView /佈局

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <ListView 
     android:id="@+id/listView1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" > 

    </ListView> 

</RelativeLayout> 

示例如何使用:

MainActivity.java

public class MainActivity extends Activity implements OnSharedPreferenceChangeListener{ 
    private SharedPreferences sharedPref; 
    private CustomPreferenceFragment frag; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     frag = new CustomPreferenceFragment(); 
     Bundle bundle = new Bundle(); 
     bundle.putInt("xml", R.xml.prefs); //Your preference xml that you want to inflate 
     frag.setArguments(bundle); 
     getFragmentManager().beginTransaction().add(R.id.frameLayout, frag).commit(); 

     sharedPref = PreferenceManager.getDefaultSharedPreferences(this); 


    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 



    @Override 
    public void onResume(){ 
     super.onResume(); 
     sharedPref.registerOnSharedPreferenceChangeListener(this); 
    } 

    @Override 
    public void onPause(){ 
     super.onPause(); 
     sharedPref.unregisterOnSharedPreferenceChangeListener(this); 
    } 

    @Override 
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 
      String key) { 
     Toast.makeText(this, "Preferences changed, key: " + key, Toast.LENGTH_SHORT).show(); 

    } 

} 

的prefs.xml進入下res/xml /文件夾:

<?xml version="1.0" encoding="utf-8"?> 
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="android custom prefs test"> 
     <Preference android:title="Preference Fragment " android:summary="With custom background" android:key="key_1"/> 
     <CheckBoxPreference android:title="CheckBoxPref" android:summary="Preference with checkbox" android:key="key_2"/> 
     <SwitchPreference android:title="SwitchPreference" android:summary="Prefrence with switch" android:key="key_3"/> 
    </PreferenceScreen> 

如何更改此首選項的背景顏色?

在CustomPreferenceFragment.java:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup root, Bundle savedInstanceState){ 
    lv.setBackgroundColor(Color.WHITE); 
} 

結果: enter image description here

+0

其實我喜歡這種方法。我只是謹慎添加,而我決定不走這條路線的原因是它可能會在未來的更新中破壞:(無論如何,無論哪種方式,這可能是最好的解決方案,對於與定製首選項片段相關的任何事情都不是胡扯。 – Andy

相關問題