Saturday 6 September 2014

Customizing Switch Android

CUSTOMIZING SWITCH

Switch is a type of toggle button. This toggle button is supported in API 14 and in later versions. It has the same functionality as defined for toggle button. The specialty of this compound button is that it provides a slider which you can slide to check/select a particular state. The button which you use to move/slide in order to select a particular state is known as thumb & the thing on which the thumb slides back and forth is known as track. So in order to customize the switch we can customize the thumb and track. We can also use selectors for selecting the appropriate drawable or color for a particular state in which the switch compound button is in.

So based on the following information, let's get started.

The first step is to customize the thumb, but the background color and text of the thumb changes according to the state the button is in. So in order to achieve this use <selector>.

customswitchselector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_checked="true">
        <shape android:shape="rectangle"
               android:visible="true"
               android:dither="true"
               android:useLevel="false">
       
        <gradient android:startColor="#66AAFF00"
                  android:endColor="#6600FF00"
                  android:angle="270"/>
    
       <corners android:radius="15dp"/>
    
       <size android:width="27dp"
          android:height="37dp" />
       </shape>
      </item>
    
    <item android:state_checked="false">
         <shape android:shape="rectangle"
               android:visible="true"
               android:dither="true"
               android:useLevel="false">
       
        <gradient android:startColor="#66FF0000"
                  android:endColor="#66FF00CC"
                  android:angle="270"/>
    
       <corners android:radius="15dp"/>
    
       <size android:width="27dp"
          android:height="37dp" />
       </shape>
    </item>


</selector>

In the above xml file the selector for changing the background of the thumb according to the state the switch button is in. As you can see, custom shapes are nested inside item elements. The nested custom shapes is selected as per the state of the switch.

Now the next step is to customize the track in which the thumb slides.

customtrack.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
       android:shape="rectangle"
       android:visible="true"
       android:dither="true"
       android:useLevel="false">
    <gradient android:startColor="#660000FF"
              android:endColor="#6600CCFF"
              android:angle="270"/>
    <corners android:radius="15dp"/>
    <size android:width="30dp"
          android:height="40dp" />
</shape>

Well the above xml file defines the custom shape for track in which the thumb slides. In android custom shapes are defined in xml. The root node is shape with an xmlns attribute that defines the namespace.
Basically 4 types of custom shapes are supported i.e. rectangle, oval, ring and line. Then after defining the shape that you want to use, specify some properties related to shape such as dither, visible and useLevel  etc.

Some more nodes or elements are also supported such as gradient, solid, corners, stroke, padding and size.
gradient node is basically used for defining gradient background. corners node is used for defining corners basically for rectangle shape. Now we can also define the size of the custom shape using the size node.

Now the layout file in which the switch button is defined:--

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@drawable/background"
              android:orientation="vertical">
              
        <include layout="@layout/customtitlebar"/>

     <Switch android:id="@+id/swtch"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:textOn="@string/checkedstate"
             android:textOff="@string/uncheckedstate"
             android:minWidth="25dp"
             android:layout_marginTop="29dp"
             android:layout_marginLeft="40dp"
             android:switchPadding="10dp"
             android:onClick="togglestatehandler"
             android:thumb="@drawable/customswitchselector"
             android:track="@drawable/customtrack"
             android:thumbTextPadding="15dp"
             android:textStyle="bold|italic"
             android:typeface="sans"/>

</LinearLayout>

Now you can see in the layout file how we have referred to the custom selector we defined for thumb and track. We have done this using android:thumb for thumb and android:track for track.
             android:thumb="@drawable/customswitchselector"
             android:track="@drawable/customtrack"

The custom selectors are defined as drawable.

The strings or text used for textOn and textOff are defined in the strings.xml file.

Here is the strings.xml file present in the values directory.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="checkedstate">START</string>
    <string name="uncheckedstate">STOP</string>
</resources>

Now the java code:--
package com.example.practice;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.PopupWindow;
import android.widget.Switch;
import android.widget.Toast;

