Borys
Borys

Reputation: 1823

android custom Switch widget for SwitchPreferenc

I search around stackoverflow and find next related topics:

  1. How can i style an Android Switch?
  2. Custom switch widget in Android 4
  3. Set switchStyle - get error resource not found - why?

I also find bugreport on google group: Issue 36636: Unable to override style switchStyle And at last find new probles with Switch widget:

but I get an compliation error: Error: Resource is not public. (at 'id' with value '@+android:id/switchWidget'). So I can't use this way.

So, How can I get custom Switch Preference for SDK API 15 ??? Or how can I customize Switch in Preferences?

Upvotes: 3

Views: 10564

Answers (5)

user3999206
user3999206

Reputation: 1

Change:

android:id="@+android:id/switchWidget"

To:

android:id="@*android:id/switchWidget"

Upvotes: -3

Romain Pellerin
Romain Pellerin

Reputation: 2480

Just found an awful way to achieve this.

First, src/com/myapp/views/preference/MySwitchPreference.java

public class MySwitchPreference extends SwitchPreference {
    public MySwitchPreference(Context context) {
        super(context);
    }

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

    public MySwitchPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onBindView(View view) {
        super.onBindView(view);

        if (view instanceof ViewGroup) {
            setLayout((ViewGroup) view);
        }
    }

    @SuppressLint("NewApi")
    private void setLayout(ViewGroup viewGroup) {
        int count = viewGroup.getChildCount();
        for(int n = 0; n < count; ++n) {
            View childView = viewGroup.getChildAt(n);
            if(childView instanceof Switch) {
                final Switch switchView = (Switch) childView;

                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
                    switchView.setThumbResource(com.myapp.R.drawable.switch_inner);
                    switchView.setTrackResource(com.myapp.R.drawable.switch_track);
                }
                return;
            }
            else if (childView instanceof ViewGroup)
                setLayout((ViewGroup) childView);
        }
    }
}

And now, res/xml/preferences.xml

<com.myapp.views.preference.MySwitchPreference
            android:switchTextOff="Off"
            android:switchTextOn="On"
            android:title="whatever"
            android:key="switch" />

A little bit tricky, and only working with Android > 16.

Upvotes: 3

sgadde
sgadde

Reputation: 51

Inherit SwitchPreference class and use it in preferences.xml with layout pointing to your custom layout. Then in the onBind method of inherited SwitchPreference class you can find corresponding view by id and set listeners. Don't forget to call super in onBind().

Upvotes: 0

Andrei
Andrei

Reputation: 2607

Don't know much about the switch issues but you could use a ToggleButton as follows:

Define the button in your layout:

<ToggleButton
            android:id="@+id/your_awesome_toggle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:gravity="center_vertical|center_horizontal"
            android:layout_marginRight="15dp"
            android:textOn=""
            android:textOff=""
            android:background="@drawable/toggle_button"
        />

Create a selector:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item 
        android:state_checked="false" 
        android:state_focused="false"
        android:drawable="@drawable/switch_off_btn" />
    <item 
        android:state_checked="true" 
        android:state_focused="false" 
        android:drawable="@drawable/switch_on_btn" />
    <item 
        android:drawable="@drawable/switch_off_btn" />
</selector>

OnClickListener:

    toggleOnOff = (ToggleButton) findViewById(R.id.your_awesome_toggle);

    toggleOnOff.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            updateButtons();
            if(toggleOnOff.isChecked()){
                 SharedPreferences emailPrefs = getSharedPreferences(rememberToggleOnOff,MODE_PRIVATE);
                 SharedPreferences.Editor editor = yourPrefs.edit();
                 editor.putBoolean("mon", true);
                 editor.commit();
            }
            else {
                SharedPreferences emailPrefs = getSharedPreferences(rememberToggleOnOff,MODE_PRIVATE);
                SharedPreferences.Editor editor = yourPrefs.edit();
                editor.putBoolean("mon", false);
                editor.commit();
            }
        }
    });
    checkToggleState();

checkToggleState method:

/**
     * Checks the state of the Toggle button preferences.  
     * If preferences are true set the toggle to on, if false set the toggle off.  
     * 
     */
    private void checkToggleState() {
        SharedPreferences yourPrefs = getSharedPreferences(rememberToggleOnOff,MODE_PRIVATE);
        boolean mON = yourPrefs.getBoolean("mon", true);
        if(mON) {
            toggleOnOff.setChecked(true);
        }
        else {
            toggleOnOff.setChecked(false);
        }
    }

Upvotes: 1

Alejandro Colorado
Alejandro Colorado

Reputation: 6094

Change:

android:id="@+android:id/switchWidget"

To:

android:id="@+id/switchWidget"

A simple switch example can be found here.

Switch widget supports 14 and above API level only, but if you want to use Switch Preference pre API level 14, check this.

UPDATE: If you want to style your own switch, try this

Upvotes: 0

Related Questions