Custom sliding buttons For example graphic profiling Android Custom View Drawing _android

Source: Internet
Author: User
Tags float max

Custom view has always been a hurdle for Android developers.

The relationship between view and ViewGroup

From view and ViewGroup relationship, ViewGroup inherits view.

View subclasses, mostly functional controls, provide the style to draw, such as Imageview,textview, and ViewGroup subclasses, used to manage the size of controls, locations, such as Linearlayout,relativelayout, As you can see from the figure below,

From the practical application, they are also the combination of relations, we are in the layout, often a viewgroup nested multiple viewgroup or view, and nested viewgroup will nest multiple viewgroup or view

As follows

Second, the view of the drawing process

From view Source view, the main relationship three methods:

1, Measure (): Measurement
A final method that controls the size of the control
2, Layout (): Layout
To control the location of your layout
Have relativity, only relative to their own parent-class layout, do not care about ancestral layout
3, Draw (): Drawing
Used to control the display style of a control

Process: process measure--> layout--> Draw

The method that corresponds to our implementation is

Onmeasure ()

OnLayout ()

OnDraw ()

In actual drawing, our thinking order is generally like this:

Whether you want to control the size of the control--> is-->onmeasure ()
(1) If this custom view is not a viewgroup,onmeasure () method call Setmeasuredeminsion (width,height): Used to set its own size
(2) if the Viewgroup,onmeasure () method is invoked, child.measure () measures the child's size, gives the child's expected size value, and then-->setmeasuredeminsion (width,height): Use to set your own size

Whether you want to control the placement of controls--> is-->onlayout ()

Do you want to control the appearance of the control--> is the drawing of-->ondraw ()-->canvas

Here's the flowchart I'm drawing:

The following is an example of a custom slide button to illustrate the drawing process of a custom view

We look forward to achieving this effect:

Drag or click on the button, the switch to the right slide, into


The switch can slide to the corresponding position with the touch of the finger until it is finally fixed on the switch position.

Create a new class that inherits from view and implements its two constructed methods

public class Switchbuttonview extends View {public 
 
   
  Switchbuttonview (context 
    , null); 
  Public 
 