@SuppressLint("NewApi")
public class ActivityE extends Activity{

Switch switchbtn;
private Context context = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_e);
        switchbtn = (Switch)findViewById(R.id.swtch);
        applyStyle(switchbtn.getTextOn(), switchbtn.getTextOff());
        
}
public void applyStyle(CharSequence switchTxtOn, CharSequence switchTxtOff){

Spannable styleText = new SpannableString(switchTxtOn);
StyleSpan style = new StyleSpan(Typeface.BOLD);
styleText.setSpan(style, 0, switchTxtOn.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
styleText.setSpan(new ForegroundColorSpan(Color.GREEN), 0, switchTxtOn.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
switchbtn.setTextOn(styleText);
styleText = new SpannableString(switchTxtOff);
styleText.setSpan(style, 0, switchTxtOff.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
styleText.setSpan(new ForegroundColorSpan(Color.RED), 0, switchTxtOff.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
switchbtn.setTextOff(styleText);
}
public void togglestatehandler(View v){
Switch switchbtn = (Switch)v;
boolean isChecked = switchbtn.isChecked();
if(isChecked){
Toast.makeText(context, "STARTED......", Toast.LENGTH_SHORT).show();
        } else {
Toast.makeText(context, "STOPPED......", Toast.LENGTH_SHORT).show();
        }

}
}

The most noticeable thing in the code is changing the color of the text used in the thumb based on the changing of the state of the compound button i.e Switch.

 public void applyStyle(CharSequence switchTxtOn, CharSequence switchTxtOff){

Spannable styleText = new SpannableString(switchTxtOn);
StyleSpan style = new StyleSpan(Typeface.BOLD);
 styleText.setSpan(style, 0, switchTxtOn.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 styleText.setSpan(new ForegroundColorSpan(Color.GREEN), 0, switchTxtOn.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 switchbtn.setTextOn(styleText);
 styleText = new SpannableString(switchTxtOff);
 styleText.setSpan(style, 0, switchTxtOff.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 styleText.setSpan(new ForegroundColorSpan(Color.RED), 0, switchTxtOff.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
 switchbtn.setTextOff(styleText);
}
Now in the above code as we know that Switch has two states and two texts are used to represent the appropriate state. For on state we used START and for off state it is STOP. Now we want to change the color of the text. So we did it using Spannable. What this code does is that it makes two spannable objects for styling the checked text and unchecked state of the Switch button. 

So , the last thing remains here is how to capture the state of the Switch button and performs appropriate action based upon the state the Switch button is in.

This is done by using togglestatehandler method . This method name is defined in the layout file as 
             android:onClick="togglestatehandler"

So now when the Switch button is clicked or the state of the compound button is changed manually then the method defined as value for the onClick attribute is invoked. It's definition is provided below:--

public void togglestatehandler(View v){
Switch switchbtn = (Switch)v;
boolean isChecked = switchbtn.isChecked();
if(isChecked){
Toast.makeText(context, "STARTED......", Toast.LENGTH_SHORT).show();
        } else {
Toast.makeText(context, "STOPPED......", Toast.LENGTH_SHORT).show();
        }
}

What this code does is that it checks the state of the Switch button and performs appropriate action based upon the state the Switch button is in. In this case we are simply displaying a Toast based upon the state of the Switch compound button.

Finally the included layout:--

customtitlebar.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent" 
          android:layout_height="70dp"
          android:background="@drawable/custom_titlebar"
          android:orientation="vertical"
          android:id="@+id/customtitle">
  
    <TextView android:id="@+id/titleText"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:paddingTop="20dp"
               android:paddingBottom="20dp"
               android:layout_gravity="center_horizontal"
               android:text="@string/title_activity_activity_b"
               android:textSize="26sp"/>     
    </LinearLayout>  

Output :--

In Start State




In Stop State



Finally we have successfully customized the switch button. 
Happy Coding :)





No comments:

Post a Comment