8

Is the SwitchPreference introduced in ICS compatible in the android-support-v4 library? I'm trying to update some old projects and would like to use SwitchPreferences if possible.

I know I can make a separate resource file to distinguish the API version, but I'd like to avoid that if at all possible.

SD_Guru
  • 339
  • 3
  • 10
  • The short answer is no, currently the `SwitchPreference` is not available in the support library. However, it shouldn't be too tricky to backport it, if someone hasn't already. – MH. May 21 '12 at 21:41

4 Answers4

8

Is the SwitchPreference introduced in ICS compatible in the android-support-v4 library?

No, sorry.

However, it shouldn't be too tricky to backport it, if someone hasn't already.

Actually, it may be a bit of a pain, since it also requires a backport of Switch, and backporting widgets is sometimes troublesome because they frequently use package-private methods that backports cannot access.

I know I can make a separate resource file to distinguish the API version, but I'd like to avoid that if at all possible.

Well, that would certainly be way simpler than the alternatives:

  • the aforementioned backport

  • creating some sort of alias Preference mechanism that allows you to use SwitchPreference on newer devices and CheckBoxPreference on older devices with only one resource file

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
5

android-switch-backport has a SwitchPreference which works on Android 2.1+.

https://github.com/BoD/android-switch-backport

Intrications
  • 16,782
  • 9
  • 50
  • 50
  • The only thing I dislike about these, are that they cant be bundled and included in app as jar etc. Instead, you have to put many (81) res files into your app, which drowns out your own resources. Its a shame the android-support lib doesnt include it. – IAmGroot Jan 03 '13 at 09:13
  • The instructions and support are much better with this one - https://github.com/ankri/SwitchCompatLibrary – Abandoned Cart Jan 18 '13 at 15:56
  • @TwistedUmbrella SwitchCompatLibrary doesn't provide SwitchPreference so doesn't help with this question. – Intrications Jan 18 '13 at 19:34
  • @Intrications As I stated on your github, SwitchPreference is just a handler for the Switch. In all honesty your "TwoStatePreference" is almost the same as SwitchCompatLibrary's base Switch. It doesn't require the added bloat in yours to function as a SwitchPreference. – Abandoned Cart Jan 21 '13 at 01:13
0

I've tried every solution that i found but non of them were fit my needs, so i created my own widget wich is used ObjectAnimator from nineOld compatibility lib and works pretty fine on any android API.

import android.widget.RelativeLayout;
import com.myapp.utilities.AppUtils;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ObjectAnimator;

public class SwitchButton extends RelativeLayout {

public static final int TEXT_SIZE = 11;

public float HANDLE_SHIFT = -40f;
public float TEXT_RIGHT_SHIFT = 40f;
public static int BUTTON_ID = 0x00009999;
public static int TEXT_ID = 0x00008888;


private Button handleButton;
private RoboTextView textView;
private boolean switchEnabled;
private String yesStr;
private String noStr;
private int TEXT_LEFT_PADDING = 13;

private ObjectAnimator animateHandleLeftShift;
private ObjectAnimator animateHandleRightShift;
private int HANDLE_BUTTON_HEIGHT = 22;
private int HANDLE_BUTTON_WIDTH = 42;
private ObjectAnimator animateTextLeftShift;
private ObjectAnimator animateTextRightShift;


public SwitchButton(Context context) {
    super(context);
    onCreate(context);
}


private void onCreate(Context context) {

    float density = context.getResources().getDisplayMetrics().density;

    TEXT_LEFT_PADDING *= density;

    HANDLE_BUTTON_HEIGHT *= density;
    HANDLE_BUTTON_WIDTH *= density;

    HANDLE_SHIFT *= density;
    TEXT_RIGHT_SHIFT *= density;

    yesStr = getContext().getString(R.string.yes).toUpperCase();
    noStr = getContext().getString(R.string.no).toUpperCase();

    {// Button
        handleButton = new Button(getContext());
        RelativeLayout.LayoutParams buttonParams = new LayoutParams(HANDLE_BUTTON_WIDTH, HANDLE_BUTTON_HEIGHT);
        buttonParams.addRule(RelativeLayout.CENTER_VERTICAL);
        buttonParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

        handleButton.setBackgroundResource(R.drawable.button_switch_handle_selector);
        handleButton.setId(BUTTON_ID);

        addView(handleButton, buttonParams);
    }


    {// Text
        textView = new RoboTextView(getContext());
        LayoutParams textParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        textParams.addRule(RelativeLayout.CENTER_VERTICAL);

        textView.setText(yesStr);
        textView.setTextColor(getContext().getResources().getColor(R.color.new_normal_gray));
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE);
        textView.setPadding(TEXT_LEFT_PADDING, 0, 0, 0);
        textView.setFont(RoboTextView.ROBOTO_BOLD_FONT);
        textView.setId(TEXT_ID);
        float shadowRadius = 0.5f ;
        float shadowDx = 0;
        float shadowDy = 1;
        textView.setShadowLayer(shadowRadius, shadowDx, shadowDy, Color.BLACK);

        addView(textView, textParams);
    }
    initFlipAnimation();

}

