

오늘은 커스텀 스위치 버튼을 만드는 방법을 포스팅하려고 한다.
안드로이드에서 기본으로 제공되는 스위치 버튼의 경우 원모양의 thumb가 바깥 영역인 track 보다 큰 형태이다.

따라서 시안에 맞게 작업을 해주기 위해선 커스텀이 필요했다.
커스텀한다는게 뭐 무에서부터 새로운 스위치버튼을 창조하는 것은 아니고 check가 되었는지 안되었는지에 따라서 selector를 통해 thumb 와 track을 바꿔주는 작업을 한다는 의미이다.
코드로 보면 다음과 같다.
shape_switch_track_off.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="50dp" />
<size
android:width="52dp"
android:height="27dp" />
<solid android:color="#D6D6D6"/>
</shape>
shape_switch_track_on.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="50dp" />
<size
android:width="52dp"
android:height="27dp" />
<solid android:color="#C2F3D2" />
</shape>
shape_switch_thumb_off.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="27dp"
android:height="27dp" />
<solid android:color="#ECECEC" />
</shape>
shape_switch_thumb_on.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="27dp"
android:height="27dp" />
<solid android:color="#53E183" />
</shape>
selector_switch
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_switch_track_off" android:state_checked="false" />
<item android:drawable="@drawable/shape_switch_track_on" android:state_checked="true" />
</selector>
selector_thumb
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_switch_thumb_off" android:state_checked="false" />
<item android:drawable="@drawable/shape_switch_thumb_on" android:state_checked="true" />
</selector>
activity or fragment
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/sc_manage"
android:layout_width="56dp"
android:layout_height="28dp"
android:layout_marginEnd="18dp"
android:background="@null"
android:thumb="@drawable/selector_thumb"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:switchMinWidth="52dp"
app:track="@drawable/selector_switch" />
switch button의 check가 변할때 ripple effect를 off 하기위해 background 옵션을 null로 설정하였다.
하지만 이렇게 만들어줄 경우 문제가 발생한다.


바로 thumb가 track과 크기와 일치하거나 더 커질 경우만 가능하다는 것이다.
thumb의 절대적인 크기를 줄여도 track 내부에 들어가도록 작아지지 않았다.
스택오버플로우에도 찾아보았는데 맘에 드는 방법을 발견하지 못했다.
이를 해결할 괜찮은 방법을 생각해보다가 thumb의 테두리를 track의 색상과 같게 해주면(눈속임)
이를 구현할 수 있을 것이라 판단했다. 색이 같으면 그 영역은 track으로 보여지기 때문이다.
shape_switch_thumb_off
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="27dp"
android:height="27dp" />
<solid android:color="#ECECEC" />
<stroke
android:width="3dp"
android:color="#D6D6D6" />
</shape>!
shape_switch_thumb_on
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size
android:width="27dp"
android:height="27dp" />
<solid android:color="#53E183" />
<stroke
android:width="3dp"
android:color="#C2F3D2" />
</shape>
결과


오늘도 문제를 해결하였다.
혹시 더 좋은 방법이 있으면 덧글로 알려주시면 감사하겠습니다.
https://stackoverflow.com/questions/22726408/switch-button-thumb-gets-skewed
자체적으로 padding 을 dimens 을 통해 넣어주거나 하는 방법이 있다고 한다.
https://wimir-dev.tistory.com/44
https://velog.io/@developerelen/Android-Switch-%EB%B2%84%ED%8A%BC-customizing