Android,시 크 한 영화 표 만 들 기 온라인 좌석 선택 app 온라인 좌석 선택 기능

여러분 이 사용 해 보 셨 는 지 모 르 겠 습 니 다.타 오 바 오 영화 클 라 이언 트(타 오 바 오 표)가 영화 표를 산 적 이 있 습 니 다.각종 온라인 좌석 선택 app 의 온라인 좌석 선택 기능 을 살 펴 보면 타 오 바 오 온라인 좌석 선택 기능 의 사용자 체험 이 가장 좋 습 니 다.사용 하기에 가장 편리 합 니 다.과장 되 게 말 하면 이미 최고의 수준 에 이 르 렀 습 니 다.다음은 효 과 를 보 겠 습 니 다.
这里写图片描述
효과 분석:
전체 컨트롤 은 좌석 그림 영역,좌석 미리 보기 그림 영역,줄 번호 영역,화면 영역 으로 나 뉜 다.
1.좌석 도 는 자 유 롭 게 이동 할 수 있 고 확대 축소 이동 후 자동 으로 적당 한 위치 로 되 돌아 가 며 선택 한 좌석 은 자동 으로 적당 한 비율 로 확 대 됩 니 다.
2.줄 번호 부분 은 좌석도 의 크기 조정 과 상하 이동,화면 영역 은 좌석도 의 좌우 이동 에 따라 크기 를 조정 합 니 다.
3.손가락 을 눌 렀 을 때 미리 보기 그림 이 나타 납 니 다.미리 보기 그림 에 빨간색 사각형 이 있 습 니 다.현재 볼 수 있 는 영역 을 표시 하고 미리 보기 그림 을 따라 이동 합 니 다.
관련 된 지식 포인트:
view 의 그리 기 원리,사건 분배 메커니즘 등 은 말 하지 않 겠 습 니 다.이것들 은 기초 입 니 다.여 기 는 소개 할 생각 이 없습니다.인터넷 에는 이 방면 의 자료 가 매우 많 습 니 다.
1.매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스 매트릭스
2.신축성 이동,신축성 확대.
3.제스처 감청 의 사용 은 Gesture Detector,Scale Gesture Detector 를 통 해 크기 조정 비례 폭 을 얻 을 수 있 습 니 다.
인 코딩 구현
다음 과 같은 몇 가지 핵심 부분 을 통 해 소개 하면 다른 부분 은 모두 비슷 한 사고 로 이 루어 진다.
1.좌석 도 그리 기
2.좌석도 의 크기 조정 과 이동
3.좌석 도 자동 재생,자동 크기 조정
4.미리 보기 그림 부분의 그리 기 실현
다른 부분,예 를 들 어 영화관 스크린,왼쪽 줄 번호 부분의 사고방식 은 좌석 도 실현 사고방식 과 일치한다.
1.좌석 도 그리 기
좌석 도 는 실제 적 으로 2 차원 행렬 로 줄 수 와 열 수가 있 습 니 다.우 리 는 줄 수 와 열 수 에 따라 일정한 간격 을 더 해서 그리 면 됩 니 다.

void drawSeat() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
int left = j * seatBitmap.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;
}
getseat Type()방법 은 현재 좌석 이 사용 가능 한 지,이미 팔 렸 는 지,선택 되 었 는 지,이 상태 에 따라 좌석 도 를 그립 니 다.
2.좌석도 의 크기 조정 과 이동
이동 크기 조정 기능 은 Matirx 를 사용 하여 이 루어 집 니 다.Matrix 는 안 드 로 이 드 에서 그림 의 크기 조정,이동,회전 등 변환 을 할 수 있 습 니 다.
matrix 자 체 는 3*3 의 행렬 이 고 행렬 의 모든 값 은 하나의 변환 속성 을 대표 합 니 다.다음 과 같 습 니 다.

MSCALE_X MSKEW_X MTRANS_X 
MSKEW_Y MSCALE_Y MTRANS_Y 
MPERSP_0 MPERSP_1 MPERSP_2
실제로 9 개의 요소 가 있 는 배열 이다.