@Override
public void setOnClickListener(OnClickListener l) {
    handleButton.setOnClickListener(l);
    textView.setOnClickListener(l);
}

public void toggle(View view){
    if (AppUtils.HONEYCOMB_PLUS_API && view.getId() == TEXT_ID) { // ignore text clicks
        return;
    }

    switchEnabled = !switchEnabled;

    if (switchEnabled) {
        // animate handle to the left
        animateHandleLeftShift.start();
        animateTextLeftShift.start();

        textView.setText(noStr);
    } else {
        animateHandleRightShift.start();
        animateTextRightShift.start();

        textView.setText(yesStr);
    }
}

private android.view.animation.Interpolator accelerator = new LinearInterpolator();
private static final int DURATION = 70;

private void initFlipAnimation() {


    animateHandleLeftShift = ObjectAnimator.ofFloat(handleButton, "translationX", 0f, HANDLE_SHIFT);
    animateHandleLeftShift.setDuration(DURATION);
    animateHandleLeftShift.setInterpolator(accelerator);

    animateHandleRightShift = ObjectAnimator.ofFloat(handleButton, "translationX", HANDLE_SHIFT, 0f);
    animateHandleRightShift.setDuration(DURATION);
    animateHandleRightShift.setInterpolator(accelerator);

    animateHandleLeftShift.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator anim) {
            // TODO
        }
    });


    animateTextLeftShift = ObjectAnimator.ofFloat(textView, "translationX", 0f, TEXT_RIGHT_SHIFT);
    animateTextLeftShift.setDuration(DURATION);
    animateTextLeftShift.setInterpolator(accelerator);

    animateTextRightShift = ObjectAnimator.ofFloat(textView, "translationX", TEXT_RIGHT_SHIFT, 0f);
    animateTextRightShift.setDuration(DURATION);
    animateTextRightShift.setInterpolator(accelerator);
}

}

In XML

<com.chess.SwitchButton
    android:id="@+id/ratedGameSwitch"
    android:layout_width="@dimen/button_switch_width"
    android:layout_height="@dimen/button_switch_height"
    android:background="@drawable/button_switch_back"
    />

In the Activity/Fragment you only have to findViewById and set clickListener to it, and in onClick callback handle it:

switchButton = (SwitchButton) optionsView.findViewById(R.id.ratedGameSwitch);
switchButton.setOnClickListener(this);


@Override
public void onClick(View view) {
    if (view.getId() == SwitchButton.BUTTON_ID  || view.getId() == SwitchButton.TEXT_ID){
        switchButton.toggle(view);
    }
}
Roger Alien
  • 3,040
  • 1
  • 36
  • 46
0

Try this solution, if you want to create settings activity programmatically.

public class SettingsActivity extends PreferenceActivity {

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PreferenceScreen rootScreen = getPreferenceManager()
                .createPreferenceScreen(this);
        setPreferenceScreen(rootScreen);
        Preference NotifCheck=null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            NotifCheck = new SwitchPreference(this);

        } else {
            NotifCheck = new CheckBoxPreference(this);

        }
        NotifCheck.setKey("yourKey");
        NotifCheck.setTitle(R.string.ShowNotification);
        NotifCheck.setEnabled(true);
        rootScreen.addPreference(NotifCheck);
    }
}
Vladislav
  • 1,236
  • 13
  • 22