Android custom View ------- IOS sliding switch, android custom view
Source code and test examples have been put on github https://github.com/leaking/slideswitch. welcome star fork issue
During project development, there are often some user-specific settings. At this time, a switch control is often required. On the weekend, the custom switch control is optimized as follows. Let's talk about the general idea: the button draws three layers, the bottom is the gray covering the entire View, and the second is the custom color covering the entire View, which can change the transparency. The third is white. When the white part moves, modify the transparency of the second layer to make the color gradient effect during the sliding process.
Record the implementation process of rewriting a component.
1. Define attributes
2. Get the attribute value from the constructor in the Java code.
3. Override onMeasure ()
4. Override onDraw ()
5. Rewrite the onTouch listener if needed.
6. Define a namespace in the layout file of your project and use attributes
1. Define attributes
Create a new project named SlieSwitch and create the property file SlideSwitch \ res \ values \ attrs. xml
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="slideswitch"> <attr name="themeColor" format="color" /> <attr name="isOpen" format="boolean" /> <attr name="shape"> <enum name="rect" value="1" /> <enum name="circle" value="2" /> </attr> </declare-styleable></resources>
Three attributes are defined. One is the color of the button, the other is the open status of the button, and the other is the enumeration type, which is used to describe the shape of the button, the use of these attributes and several other types of attributes can be easily achieved by Baidu Google, which is not recorded here.
2. Get the attribute value from the constructor in the Java code.
Create a new package com. leaking. slideswitch in SlieSwitch, and create a file SlieSwitch. java in the package. The custom component must first inherit the View class and then obtain the custom attributes in the constructor, as shown in the following Emma fragment:
Public class SlideSwitch extends View {//, omitted, public SlideSwitch (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); listener = null; paint = new Paint (); paint. setAntiAlias (true); TypedArray a = context. obtainStyledAttributes (attrs, R. styleable. slideswitch); color_theme =. getColor (R. styleable. slideswitch_themeColor, COLOR_THEME); isOpen =. getBoolean (R. styleable. slideswitch_isOpen, false); shape =. getInt (R. styleable. slideswitch_shape, SHAPE_RECT);. recycle ();} public SlideSwitch (Context context, AttributeSet attrs) {this (context, attrs, 0);} public SlideSwitch (Context context) {this (context, null );} //, omitted ,,,,,,,,,,}
Generally, a View has three constructors. I am used to having only one constructor to call two constructor parameters, and then two calls to three constructor, use TypeArray to read custom attributes in the constructor with three parameters, and then call the recycle () method of TypeArray to recycle resources.
3. Override onMeasure ()
You can search for the onMeasure () method on the Internet, but it is hard to find out why you need to rewrite the onMeasure () method. This question is recorded in another article.
Android custom View ------- why to override onMeasure () and how to rewrite it
In onMeasure (), we mainly do two things here. The first is to calculate the size of the View, that is, its length and width, and the second is to record the starting position of the white color block, and some other parameters of the draw button. Note that when you call the invalidate () method of view for repainting, the system will only call the onDraw () method, however, if the size and content of other components (such as the setText () of TextView) are modified, onMeasure () is triggered, so the location variable calculated in onMeasure () is, avoid being affected by calling onMeasure () again. This is the cause of a bug in the coding process.
4. Override onDraw ()
The onDraw () part is relatively easy. You only need to draw three layers based on the parameters calculated in onMeasure.
5. Rewrite the onTouch listener if needed.
This part is also relatively easy, that is, to calculate the positions based on the down, move, and up events respectively, modify the transparency of the second layer color, and then call invaliate to re-paint the View. Start a thread in the up event to automatically move the button to the end.
6. Define a namespace in the layout file of your project and use attributes
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:slideswitch="http://schemas.android.com/apk/res/com.example.testlibs" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffffff" android:gravity="center_horizontal" android:orientation="vertical" android:padding="10dip" tools:context="com.example.testlibs.MainActivity" > <com.leaking.slideswitch.SlideSwitch android:id="@+id/swit" android:layout_width="150dip" android:layout_height="60dip" slideswitch:isOpen="true" slideswitch:shape="rect" slideswitch:themeColor="#ffee3a00" > </com.leaking.slideswitch.SlideSwitch></LinearLayout>
Note that the second line of the preceding code snippet introduces a namespace in the following format:
Xmlns: Name = "http://schemas.android.com/apk/res/your application package name"
Note that the last part is the application package name of the project where you use the custom VIew.
Next, set the monitoring and status settings of the switch in the Java code, as shown in the following code:
public class MainActivity extends Activity implements SlideListener {TextView txt;SlideSwitch slide;SlideSwitch slide2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);slide = (SlideSwitch) findViewById(R.id.swit);slide2 = (SlideSwitch) findViewById(R.id.swit2);slide.setState(false);txt = (TextView) findViewById(R.id.txt);slide.setSlideListener(this);}@Overridepublic void open() {// TODO Auto-generated method stubtxt.setText(" is opend ");}@Overridepublic void close() {// TODO Auto-generated method stubtxt.setText(" is close ");}}
SlideSwitch. java complete code
Complete code and test examples are put on github, https://github.com/Leaking/SlideSwitch
Package com. leaking. slideswitch; import android. content. context; import android. content. res. typedArray; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. graphics. rect; import android. graphics. rectF; import android. OS. handler; import android. OS. logoff; import android. OS. message; import android. support. v4.view. motionEventCompat; import android. util. attr IbuteSet; import android. view. motionEvent; import android. view. view; import com. example. slideswitch. r; public class SlideSwitch extends View {public static final int SHAPE_RECT = 1; public static final int SHAPE_CIRCLE = 2; private static final int RIM_SIZE = 6; private static final int COLOR_THEME = Color. parseColor ("# ff00ee00"); // 3 attributesprivate int color_theme; private boolean isOpen; private int s Hape; // varials of drawingprivate Paint; private Rect backRect; private Rect frontRect; private int alpha; private int max_left; private int min_left; private int frontRect_left; private int trim = RIM_SIZE; private int eventStartX; private int eventLastX; private int diffX = 0; private SlideListener listener; public interface SlideListener {public void open (); public void close ();} public SlideSwitch (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); listener = null; paint = new Paint (); paint. setAntiAlias (true); TypedArray a = context. obtainStyledAttributes (attrs, R. styleable. slideswitch); color_theme =. getColor (R. styleable. slideswitch_themeColor, COLOR_THEME); isOpen =. getBoolean (R. styleable. slideswitch_isOpen, false); shape =. getInt (R. styl Eable. slideswitch_shape, SHAPE_RECT);. recycle ();} public SlideSwitch (Context context, AttributeSet attrs) {this (context, attrs, 0);} public SlideSwitch (Context context) {this (context, null) ;}@ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec); int width = measureDimension (280, widthMeasureSpec); int height = measureDime Nsion (140, heightMeasureSpec); if (shape = SHAPE_CIRCLE) {if (width
Finally, let's talk about how to upload GIF images on the csdn blog: instead of directly uploading images, we must first transfer the images to the csdn album and then copy the links to the images in the album.