Android to create cool movie tickets online selection of the app online selection function _android

Source: Internet
Author: User
Tags abs ticket

I don't know if you've used it, Taobao movie client (Amoy ticket) bought movie tickets, overview of various types of online choice of app online selection function Taobao online function of the best user experience, use up the most convenient, exaggerated point said has reached the degree of perfection, the following we look at the effect:

Effect Analysis:

The entire control is divided into sections, seating chart area, seat thumbnail area, line number area, screen area

1, the seating chart can move the scale freely, enlarges reduces moves after will automatically rebound to the suitable position, the selected seat will enlarge automatically to the suitable proportion.

2, the line number part follows the seating chart scaling and moves up and down, the screen area follows the seat chart to move the scale.

3. When the finger is pressed, a thumbnail appears, and a red box on the thumbnail shows the area that is currently visible and follows the thumbnail movement.

The knowledge points involved:

View drawing principle, event distribution mechanism These are not said, these are the basis, here is not intended to introduce, the Internet has a lot of this information.

1, matrix for the use of matrices to move, zoom

2, elastic movement, elastic scaling.

3, the use of gesture monitoring through gesturedetector, scalegesturedetector to obtain a scaling scale.

Coding implementation

Through the following core sections to introduce, the other parts are similar ideas to achieve

1. Draw the seating chart

2, the seating chart scaling and moving

3, seat chart automatic rebound, automatic scaling

4, the thumbnail part of the drawing implementation

As for the other parts, such as the cinema screen, the left-hand line part of the train of thought and seating chart to achieve the idea is consistent.

1. Draw the seating chart

The seating chart is actually a two-dimensional matrix, with rows and columns, and we just need to draw a certain amount of spacing based on the number of rows and columns.

void Drawseat () {for
(int i = 0; i < row; i++) {for
(int j = 0; j < column; J +) {
int left = J * Seat Bitmap.getwidth () + j * Spacing;
int top = i * seatbitmap.getheight () + i * verspacing;
int seattype = Getseattype (i, j);
Switch (seattype) {case
seat_type_available:
seatcanvas.drawbitmap (Seatbitmap, left, top, paint);
break;
Case seat_type_not_available: Break
;
Case seat_type_selected:
seatcanvas.drawbitmap (Checkedseatbitmap, left, top, paint);
break;
Case Seat_type_sold:
seatcanvas.drawbitmap (Seatsoldbitmap, left, top, paint);
break;
}
}} Isneeddrawseatbitmap = false;
}

The Getseattype () method is used to determine whether the current seat is available, whether it has been sold, whether it has been selected, and to draw a different seating chart according to these states.

2, the seating chart scaling and moving

The move zoom feature is implemented using Matirx, which can be used to zoom, move, rotate, and so on in Android.
The matrix itself is a 3*3, and each value in the matrix represents a transformation attribute, as follows

mscale_x mskew_x mtrans_x 
mskew_y mscale_y mtrans_y mpersp_0 mpersp_1 mpersp_2 

is actually an array of 9 elements.

 
 

A specific value can be obtained by matrix.getvalues (value).

Value[0] Represents the scaled X value

Value[1] Represents a chamfered x value

VALUE[2] Represents the value translated on the x-axis

Value[3] Represents a chamfered y-value

Value[4] Represents the scaling on the Y axis

VALUE[5] Represents the value of a translation on the Y axis

Matrix class There are ways to change these values

Setscale (float sx, float sy, float px, float py): Sets the scaling ratio on the x and Y weeks, px,py The center point of the zoom.

Settranslate (float dx, float dy): Sets the offset on the x-axis and Y-week.

There are two other ways to do this:

Postscale (float sx, float sy, float px, float py) 

So what's the difference between a post and a set, a simple understanding is set directly, overwriting the previous value, and the post is transformed based on the previous value. For example, now that you have moved 10 pixels to the left, you are using Settranslate (5,5) to move directly to 5 pixels, and the post is 10 on the basis of moving 5 pixels into 15.

These are the methods used by the matrix, and the canvas object has a Drawbitmap method to receive a matrix so that it can be transformed using the matrix when drawing.

The way to realize the translation and scaling of seating chart:

Two things to do to achieve the zoom of the seating chart move

1, get the translation of the value and zoom out of proportion

Rewrite the Ontouchevent method to calculate the x and Y values for the move

Use the Scalegesturedetector class to help us get the magnification scale, use it very simply, create a Scalegesturedetector object, Then in the Ontouchevent method call the Scalegesturedetector.ontouchevent (event);

