How to shrink SwitchCompat width?
Asked Answered
S

1

7

I want to reduce my Switch's width. The current solution in How to change the size of a Switch Widget and How to change Width of Android's Switch track? is not solving my problem. android:switchMinWidth just defined the minWidth, but I want it to be smaller than 2 x thumbWidth size.

I dig into the SwitchCompat class' onMeasure() function. The way the width is defined is as below.

    // Adjust left and right padding to ensure there's enough room for the
    // thumb's padding (when present).
    int paddingLeft = padding.left;
    int paddingRight = padding.right;
    if (mThumbDrawable != null) {
        final Rect inset = DrawableUtils.getOpticalBounds(mThumbDrawable);
        paddingLeft = Math.max(paddingLeft, inset.left);
        paddingRight = Math.max(paddingRight, inset.right);
    }

    final int switchWidth = Math.max(mSwitchMinWidth,
            2 * mThumbWidth + paddingLeft + paddingRight);
    final int switchHeight = Math.max(trackHeight, thumbHeight);
    mSwitchWidth = switchWidth;
    mSwitchHeight = switchHeight;

I was considering using negative padding, but then there's this line paddingLeft = Math.max(paddingLeft, inset.left);. I'm not sure how to set the inset to my thumb drawable that has negative value (I don't know what inset or OpticalBounds is. Maybe this should be another stackoverflow question ).

Anyone has idea how I could shrink the width of my SwitchCompat?

Update I have filed a request to google on this https://code.google.com/p/android/issues/detail?id=227184&thanks=227184&ts=1478485498

Seaquake answered 3/11, 2016 at 2:40 Comment(2)
fair answer would be make your own track and thumb drawable that would solve your problem. There is no standard way to shrink the size.Saturant
Already have my own thumb drawable. That's the problem, as the thumb drawable is slightly big. But I don't want my track to be 2x the length. Having my own track is not helping either as seemingly the width of the switch doesn't depends on my track drawable length.Seaquake
S
3

The current approach I could workaround the challenge is using reflection to force set the mSwitchWidth variable right after the onMeasure(...) function is called.

public class SwitchCustomWidth extends SwitchCompat {

    //... the needing constructors goes here...    

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        try {
            Field switchWidth = SwitchCompat.class.getDeclaredField("mSwitchWidth");
            switchWidth.setAccessible(true);

            // Using 120 below as example width to set
            // We could use attr to pass in the desire width
            switchWidth.setInt(this, 120);

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

This is not ideal. I hope to have someone else contribute a better answer, without needing reflection (or copy entire class over to modify the class, or rewriting a custom Switch just because of the width issue).

If there's no solution out there, then this would serve best for now to help others facing the same challenge.

Seaquake answered 4/11, 2016 at 15:17 Comment(1)
I followed this but I can't make the Switch switch, it somewhat disabled the click/touch on the viewPolanco

© 2022 - 2024 — McMap. All rights reserved.