更改PreferenceFragment的背景颜色

时间:2014-01-05 13:44:01

标签: android android-fragments android-preferences

我正在使用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 个答案:

答案 0 :(得分:4)

这是一种方法:您可以使用自定义布局和ListView创建自己的PrefrenceFragment。基本上它是一个简单的Fragment,返回包含ListView的View。通过调用PreferenceScreen bind()方法,您可以将PreferenceScreen内容扩展到您自己的ListView

  
    

public void bind(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 / Layout

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