2. Translate and scale the seating chart according to the acquired value

After you get the value of the translation and the scaling ratio, use Matrix.postscale (x,y) and Matrix.posttrans (x,y) for the corresponding transformation, The Invalidate method that calls view is changed to make the view redraw the matrix to take effect.

Only the core code is listed below, and some logic is omitted, and the complete code is viewed in GitHub.

Scalegesturedetector scalegesturedetector = new Scalegesturedetector (GetContext (), New Scalegesturedetector.onscalegesturelistener () {
@Override public
boolean Onscale (scalegesturedetector detector) {
float scalefactor = Detector.getscalefactor ();
Matrix.postscale (Scalefactor, Scalefactor, ScaleX, ScaleY);
Invalidate ();
return true;
}
});

Ontouchevent processing Logic

@Override Public
Boolean ontouchevent (Motionevent event) {
int y = (int) event.gety ();
int x = (int) event.getx ();
Scalegesturedetector.ontouchevent (event);
Switch (event.getaction ()) {case
motionevent.action_down:
downx = x;
DownY = y; 
break;
Case motionevent.action_move:
int downdx = Math.Abs (X-DOWNX);
int downdy = Math.Abs (y-downy);
if (Downdx > | | | downdy >) {
int dx = X-LASTX;
int dy = y-lasty;
Matrix.posttranslate (dx, dy);
Invalidate ();
}
break;
Case MOTIONEVENT.ACTION_UP: .....
break;
Lasty = y;
LASTX = x;
return true;
}

When OnDraw.

@Override
protected void OnDraw (Canvas Canvas) {
...
.. Canvas.drawbitmap (seat, Matrix, paint);
.....
}

3, the seat chart automatic rebound, the realization of automatic scaling effect

Why to automatically rebound it, because you are operating when it is possible to move the seat map to the screen, zoom when the figure scaling smaller, or relatively large, this time the program through the calculation to you automatically move to a more appropriate position, the more appropriate shrinkage amplification small. This is a good experience to use.

The idea of automatic rebound realization:

When we move the finger on the screen and then lift the Motionevent.action_up event, this time we can get the current moving position through the matrix object, if the current moving value does not conform to our rules, we will move the seating chart to the specified position according to the rules.

Move the rules as follows (refer to the Amoy ticket client's mobile logic)

When the entire size of the seating chart does not exceed the size of the control:

Slide to the left, automatically bounce back to the line number to the right

Slide to the right and automatically bounce back to the right.

Go up, slide, bounce back to the top

When the entire size of the seating chart exceeds the size of the control:

Slide to the left, bounce back to the right, slide back to the right and bounce to the left.

Slide up, rebound to the bottom, slide back up to the top

The implementation of the above mobile rules you can see the specific source of the AutoScroll () method of implementation, here is not posted.

Moving and scaling involves an elastic movement and scaling problem, and the so-called elastic Movement is the movement of the animation effect. Because if you are currently in the position of 100,100, you need to move to 800,100 this position, if you move directly to 800 of this position, instead of passing, first move to 110, before moving to 120 ... All the way up to 800 for such a period of movement. Then the moving effect will be very stiff, brush the flash of the past feeling, the effect is very bad.

The idea of elastic movement is:

For example, to move from 100,100 to 800,100, it's clear that the x-axis is going to move 700 pixels. So the 700 pixel of the move we split into 10 times to achieve, each move 700/10=70 pixels, two times between the interval of 50 milliseconds, like the frame animation, so there will be a flexible animation effect.

The following code is implemented by handler:

int frame_count = ten;
int time =;
int count;
Handler Handler = new Handler (new Handler.callback () {
@Override public
boolean handlemessage (msg) {
if (Count < Frame_count) {
count++;
Moveinfo Moveinfo = (moveinfo) msg.obj;
float movexlength = moveinfo.movexlength;
float moveylength = moveinfo.moveylength;
float xvalue = movexlength/frame_count;
float yvalue = moveylength/frame_count;
Matrix.posttranslate (Xvalue, yvalue);
Invalidate ();
Message message = Message.obtain ();
Message.obj = msg.obj;
Loop call
handler.sendmessagedelayed (message, time);
} else {
count = 0;
}
return true;
}

The principle of elastic scaling is consistent with the principle of elastic movement.

4, the thumbnail part of the drawing implementation

Thumbnail is a smaller version of the seating chart, the width of the thumbnail and the height of the seating chart is a certain proportion, such as one-fifth. Of course, this can be adjusted according to the effect. It must be a percentage of the seating chart because there is a dynamic red box on the thumbnail that represents the currently visible seating area, and the red box needs to be moved according to the seating chart. After the ratio is determined, this can move the red box according to the movement of the seating chart. For example-if the current seating chart moves 100 pixels up, the corresponding red box portion of the thumbnail moves down 100/4=250 pixels.

To draw an overview diagram code:

Bitmap Drawoverview () {//Calculate the square width, height/rule of seats on the overview chart: Seating width/scaling ratio float rectsize = seatbitmap.getheight ()/Overviewsca
Le
Calculate the width and height of the overview chart rectw = column * rectwidth + (column-1) * overviewspacing + overviewspacing * 2;
RECTH = row * rectsize + (row-1) * overviewverspacing + overviewverspacing * 2;
Canvas Canvas = new Canvas (OVERVIEWBITMAP);
Draw Transparent gray background canvas.drawrect (0, 0, rectw, RECTH, paint);
Paint.setcolor (Color.White);  Loop draw for (int i = 0; i < row; i++) {Float top = i * rectsize + i * overviewverspacing + overviewverspacing; j = 0; J < column; J + +) {//Get seat What status has been sold, unchecked, already selected int seattype = Getseattype (i, j); switch (seattype) {case SEAT_TYPE_AVAILABLE:paint.set
Color (Color.White);
Break
Case Seat_type_not_available:continue;
Case SEAT_TYPE_SELECTED:paint.setColor (overview_checked);
Break
Case SEAT_TYPE_SOLD:paint.setColor (Overview_sold);
Break
} float left;
left = J * Rectwidth + J * overviewspacing + overviewspacing; Canvas.drawrect (left, top, left + rectwidth, top + rectsize, paint);
} return Overviewbitmap; }

Draw a red box on the overview map

/** * Draw Overview map/void Drawoverviewborder (Canvas Canvas) {//Draw red box int left = (int)-gettranslatex ();//get the translation position on the x axis of the current seating chart if (L) EFT < 0) {left = 0;} left/= Overviewscale; Overviewscale represents the ratio of the overview figure to the seating chart left/= Getmatrixscalex ();//getmatrixscalex () Gets the scaling ratio of the current seating chart//Determines whether the current seating chart is wider than the width of the entire control. If it is exceeded, then the excess is not visible.
A red box that represents the position you are currently able to see will not be able to bring in the boxes that are out of bounds. int currentwidth = (int) (Gettranslatex () + (column * Seatbitmap.getwidth () + spacing * (column-1)) * Getmatrixscalex ())
; if (Currentwidth > GetWidth ()) {currentwidth = Currentwidth-getwidth ();} else {currentwidth = 0;} int right = (in
T) (Rectw-currentwidth/overviewscale/getmatrixscalex ());
float top =-gettranslatey () +headheight;
if (Top < 0) {top = 0;} top/= Overviewscale;
Top/= Getmatrixscaley (); if (Top > 0) {top = overviewverspacing}//Determines whether the width of the current seating chart exceeds the height of the entire control, if it is exceeded, the excess portion is not visible.
A red box that represents the position you are currently able to see will not be able to bring in the boxes that are out of bounds. 
int currentheight = (int) (Gettranslatey () + (Row * seatbitmap.getheight () + verspacing * (row-1)) * Getmatrixscaley ());if (Currentheight > GetHeight ()) {currentheight = Currentheight-getheight ();} else {currentheight = 0;} int Botto
m = (int) (Recth-currentheight/overviewscale/getmatrixscaley ());
Canvas.drawrect (left, top, right, bottom, redborderpaint); }

Control performance Optimization

Painstakingly finally put the control to make, the result of a running card do not want. In particular, the number of rows in the series, Cotton's Meng force. This time we have to optimize the performance, summed up from the following aspects:

1. Avoid creating objects in OnDraw, allocating memory, and putting the creation of paint objects in the initialization function. This step is really important because when we use canvas drawing we need paint objects, often different places need different paint, so we create more paint objects, and the OnDraw method may be executed multiple times. Frequent creation of objects can result in a GC, resulting in Carrington. Of course, more than just paint objects, other objects can be created less.

2, to avoid unnecessary drawing logic, when needed to draw. This needs to be adjusted based on the control's drawing logic, which is also very important.

3, the general principle is to do everything possible to control the implementation of the OnDraw method within 16ms, will not be card.

Finally, look at the effect we've achieved.

Source Address:

GitHub Address

The above is a small set to introduce Android to create cool movie tickets online selection of apps online function, hope to help everyone, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

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.