Android更改 PreferenceFragment 的背景颜色

我使用的 PreferenceFragment 与如下所示的 xml 文件

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 文件吗?

希望有人可以帮助我。先谢谢了。

解决方法 1:

这是一种方法: 你可以用自定义布局和 ListView 创建您自己的 PrefrenceFragment。基本上这是一个简单的片段,返回包含列表视图的视图。通过调用 PreferenceScreen bind() 方法你可以到你自己 ListView 夸大 PreferenceScreen 内容

公共 void 绑定 (ListView listView)

在 API 级别 1 绑定 ListView 添加到此 PreferenceScreen 通过 getRootAdapter() 中所载的首选项。它还处理传递列表项目单击到此 PreferenceScreen 所载的相应首选项。参数 listView 要附加到的列表视图。

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 //Your 自定义列表视图/布局

<?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

posted @ 2015-08-18 15:20  xiexie2015  阅读(1127)  评论(0编辑  收藏  举报