float[] value=new float[9]; 
matrix.getValues(value)를 통 해;구체 적 인 값 을 얻 을 수 있 습 니 다.
value[0]는 크기 조정 x 값 을 표시 합 니 다.
value[1]는 비스듬히 자 른 x 값 을 나타 낸다.
value[2]는 x 축 에서 이동 하 는 값 을 나타 낸다.
value[3]는 비스듬히 자 른 y 값 을 나타 낸다.
value[4]가 표시 하 는 y 축의 크기 조정 비율
value[5]는 y 축의 이동 값 을 나타 낸다.
Matrix 클래스 는 이 값 을 바 꿀 수 있 는 방법 이 있 습 니 다.
setScale(float sx,float sy,float px,float py):x 축 과 y 주의 크기 조정 비율 을 설정 하고 px,py 는 크기 조정 중심 점 을 표시 합 니 다.
setTranslate(float dx,float dy):x 축 과 y 주 상의 오프셋 을 설정 합 니 다.
이에 대응 하 는 두 가지 방법 이 있다.

postScale(float sx, float sy, float px, float py) 
postTranslate(float dx, float dy) 
그러면 post 와 set 는 어떤 차이 가 있 습 니까?간단하게 이해 하면 set 입 니 다.이전의 값 을 덮어 쓰 고 post 는 이전의 값 을 바탕 으로 변환 합 니 다.예 를 들 어 지금 은 10 개의 픽 셀 을 왼쪽으로 이동 하 였 습 니 다.이때 setTranslate(5,5)를 사용 하면 5 개의 픽 셀 을 이동 하 는 것 이 되 었 습 니 다.post 를 사용 하면 10 을 바탕 으로 5 개의 픽 셀 을 이동 하면 15 가 됩 니 다.
이상 은 Matrix 의 사용 방법 입 니 다.Canvas 대상 은 drawBitmap 방법 으로 matrix 를 받 을 수 있 습 니 다.그림 을 그 릴 때 matrix 를 사용 하여 변환 할 수 있 습 니 다.
좌석 도 이동 크기 조정 실현 방향:
좌석 도 크기 조정 이동 을 위해 서 두 가지 일 을 해 야 합 니 다.
1.이동 하 는 값 을 가 져 오고 축소 하 는 비율 을 확대 합 니 다.
onTouchEvent 방법 을 다시 써 서 이동 하 는 x 값 과 y 값 을 계산 합 니 다.
Scale Gesture Detector 라 는 종 류 를 사용 하여 확대 축소 비율 을 가 져 옵 니 다.아주 간단 합 니 다.Scale Gesture Detector 의 대상 을 만 든 다음 onTouchEvent 방법 에서 Scale Gesture Detector.onTouchEvent(event)를 호출 합 니 다....하면 된다
2.가 져 온 값 에 따라 좌석 도 를 이동 하고 크기 조정 합 니 다.
이동 하 는 값 과 크기 조정 비율 을 가 져 온 후,matrix.postScale(x,y)과 matrix.postTrans(x,y)를 사용 하여 대응 하 는 변환 을 하면 됩 니 다.view 를 호출 하 는 invalidate 방법 을 바 꾸 어 view 가 matrix 를 다시 그리 면 유효 합 니 다.
다음은 핵심 코드 만 열거 하고 논 리 를 줄 였 습 니 다.전체 코드 는 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 처리 논리

@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 > 10 || downDY > 10) {
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;
}
onDraw 때.

