One of the controls in Android is ProgressBar, and there is a absseekbar in its subclasses. I believe there are a lot of children's shoes for this drag bar of the parent class is more interested in it! Especially see NetEase Cloud music progress bar above is can deal with playback and pause events, is not very envious ha ~ I here to tell you, do not envy, see me the following code analysis, you can also make that effect oh. Let ' s go.
Let's give you a list of what the member variables of Absseekbar are.
The current rectangle private final rect mtemprect = new rect (); Can drag the slider private drawable mthumb; The list of state of the color private colorstatelist mthumbtintlist = null; The fusion of the corresponding ports private porterduff.mode mthumbtintmode = null; Whether the cheerful Tint private Boolean mhasthumbtint = False is supported; The pattern corresponding to the slider is private Boolean mhasthumbtintmode = false; The offset of the slider private int mthumboffset; Whether to split tracking private Boolean msplittrack;
In the variables we need to know a few things:
1. Mtemprect is a variable related to the entire trajectory drawing of Seekbar
2, Mthumb is Seekbar above the slider of the drawable picture
3. Mthumboffset is the distance from the left margin of the X-slider.
For the Absseekbar member method, the following select a more important, in the actual development work often used in several ways to explain to you.
1, Setthumboffset
This method is to set the position of the slider from the left margin.
2.
Public synchronized void Setmax (int max) { super.setmax (max); if ((mkeyprogressincrement = = 0) | | (Getmax ()/mkeyprogressincrement > 20)) { //It'll take the user too long-to-change this via keys, change it //to something more reasonable//set to compare Reasonable numerical setkeyprogressincrement (Math.max (1, Math.Round ((float) getmax ()));} }
This method actually correlates to two functions.
1. Set the maximum value of the current Seekbar
2, because there are some mobile phones have left the button and the right button, such as I have encountered a Samsung business machine. According to the logic of the source code, control the left button and the right button one displacement of the margin not more than 20.
The following piece of code focuses on the drawing of the trajectory and the update of the slider's drawing
if (track! = null) { track.setbounds (0, Trackoffset, W-mpaddingright-mpaddingleft, H-mpaddingbottom-tracko ffset-mpaddingtop); } if (thumb! = null) { Setthumbpos (w, Thumb, Getscale (), thumboffset); }
The plot of the trajectory is more important, let's take a look together;
void Drawtrack (canvas canvas) { //Get a reference to the current slider final drawable thumbdrawable = mthumb; if (thumbdrawable! = null && msplittrack) { final Insets Insets = Thumbdrawable.getopticalinsets (); Final Rect temprect = mtemprect; Thumbdrawable.copybounds (temprect); Temprect.offset (Mpaddingleft-mthumboffset, mpaddingtop); Temprect.left + = Insets.left; Temprect.right-= insets.right; Final int savecount = Canvas.save (); Crops the current rectangle canvas.cliprect (temprect, op.difference); Super.drawtrack (canvas); Canvas.restoretocount (Savecount); } else { super.drawtrack (canvas); } }
For the above code block, the main points are as follows:
1, mslittrack this variable exists because we usually encounter the slider of the left and right color is different, this variable is to split the left and right sides of the purpose.
The drawing of the slider is also more important, oh, here is also a look at it:
void Drawthumb (canvas canvas) { if (mthumb! = null) { canvas.save (); Translate the padding. For the X, we need to allow the thumb to//draw in its extra space //main is the x axis above the change canvas.translate (mpaddingleft -Mthumboffset, mpaddingtop); Draw some canvas objects mthumb.draw (canvas); Canvas.restore (); } }
We know that the position of the slider will continue to shift with progress, and the nature of the drawing actually takes advantage of canvas class canvas, so essentially the canvas is constantly shifting. That's what this line of code means:
Canvas.translate (Mpaddingleft-mthumboffset, mpaddingtop);
The following is mainly to explain how Absseekbar is handling touch events, and I said above the NetEase cloud Music If you do click Progress bar to achieve the effect of playback and pause is also related to the following explanation:
As above, let's start with the code:
public boolean ontouchevent (Motionevent event) { if (!misuserseekable | |!isenabled ()) {return FAL Se } switch (Event.getaction ()) {Case MotionEvent.ACTION_DOWN:if (Isinscrollingcontainer () ) {Mtouchdownx = Event.getx (); } else {//sets the current state to be in the pressed state setpressed (true); if (mthumb! = null) {invalidate (Mthumb.getbounds ());//This could be within the padding region } onstarttrackingtouch (); Tracktouchevent (event); Attemptclaimdrag (); } break; Case MotionEvent.ACTION_MOVE:if (misdragging) {tracktouchevent (event); } else {final float x = Event.getx (); More than a certain state if (Math.Abs (X-MTOUCHDOWNX) >Mscaledtouchslop) {setpressed (true); if (mthumb! = null) {invalidate (Mthumb.getbounds ());//This could be within the padding region } onstarttrackingtouch (); Tracktouchevent (event); Attemptclaimdrag (); }} break; Case MotionEvent.ACTION_UP:if (misdragging) {tracktouchevent (event); Onstoptrackingtouch (); Setpressed (FALSE); } else {//touch up if we never crossed the touch slop threshold should//BE int Erpreted as a tap-seek to the location. Onstarttrackingtouch (); Tracktouchevent (event); Onstoptrackingtouch (); }//ProgressBar doesn ' t know to repaint The Thumb drawable//In it inactive state while the touch stops (because the//value has Not apparently changed) invalidate (); Break Case MotionEvent.ACTION_CANCEL:if (misdragging) {Onstoptrackingtouch (); Setpressed (FALSE); } invalidate (); See above explanation break; } return true; }
The above code, you crossing don't worry, and listen to the next one:
1, if the current Seekbar has been set to not be able to touch operation, nonsense needless to say, direct return.
2, according to the interpretation of the source code, when the current control is in the state of being pressed, mainly for the following processing:
2, 1 sets the current state for the state of the press
2, 2 refresh the current view
If we need to imitate NetEase cloud music, we need to deal with the logic of pause music,
Two points to note
1, determine whether the current event x coordinates are within the slider, if so, regardless of the current displacement is how much, do not change the current progress
2. Modify the picture of the current slider
Well, the whole source of the explanation is here, I believe you see here, on the Android Seekbar has a better understanding than before! No thanks, just call me fat brother. Good bye
A glimpse of the seekbar of the Android slider bar Absseekbar The source of the parent class