2014-01-20 125 views
9

如何在Android中爲SwitchPreference小部件設置可繪製的自定義樣式或其他背景選擇器?Android中的自定義SwitchPreference

(注意:不是正規Switch小部件,我的意思是,在PreferenceActivity/PreferenceFragment使用的非標準部件SwitchPreference

+0

此解決方案適用於我。但只適用於API21 +: http://stackoverflow.com/a/30678605/1816277 – Blankarsch

回答

15

你必須創建交換機本身的自定義佈局,就可以用它動態地喜歡。

preference.setWidgetLayoutResource(R.layout.custom_switch); 

但我會詳細介紹並告訴你如何實現這一點。

所以,您可以定義自己的喜好在XML文件中像的preferences.xml

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > 
    <PreferenceCategory android:title="YOUR_CATEGORY_TITLE" > 
     <SwitchPreference 
      android:key="SWITCH" 
      android:title="YOUR_TITLE_FOR_SWITCH" /> 
    </PreferenceCategory> 
</PreferenceScreen> 

然後在OnCreate閱讀()方法你PreferenceActivty類中:

SwitchPreference pref = (SwitchPreference) findPreference(getString(R.string.SWITCH)); 
    //pref.setChecked(true); // You can check it already if needed to true or false or a value you have stored persistently 
    pref.setWidgetLayoutResource(R.layout.custom_switch); // THIS IS THE KEY OF ALL THIS. HERE YOU SET A CUSTOM LAYOUT FOR THE WIDGET 
    pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { 

     @Override 
     public boolean onPreferenceChange(Preference preference, Object newValue) { 
      // Here you can enable/disable whatever you need to 
      return true; 
     } 
    }); 

custom_switch佈局看起來像這樣:

<?xml version="1.0" encoding="utf-8"?> 
<Switch xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/custom_switch_item" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center_vertical" 
    android:textColor="@android:color/white" 
    android:textIsSelectable="false" 
    android:textSize="18sp" 
    android:textStyle="bold" 
    android:track="@drawable/switch_track" 
    android:thumb="@drawable/switch_thumb"/> 

而對於開關你有2個選擇爲軌道拇指性能。 這些選擇器的drawable可以使用Android Holo Color Generator生成,tasomaniac建議使用Android Holo Color Generator。在這種情況下,您只需複製生成的可繪製文件夾的內容(僅適用於drawable-hdpi,drawable-mdpi,drawable-xhdpi,drawable-xxhdpi)。但是您可以爲您需要的每個狀態創建自定義視圖。

下面是這些選擇將如何看起來像: switch_track:

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

    <item android:drawable="@drawable/switch_bg_focused" android:state_focused="true"/> 
    <item android:drawable="@drawable/switch_bg"/> 

</selector> 

switch_thumb:

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

    <item android:drawable="@drawable/switch_thumb_disabled" android:state_enabled="false"/> 
    <item android:drawable="@drawable/switch_thumb_pressed" android:state_pressed="true"/> 
    <item android:drawable="@drawable/switch_thumb_activated" android:state_checked="true"/> 
    <item android:drawable="@drawable/switch_thumb"/> 

</selector> 

而這幾乎是它。這個解決方案幫了我。如果我省略了某些內容,請讓我知道,我會糾正這些問題。

+2

我遇到的問題是該小部件似乎不代表sharedpreference值的狀態,即它永遠不會被檢查根據sp和setCheck,/ unchecked似乎也沒有改變UI。我認爲這是我使用的Android版本的一個問題(4.4.2) – siyb

+0

我無法處理任何切換首選項的事件 – vuhung3990

+0

@siyb - 共享偏好不能通過setChecked等改變:) - 如果你想手動改變sp部件你需要通過首選項管理器設置首選項,然後重新繪製標題或重新加載視圖{通過invalidate或getPreferenceScreen()。removeAll(); addPreferencesFromResource(@IdRes int); } – ceph3us

1

這樣做的一種方法是繼承SwitchPreference並覆蓋onBindView方法。在這樣做的時候,你會想要仍然叫超級。onBindView(view)方法,但隨後在子視圖中找到Switch並將其設置爲適當的樣式:

package com.example; 

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.preference.SwitchPreference; 
import android.util.AttributeSet; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Switch; 

import com.example.R; 


public class CustomSwitchPreference extends SwitchPreference { 

    @SuppressLint("NewApi") 
    public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    public CustomSwitchPreference(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public CustomSwitchPreference(Context context) { 
     super(context); 
    } 

    @Override 
    protected void onBindView(View view) { 

     super.onBindView(view); 
     Switch theSwitch = findSwitchInChildviews((ViewGroup) view); 
     if (theSwitch!=null) { 
      //do styling here 
      theSwitch.setThumbResource(R.drawable.new_thumb_resource); 
     } 

    } 

    private Switch findSwitchInChildviews(ViewGroup view) { 
     for (int i=0;i<view.getChildCount();i++) { 
      View thisChildview = view.getChildAt(i); 
      if (thisChildview instanceof Switch) { 
       return (Switch)thisChildview; 
      } 
      else if (thisChildview instanceof ViewGroup) { 
       Switch theSwitch = findSwitchInChildviews((ViewGroup) thisChildview); 
       if (theSwitch!=null) return theSwitch; 
      } 
     } 
     return null; 
    } 
}