@Override
protected void onDraw(Canvas canvas) {
.....
canvas.drawBitmap(seat, matrix, paint);
.....
}
3.좌석 그림 의 자동 리 턴,자동 크기 조정 효과 의 실현
왜 자동 으로 튕 겨 야 합 니까?왜냐하면 당신 이 조작 할 때 좌석 도 를 화면 밖으로 옮 길 수 있 기 때 문 입 니 다.크기 를 조정 할 때 그림 을 비교적 작 게 조정 하거나 비교적 크게 조정 할 수 있 기 때 문 입 니 다.이 때 프로그램 은 계산 을 통 해 비교적 적합 한 위치 로 자동 으로 이동 할 수 있 고 적당 한 크기 를 줄 일 수 있 습 니 다.이렇게 하면 좋 은 사용 체험 을 할 수 있다.
자동 리 턴 실현 의 사고:
저희 가 손가락 화면 을 움 직 이 고 들 면 MotionEvent.ACTION 이 울 려 요.UP 이벤트,이 때 우 리 는 matrix 대상 을 통 해 현재 이동 하 는 위 치 를 얻 을 수 있 습 니 다.현재 이동 하 는 값 이 우리 의 규칙 에 부합 되 지 않 으 면 좌석 도 를 규칙 에 따라 지정 한 위치 로 이동 합 니 다.
이동 규칙 은 다음 과 같다.
좌석 도 전체 크기 가 컨트롤 크기 를 초과 하지 않 을 때:
왼쪽으로 미 끄 러 지면 자동 으로 줄 번호 오른쪽으로 되 돌아 갑 니 다.
오른쪽으로 미 끄 러 지면 자동 으로 오른쪽으로 되 돌아 갑 니 다.
위로,아래로 미 끄 러 지면 자동 으로 상단 으로 튕 겨 집 니 다.
좌석 도 전체 크기 가 컨트롤 크기 를 초과 할 때:
왼쪽으로 미 끄 러 지고 맨 오른쪽 으로 튕 기 고 오른쪽 으로 미 끄 러 지 며 맨 왼쪽 으로 튕 깁 니 다.
위로 미 끄 러 지고 끝까지 튕 기 고 아래로 미 끄 러 지 며 꼭대기 까지 튕 깁 니 다.
이상 의 모 바 일 규칙 의 실현 은 구체 적 인 소스 코드 중의 autoScroll()방법의 실현 을 볼 수 있 습 니 다.여 기 는 붙 이지 않 습 니 다.
이동 과 크기 조정 은 탄력 적 인 이동 과 크기 조정 문제 와 관련 되 는데 탄력 적 인 이동 이란 애니메이션 효과 가 있 는 이동 입 니 다.만약 당신 이 현재 100,100 이 위치 에 있다 면,당신 은 800,100 이 위치 로 이동 해 야 합 니 다.만약 당신 이 통과 하 는 것 이 아니 라,110 으로 이동 하고,120 으로 이동 해 야 하기 때 문 입 니 다.800 까지 한 단락 한 단락 이동 하 다.그러면 이동 효 과 는 매우 경직 되 고 스 쳐 지나 가 는 느낌 으로 효과 가 매우 좋 지 않다.
탄성 이동 의 실현 방향 은 바로:
예 를 들 어 100,100 에서 800,100 으로 이동 하려 면 x 축 이 700 개의 픽 셀 을 이동 해 야 한 다 는 것 이 분명 하 다.그러면 이 700 개의 픽 셀 의 이동 을 우 리 는 10 번 으로 나 누 어 실현 합 니 다.매번 700/10=70 개의 픽 셀 을 이동 할 때마다 두 번 의 이동 사이 에 50 밀리초 간격 을 두 면 프레임 애니메이션 처럼 탄력 적 인 애니메이션 효 과 를 얻 을 수 있 습 니 다.
handler 를 통 해 코드 를 다음 과 같이 실현 합 니 다.

int FRAME_COUNT = 10;
int time = 15;
int count;
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message 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;
//    
handler.sendMessageDelayed(message, time);
} else {
count = 0;
}
return true;
}
탄성 크기 의 원 리 는 탄성 이동 의 원리 와 일치한다.
4.미리 보기 그림 부분의 그리 기 실현
미리 보기 그림 은 좌석 그림 의 축소판 으로 미리 보기 그림 의 너비 와 좌석 그림 의 너비 와 높이 는 일정한 비례 가 있다.예 를 들 어 5 분 의 1 이다.물론 효과 에 따라 조정 할 수 있다.좌석 그림 의 일정한 비율 이 어야 하 는 이 유 는 미리 보기 그림 에 현재 보 이 는 좌석 구역 을 나타 내 는 동적 인 빨간색 사각형 이 있 기 때 문 입 니 다.이 빨간색 사각형 은 좌석 그림 의 이동 에 따라 이동 해 야 합 니 다.비례 가 확정 되면 좌석 도 이동 에 따라 빨간색 사각형 을 이동 할 수 있다.예 를 들 어 현재 좌석 도가 100 개의 픽 셀 을 위로 이동 하면 미리 보기 그림 에 대응 하 는 빨간색 사각형 부분 을 100/4=250 개의 픽 셀 로 아래로 이동 하면 됩 니 다.
개관 도 코드 그리 기:

Bitmap drawOverview() {
//                、   
//   :         /    
float rectSize = seatBitmap.getHeight() / overviewScale;
//            
rectW = column * rectWidth + (column - 1) * overviewSpacing + overviewSpacing * 2;
rectH = row * rectSize + (row - 1) * overviewVerSpacing + overviewVerSpacing * 2;
Canvas canvas = new Canvas(overviewBitmap);
//        
canvas.drawRect(0, 0, rectW, rectH, paint);
paint.setColor(Color.WHITE);
//    
for (int i = 0; i < row; i++) {
float top = i * rectSize + i * overviewVerSpacing + overviewVerSpacing;
for (int j = 0; j < column; j++) {
//              、   、    
int seatType = getSeatType(i, j);
switch (seatType) {
case SEAT_TYPE_AVAILABLE:
paint.setColor(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;
}
개관 도 에 있 는 빨간색 사각형 그리 기

/**
*      
*/
void drawOverviewBorder(Canvas canvas) {
//     
int left = (int) -getTranslateX();//       x       
if (left < 0) {
left = 0;
}
left /= overviewScale; //overviewScale             
left /= getMatrixScaleX();//getMatrixScaleX()             
//                      ,     ,           。                           。
int currentWidth = (int) (getTranslateX() + (column * seatBitmap.getWidth() + spacing * (column - 1)) * getMatrixScaleX());
if (currentWidth > getWidth()) {
currentWidth = currentWidth - getWidth();
} else {
currentWidth = 0;
}
int right = (int) (rectW - currentWidth / overviewScale / getMatrixScaleX());
float top = -getTranslateY()+headHeight;
if (top < 0) {
top = 0;
}
top /= overviewScale;
top /= getMatrixScaleY();
if (top > 0) {
top += overviewVerSpacing;
}
//                      ,     ,           。                           。
int currentHeight = (int) (getTranslateY() + (row * seatBitmap.getHeight() + verSpacing * (row - 1)) * getMatrixScaleY());
if (currentHeight > getHeight()) {
currentHeight = currentHeight - getHeight();
} else {
currentHeight = 0;
}
int bottom = (int) (rectH - currentHeight / overviewScale / getMatrixScaleY());
canvas.drawRect(left, top, right, bottom, redBorderPaint);
}
컨트롤 성능 최적화
천신만고 끝 에 컨트롤 을 만 들 었 더 니 카드 가 꺼 지지 않 았 다.특히 행 수열 이 많아 서 카드 가 멍 해 졌 다.이때 우 리 는 성능 을 최적화 시 켜 야 한다.정리 해 보면 주로 다음 과 같은 몇 가지 측면 에서
1.onDraw 에서 대상 을 만 들 지 않 고 메모 리 를 분배 하 며 paint 대상 의 생 성 을 초기 화 함수 에 넣 습 니 다.이 단 계 는 사실 매우 중요 합 니 다.왜냐하면 우 리 는 canvas 를 사용 하여 그림 을 그 릴 때 paint 대상 이 필요 하기 때 문 입 니 다.서로 다른 곳 에 서로 다른 paint 가 필요 하기 때 문 입 니 다.그러면 만 든 paint 대상 이 비교적 많 습 니 다.게다가 onDraw 방법 은 여러 번 실 행 될 수 있 습 니 다.잦 은 생 성 대상 은 gc 로 인해 렉 이 발생 합 니 다.물론 paint 대상 뿐만 아니 라 다른 대상 도 적 게 만 들 수 있어 야 합 니 다.
2.불필요 한 논리 그리 기 를 피하 고 필요 할 때 만 그립 니 다.이것 은 우리 가 컨트롤 의 그리 기 논리 에 따라 조정 해 야 하 는 것 도 매우 중요 하 다.
3.전체적인 원칙 은 모든 방법 을 다 강구 하여 onDraw 방법의 집행 을 16ms 이내 로 통제 하면 끊 기지 않 는 다 는 것 이다.
마지막 으로 저희 가 이 룬 효 과 를 보 겠 습 니 다.
这里写图片描述
원본 주소:
github 주소
위 에서 말 한 것 은 편집장 이 소개 한 안 드 로 이 드 가 멋 진 영화 표 온라인 좌석 선택 app 온라인 좌석 선택 기능 을 만 드 는 것 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 은 신속하게 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기