  Switchbuttonview (context, AttributeSet attrs) { 
    Super (context, attrs); 
  

Add these two pictures to the drawable resource

In this case, we can use Onmeasure () to determine the size of this control

@Override 
  protected void onmeasure (int widthmeasurespec, int heightmeasurespec) { 
 
    Mswitchbutton = Bitmapfactory.decoderesource (Getresources (), r.drawable.switch_background); 
    Mslidebutton = Bitmapfactory.decoderesource (Getresources (), r.drawable.slide_button_background); 
    Setmeasureddimension (Mswitchbutton.getwidth (), Mswitchbutton.getheight ()); 
  } 

This control does not need to control its placement, skip onlayout ();

Next OnDraw () determines its shape.

But we need to determine the shape based on the different behaviors we click on the control, which requires rewriting the ontouchevent ()

The logic is:

When pressed, triggers the event motionevent.action_down, if the state is off at this time:

(1) If the finger touch point (through Event.getx () to the right of the center line of the button, the button to the right to slide a distance (Event.getx () and the switch control width of the difference, specific look at the source below)

(2) If the finger touch point on the left side of the button centerline, the button is still at the leftmost (that is, "off" state).

If the state is open at this time:

(1) If the finger touch point on the left side of the button centerline, the button to the left to slide a distance

(2) If the finger touch point on the right side of the button centerline, the button is still at the far right (that is, "open" state)

When sliding, the trigger time is motionevent.action_move, and the logic is consistent with the press

Note that ontouchevent () requires that the return value be set to True, otherwise the slide event cannot be responded to

When the finger is closed, if the switch centerline is located on the left side of the entire control centerline, the setting state is off, otherwise, set to open.

The specific source code is as follows: (also provides an external exposure at this time the switch state of the interface)

Customizing the View section

Package Com.lian.switchtogglebutton; 
Import Android.content.Context; 
Import Android.graphics.Bitmap; 
Import Android.graphics.BitmapFactory; 
Import Android.graphics.Canvas; 
Import Android.graphics.Paint; 
Import Android.util.AttributeSet; 
Import Android.util.Log; 
Import android.view.MotionEvent; 
 
Import Android.view.View; 
 /** * Created by Lian on 2016/3/20. * * public class Switchbuttonview extends View {private static final int state_null = 0;//default state private static fin 
  Al int state_down = 1; 
  private static final int state_move = 2; 
 
  private static final int state_up = 3; 
  Private Bitmap Mslidebutton; 
  Private Bitmap Mswitchbutton; 
  Private Paint Mpaint = new Paint (); 
  private int buttonstate = State_null; 
  private float mdistance; 
  Private Boolean isopened = false; 
 
  Private Onswitchlistener Mlistener; 
  Public Switchbuttonview {This (context, NULL); Public Switchbuttonview, AttributeSet attrs) {Super (context, attrs); @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {Mswitchbutton = Bitmapf 
    Actory.decoderesource (Getresources (), r.drawable.switch_background); 
    Mslidebutton = Bitmapfactory.decoderesource (Getresources (), r.drawable.slide_button_background); 
  Setmeasureddimension (Mswitchbutton.getwidth (), Mswitchbutton.getheight ()); 
    } @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); 
    if (mswitchbutton!= null) {Canvas.drawbitmap (Mswitchbutton, 0, 0, mpaint); 
        The value of//buttonstate determines the switch (buttonstate) {case State_down:case state_move in Ontouchevent (): 
          if (!isopened) {Float middle = mslidebutton.getwidth ()/2f; 
            if (Mdistance > middle) {Float max = Mswitchbutton.getwidth ()-mslidebutton.getwidth (); 
            float left = Mdistance-middle; 
              if (left >= max) {left = max; 
          } canvas.drawbitmap (Mslidebutton,left,0,mpaint); 
          else {canvas.drawbitmap (mslidebutton,0,0,mpaint); 
          }else{Float middle = mswitchbutton.getwidth ()-mslidebutton.getwidth ()/2f; 
            if (Mdistance < middle) {float left = mdistance-mslidebutton.getwidth ()/2f; 
            float min = 0; 
            if (left < 0) {left = min; 
          } canvas.drawbitmap (Mslidebutton,left,0,mpaint); 
          }else{Canvas.drawbitmap (Mslidebutton,mswitchbutton.getwidth ()-mslidebutton.getwidth (), 0,mPaint); 
 
      }} break; 
          Case State_null:case State_up:if (isopened) {log.d ("switch", "open"); 
        Canvas.drawbitmap (Mslidebutton,mswitchbutton.getwidth ()-mslidebutton.getwidth (), 0,mpaint); 
          }else{log.d ("switch", "closed"); Canvas.drawbitmaP (mslidebutton,0,0,mpaint); 
 
      } break; 
    Default:break;  @Override public boolean ontouchevent (Motionevent event) {switch (event.getaction ()) {case 
        MotionEvent.ACTION_DOWN:mDistance = Event.getx (); 
        LOG.D ("Down", "press"); 
        ButtonState = State_down; 
        Invalidate (); 
 
      Break 
        Case MotionEvent.ACTION_MOVE:buttonState = State_move; 
        Mdistance = Event.getx (); 
        LOG.D ("Move", "moving"); 
        Invalidate (); 
 
      Break 
        Case MotionEvent.ACTION_UP:mDistance = Event.getx (); 
        ButtonState = state_up; 
        LOG.D ("Up", "off"); 
        if (mdistance >= mswitchbutton.getwidth ()/2f) {isopened = true; 
        }else {isopened = false; 
        } if (Mlistener!= null) {mlistener.onswitchchanged (isopened); 
        } invalidate (); 
      Break 
 Default:break;   return true; 
  public void Setonswitchlistener (Onswitchlistener listener) {This.mlistener = listener; 
  public interface onswitchlistener{void Onswitchchanged (Boolean isopened);  } 
}

Demoactivity:

Package Com.lian.switchtogglebutton; 
 
Import Android.os.Bundle; 
Import android.support.v7.app.AppCompatActivity; 
Import Android.widget.Toast; 
 
public class Mainactivity extends Appcompatactivity { 
 
  @Override 
  protected void OnCreate (Bundle Savedinstancestate) { 
    super.oncreate (savedinstancestate); 
    Setcontentview (r.layout.activity_main); 
 
    Switchbuttonview Switchbuttonview = (switchbuttonview) Findviewbyid (R.id.switchbutton); 
    Switchbuttonview.setonswitchlistener (New Switchbuttonview.onswitchlistener () { 
      @Override public 
      Void Onswitchchanged (Boolean isopened) { 
        if (isopened) { 
          toast.maketext (mainactivity.this, "open", toast.length_ Short). Show (); 
        else { 
          Toast.maketext (mainactivity.this, "close", Toast.length_short). Show ();}}} 
   

Layout:

<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android= 
  "http://" Schemas.android.com/apk/res/android " 
  xmlns:tools=" Http://schemas.android.com/tools " 
  android:layout_ Width= "Match_parent" 
  android:layout_height= "match_parent" 
  android:paddingbottom= "@dimen/activity_ Vertical_margin " 
  android:paddingleft=" @dimen/activity_horizontal_margin " 
  android:paddingright=" @dimen Activity_horizontal_margin " 
  android:paddingtop=" @dimen/activity_vertical_margin " 
  tools:context=" Com.lian.switchtogglebutton.MainActivity "> 
 
  <com.lian.switchtogglebutton.switchbuttonview 
    Android:id= "@+id/switchbutton" 
    android:layout_width= "wrap_content" 
    android:layout_height= "WRAP_" Content " 
    /> 

The above is the entire content of this article, I hope to help you learn.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.