Android影院选座
生活随笔
收集整理的這篇文章主要介紹了
Android影院选座
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先先看一下效果圖
這里只是簡單的實現了這個效果,具體的思路以及知識點我個人還是不怎么理解下面的倆個連接多看一下
https://www.cnblogs.com/itgungnir/p/6217447.html?tdsourcetag=s_pcqq_aiomsg
https://blog.csdn.net/lmj623565791/article/details/45022631/
第一步:
寫自定義view的類
public class SeatTable extends View {private final boolean DBG = false;Paint paint = new Paint();Paint overviewPaint=new Paint();Paint lineNumberPaint;float lineNumberTxtHeight;/*** 設置行號 默認顯示 1,2,3....數字* @param lineNumbers*/public void setLineNumbers(ArrayList<String> lineNumbers) {this.lineNumbers = lineNumbers;invalidate();}/*** 用來保存所有行號*/ArrayList<String> lineNumbers = new ArrayList<>();Paint.FontMetrics lineNumberPaintFontMetrics;Matrix matrix = new Matrix();/*** 座位水平間距*/int spacing;/*** 座位垂直間距*/int verSpacing;/*** 行號寬度*/int numberWidth;/*** 行數*/int row;/*** 列數*/int column;/*** 可選時座位的圖片*/Bitmap seatBitmap;/*** 選中時座位的圖片*/Bitmap checkedSeatBitmap;/*** 座位已經售出時的圖片*/Bitmap seatSoldBitmap;Bitmap overviewBitmap;int lastX;int lastY;/*** 整個座位圖的寬度*/int seatBitmapWidth;/*** 整個座位圖的高度*/int seatBitmapHeight;/*** 標識是否需要繪制座位圖*/boolean isNeedDrawSeatBitmap = true;/*** 概覽圖白色方塊高度*/float rectHeight;/*** 概覽圖白色方塊的寬度*/float rectWidth;/*** 概覽圖上方塊的水平間距*/float overviewSpacing;/*** 概覽圖上方塊的垂直間距*/float overviewVerSpacing;/*** 概覽圖的比例*/float overviewScale = 4.8f;/*** 熒幕高度*/float screenHeight;/*** 熒幕默認寬度與座位圖的比例*/float screenWidthScale = 0.5f;/*** 熒幕最小寬度*/int defaultScreenWidth;/*** 標識是否正在縮放*/boolean isScaling;float scaleX, scaleY;/*** 是否是第一次縮放*/boolean firstScale = true;/*** 最多可以選擇的座位數量*/int maxSelected = Integer.MAX_VALUE;private SeatChecker seatChecker;/*** 熒幕名稱*/private String screenName = "";/*** 整個概覽圖的寬度*/float rectW;/*** 整個概覽圖的高度*/float rectH;Paint headPaint;Bitmap headBitmap;/*** 是否第一次執行onDraw*/boolean isFirstDraw = true;/*** 標識是否需要繪制概覽圖*/boolean isDrawOverview = false;/*** 標識是否需要更新概覽圖*/boolean isDrawOverviewBitmap = true;int overview_checked;int overview_sold;int txt_color;int seatCheckedResID;int seatSoldResID;int seatAvailableResID;boolean isOnClick;/*** 座位已售*/private static final int SEAT_TYPE_SOLD = 1;/*** 座位已經選中*/private static final int SEAT_TYPE_SELECTED = 2;/*** 座位可選*/private static final int SEAT_TYPE_AVAILABLE = 3;/*** 座位不可用*/private static final int SEAT_TYPE_NOT_AVAILABLE = 4;private int downX, downY;private boolean pointer;/*** 頂部高度,可選,已選,已售區域的高度*/float headHeight;Paint pathPaint;RectF rectF;/*** 頭部下面橫線的高度*/int borderHeight = 1;Paint redBorderPaint;/*** 默認的座位圖寬度,如果使用的自己的座位圖片比這個尺寸大或者小,會縮放到這個大小*/private float defaultImgW = 40;/*** 默認的座位圖高度*/private float defaultImgH = 34;/*** 座位圖片的寬度*/private int seatWidth;/*** 座位圖片的高度*/private int seatHeight;public SeatTable(Context context) {super(context);}public SeatTable(Context context, AttributeSet attrs) {super(context, attrs);init(context,attrs);}private void init(Context context,AttributeSet attrs){TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.styleable);overview_checked = typedArray.getColor(R.styleable.styleable_overview_checked, Color.parseColor("#5A9E64"));overview_sold = typedArray.getColor(R.styleable.styleable_overview_sold, Color.RED);txt_color=typedArray.getColor(R.styleable.styleable_txt_color,Color.WHITE);seatCheckedResID = typedArray.getResourceId(R.styleable.styleable_seat_checked, R.drawable.seat_gray);seatSoldResID = typedArray.getResourceId(R.styleable.styleable_overview_sold, R.drawable.sold);seatAvailableResID = typedArray.getResourceId(R.styleable.styleable_seat_available, R.drawable.seat_green);typedArray.recycle();}public SeatTable(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context,attrs);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}float xScale1 = 1;float yScale1 = 1;private void init() {spacing = (int) dip2Px(5);verSpacing = (int) dip2Px(10);defaultScreenWidth = (int) dip2Px(80);seatBitmap = BitmapFactory.decodeResource(getResources(), seatAvailableResID);float scaleX = defaultImgW / seatBitmap.getWidth();float scaleY = defaultImgH / seatBitmap.getHeight();xScale1 = scaleX;yScale1 = scaleY;seatHeight= (int) (seatBitmap.getHeight()*yScale1);seatWidth= (int) (seatBitmap.getWidth()*xScale1);checkedSeatBitmap = BitmapFactory.decodeResource(getResources(), seatCheckedResID);seatSoldBitmap = BitmapFactory.decodeResource(getResources(), seatSoldResID);seatBitmapWidth = (int) (column * seatBitmap.getWidth()*xScale1 + (column - 1) * spacing);seatBitmapHeight = (int) (row * seatBitmap.getHeight()*yScale1 + (row - 1) * verSpacing);paint.setColor(Color.RED);numberWidth = (int) dip2Px(20);screenHeight = dip2Px(20);headHeight = dip2Px(30);headPaint = new Paint();headPaint.setStyle(Paint.Style.FILL);headPaint.setTextSize(24);headPaint.setColor(Color.WHITE);headPaint.setAntiAlias(true);pathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);pathPaint.setStyle(Paint.Style.FILL);pathPaint.setColor(Color.parseColor("#e2e2e2"));redBorderPaint = new Paint();redBorderPaint.setAntiAlias(true);redBorderPaint.setColor(Color.RED);redBorderPaint.setStyle(Paint.Style.STROKE);redBorderPaint.setStrokeWidth(getResources().getDisplayMetrics().density * 1);rectF = new RectF();rectHeight = seatHeight / overviewScale;rectWidth = seatWidth / overviewScale;overviewSpacing = spacing / overviewScale;overviewVerSpacing = verSpacing / overviewScale;rectW = column * rectWidth + (column - 1) * overviewSpacing + overviewSpacing * 2;rectH = row * rectHeight + (row - 1) * overviewVerSpacing + overviewVerSpacing * 2;overviewBitmap = Bitmap.createBitmap((int) rectW, (int) rectH, Bitmap.Config.ARGB_4444);lineNumberPaint = new Paint(Paint.ANTI_ALIAS_FLAG);lineNumberPaint.setColor(bacColor);lineNumberPaint.setTextSize(getResources().getDisplayMetrics().density * 16);lineNumberTxtHeight = lineNumberPaint.measureText("4");lineNumberPaintFontMetrics = lineNumberPaint.getFontMetrics();lineNumberPaint.setTextAlign(Paint.Align.CENTER);if(lineNumbers==null){lineNumbers=new ArrayList<>();}else if(lineNumbers.size()<=0) {for (int i = 0; i < row; i++) {lineNumbers.add((i + 1) + "");}}matrix.postTranslate(numberWidth + spacing, headHeight + screenHeight + borderHeight + verSpacing);}@Overrideprotected void onDraw(Canvas canvas) {long startTime = System.currentTimeMillis();if (row <= 0 || column == 0) {return;}drawSeat(canvas);drawNumber(canvas);if (headBitmap == null) {headBitmap = drawHeadInfo();}canvas.drawBitmap(headBitmap, 0, 0, null);drawScreen(canvas);if (isDrawOverview) {long s = System.currentTimeMillis();if (isDrawOverviewBitmap) {drawOverview();}canvas.drawBitmap(overviewBitmap, 0, 0, null);drawOverview(canvas);Log.d("drawTime", "OverviewDrawTime:" + (System.currentTimeMillis() - s));}if (DBG) {long drawTime = System.currentTimeMillis() - startTime;Log.d("drawTime", "totalDrawTime:" + drawTime);}}@Overridepublic boolean onTouchEvent(MotionEvent event) {int y = (int) event.getY();int x = (int) event.getX();super.onTouchEvent(event);scaleGestureDetector.onTouchEvent(event);gestureDetector.onTouchEvent(event);int pointerCount = event.getPointerCount();if (pointerCount > 1) {pointer = true;}switch (event.getAction()) {case MotionEvent.ACTION_DOWN:pointer = false;downX = x;downY = y;isDrawOverview = true;handler.removeCallbacks(hideOverviewRunnable);invalidate();break;case MotionEvent.ACTION_MOVE:if (!isScaling && !isOnClick) {int downDX = Math.abs(x - downX);int downDY = Math.abs(y - downY);if ((downDX > 10 || downDY > 10) && !pointer) {int dx = x - lastX;int dy = y - lastY;matrix.postTranslate(dx, dy);invalidate();}}break;case MotionEvent.ACTION_UP:handler.postDelayed(hideOverviewRunnable, 1500);autoScale();int downDX = Math.abs(x - downX);int downDY = Math.abs(y - downY);if ((downDX > 10 || downDY > 10) && !pointer) {autoScroll();}break;}isOnClick = false;lastY = y;lastX = x;return true;}private Runnable hideOverviewRunnable = new Runnable() {@Overridepublic void run() {isDrawOverview = false;invalidate();}};Bitmap drawHeadInfo() {String txt = "已售";float txtY = getBaseLine(headPaint, 0, headHeight);int txtWidth = (int) headPaint.measureText(txt);float spacing = dip2Px(10);float spacing1 = dip2Px(5);float y = (headHeight - seatBitmap.getHeight()) / 2;float width = seatBitmap.getWidth() + spacing1 + txtWidth + spacing + seatSoldBitmap.getWidth() + txtWidth + spacing1 + spacing + checkedSeatBitmap.getHeight() + spacing1 + txtWidth;Bitmap bitmap = Bitmap.createBitmap(getWidth(), (int) headHeight, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);//繪制背景canvas.drawRect(0, 0, getWidth(), headHeight, headPaint);headPaint.setColor(Color.BLACK);float startX = (getWidth() - width) / 2;tempMatrix.setScale(xScale1,yScale1);tempMatrix.postTranslate(startX,(headHeight - seatHeight) / 2);canvas.drawBitmap(seatBitmap, tempMatrix, headPaint);canvas.drawText("可選", startX + seatWidth + spacing1, txtY, headPaint);float soldSeatBitmapY = startX + seatBitmap.getWidth() + spacing1 + txtWidth + spacing;tempMatrix.setScale(xScale1,yScale1);tempMatrix.postTranslate(soldSeatBitmapY,(headHeight - seatHeight) / 2);canvas.drawBitmap(seatSoldBitmap, tempMatrix, headPaint);canvas.drawText("已售", soldSeatBitmapY + seatWidth + spacing1, txtY, headPaint);float checkedSeatBitmapX = soldSeatBitmapY + seatSoldBitmap.getWidth() + spacing1 + txtWidth + spacing;tempMatrix.setScale(xScale1,yScale1);tempMatrix.postTranslate(checkedSeatBitmapX,y);canvas.drawBitmap(checkedSeatBitmap, tempMatrix, headPaint);canvas.drawText("已選", checkedSeatBitmapX + spacing1 + seatWidth, txtY, headPaint);//繪制分割線headPaint.setStrokeWidth(1);headPaint.setColor(Color.GRAY);canvas.drawLine(0, headHeight, getWidth(), headHeight, headPaint);return bitmap;}/*** 繪制中間屏幕*/void drawScreen(Canvas canvas) {pathPaint.setStyle(Paint.Style.FILL);pathPaint.setColor(Color.parseColor("#e2e2e2"));float startY = headHeight + borderHeight;float centerX = seatBitmapWidth * getMatrixScaleX() / 2 + getTranslateX();float screenWidth = seatBitmapWidth * screenWidthScale * getMatrixScaleX();if (screenWidth < defaultScreenWidth) {screenWidth = defaultScreenWidth;}Path path = new Path();path.moveTo(centerX, startY);path.lineTo(centerX - screenWidth / 2, startY);path.lineTo(centerX - screenWidth / 2 + 20, screenHeight * getMatrixScaleY() + startY);path.lineTo(centerX + screenWidth / 2 - 20, screenHeight * getMatrixScaleY() + startY);path.lineTo(centerX + screenWidth / 2, startY);canvas.drawPath(path, pathPaint);pathPaint.setColor(Color.BLACK);pathPaint.setTextSize(20 * getMatrixScaleX());canvas.drawText(screenName, centerX - pathPaint.measureText(screenName) / 2, getBaseLine(pathPaint, startY, startY + screenHeight * getMatrixScaleY()), pathPaint);}Matrix tempMatrix = new Matrix();void drawSeat(Canvas canvas) {zoom = getMatrixScaleX();long startTime = System.currentTimeMillis();float translateX = getTranslateX();float translateY = getTranslateY();float scaleX = zoom;float scaleY = zoom;for (int i = 0; i < row; i++) {float top = i * seatBitmap.getHeight() * yScale1 * scaleY + i * verSpacing * scaleY + translateY;float bottom = top + seatBitmap.getHeight() * yScale1 * scaleY;if (bottom < 0 || top > getHeight()) {continue;}for (int j = 0; j < column; j++) {float left = j * seatBitmap.getWidth() * xScale1 * scaleX + j * spacing * scaleX + translateX;float right = (left + seatBitmap.getWidth() * xScale1 * scaleY);if (right < 0 || left > getWidth()) {continue;}int seatType = getSeatType(i, j);tempMatrix.setTranslate(left, top);tempMatrix.postScale(xScale1, yScale1, left, top);tempMatrix.postScale(scaleX, scaleY, left, top);switch (seatType) {case SEAT_TYPE_AVAILABLE:canvas.drawBitmap(seatBitmap, tempMatrix, paint);break;case SEAT_TYPE_NOT_AVAILABLE:break;case SEAT_TYPE_SELECTED:canvas.drawBitmap(checkedSeatBitmap, tempMatrix, paint);drawText(canvas, i, j, top, left);break;case SEAT_TYPE_SOLD:canvas.drawBitmap(seatSoldBitmap, tempMatrix, paint);break;}}}if (DBG) {long drawTime = System.currentTimeMillis() - startTime;Log.d("drawTime", "seatDrawTime:" + drawTime);}}private int getSeatType(int row, int column) {if (isHave(getID(row, column)) >= 0) {return SEAT_TYPE_SELECTED;}if (seatChecker != null) {if (!seatChecker.isValidSeat(row, column)) {return SEAT_TYPE_NOT_AVAILABLE;} else if (seatChecker.isSold(row, column)) {return SEAT_TYPE_SOLD;}}return SEAT_TYPE_AVAILABLE;}private int getID(int row, int column) {return row * this.column + (column + 1);}/*** 繪制選中座位的行號列號** @param row* @param column*/private void drawText(Canvas canvas, int row, int column, float top, float left) {String txt = (row + 1) + "排";String txt1 = (column + 1) + "座";if(seatChecker!=null){String[] strings = seatChecker.checkedSeatTxt(row, column);if(strings!=null&&strings.length>0){if(strings.length>=2){txt=strings[0];txt1=strings[1];}else {txt=strings[0];txt1=null;}}}TextPaint txtPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);txtPaint.setColor(txt_color);txtPaint.setTypeface(Typeface.DEFAULT_BOLD);float seatHeight = this.seatHeight * getMatrixScaleX();float seatWidth = this.seatWidth * getMatrixScaleX();txtPaint.setTextSize(seatHeight / 3);//獲取中間線float center = seatHeight / 2;float txtWidth = txtPaint.measureText(txt);float startX = left + seatWidth / 2 - txtWidth / 2;//只繪制一行文字if(txt1==null){canvas.drawText(txt, startX, getBaseLine(txtPaint, top, top + seatHeight), txtPaint);}else {canvas.drawText(txt, startX, getBaseLine(txtPaint, top, top + center), txtPaint);canvas.drawText(txt1, startX, getBaseLine(txtPaint, top + center, top + center + seatHeight / 2), txtPaint);}if (DBG) {Log.d("drawTest:", "top:" + top);}}int bacColor = Color.parseColor("#7e000000");/*** 繪制行號*/void drawNumber(Canvas canvas) {long startTime = System.currentTimeMillis();lineNumberPaint.setColor(bacColor);int translateY = (int) getTranslateY();float scaleY = getMatrixScaleY();rectF.top = translateY - lineNumberTxtHeight / 2;rectF.bottom = translateY + (seatBitmapHeight * scaleY) + lineNumberTxtHeight / 2;rectF.left = 0;rectF.right = numberWidth;canvas.drawRoundRect(rectF, numberWidth / 2, numberWidth / 2, lineNumberPaint);lineNumberPaint.setColor(Color.WHITE);for (int i = 0; i < row; i++) {float top = (i *seatHeight + i * verSpacing) * scaleY + translateY;float bottom = (i * seatHeight + i * verSpacing + seatHeight) * scaleY + translateY;float baseline = (bottom + top - lineNumberPaintFontMetrics.bottom - lineNumberPaintFontMetrics.top) / 2;canvas.drawText(lineNumbers.get(i), numberWidth / 2, baseline, lineNumberPaint);}if (DBG) {long drawTime = System.currentTimeMillis() - startTime;Log.d("drawTime", "drawNumberTime:" + drawTime);}}/*** 繪制概覽圖*/void drawOverview(Canvas canvas) {//繪制紅色框int left = (int) -getTranslateX();if (left < 0) {left = 0;}left /= overviewScale;left /= getMatrixScaleX();int currentWidth = (int) (getTranslateX() + (column * seatWidth + 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 * seatHeight + 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);}Bitmap drawOverview() {isDrawOverviewBitmap = false;int bac = Color.parseColor("#7e000000");overviewPaint.setColor(bac);overviewPaint.setAntiAlias(true);overviewPaint.setStyle(Paint.Style.FILL);overviewBitmap.eraseColor(Color.TRANSPARENT);Canvas canvas = new Canvas(overviewBitmap);//繪制透明灰色背景canvas.drawRect(0, 0, rectW, rectH, overviewPaint);overviewPaint.setColor(Color.WHITE);for (int i = 0; i < row; i++) {float top = i * rectHeight + i * overviewVerSpacing + overviewVerSpacing;for (int j = 0; j < column; j++) {int seatType = getSeatType(i, j);switch (seatType) {case SEAT_TYPE_AVAILABLE:overviewPaint.setColor(Color.WHITE);break;case SEAT_TYPE_NOT_AVAILABLE:continue;case SEAT_TYPE_SELECTED:overviewPaint.setColor(overview_checked);break;case SEAT_TYPE_SOLD:overviewPaint.setColor(overview_sold);break;}float left;left = j * rectWidth + j * overviewSpacing + overviewSpacing;canvas.drawRect(left, top, left + rectWidth, top + rectHeight, overviewPaint);}}return overviewBitmap;}/*** 自動回彈* 整個大小不超過控件大小的時候:* 往左邊滑動,自動回彈到行號右邊* 往右邊滑動,自動回彈到右邊* 往上,下滑動,自動回彈到頂部* <p>* 整個大小超過控件大小的時候:* 往左側滑動,回彈到最右邊,往右側滑回彈到最左邊* 往上滑動,回彈到底部,往下滑動回彈到頂部*/private void autoScroll() {float currentSeatBitmapWidth = seatBitmapWidth * getMatrixScaleX();float currentSeatBitmapHeight = seatBitmapHeight * getMatrixScaleY();float moveYLength = 0;float moveXLength = 0;//處理左右滑動的情況if (currentSeatBitmapWidth < getWidth()) {if (getTranslateX() < 0 || getMatrixScaleX() < numberWidth + spacing) {//計算要移動的距離if (getTranslateX() < 0) {moveXLength = (-getTranslateX()) + numberWidth + spacing;} else {moveXLength = numberWidth + spacing - getTranslateX();}}} else {if (getTranslateX() < 0 && getTranslateX() + currentSeatBitmapWidth > getWidth()) {} else {//往左側滑動if (getTranslateX() + currentSeatBitmapWidth < getWidth()) {moveXLength = getWidth() - (getTranslateX() + currentSeatBitmapWidth);} else {//右側滑動moveXLength = -getTranslateX() + numberWidth + spacing;}}}float startYPosition = screenHeight * getMatrixScaleY() + verSpacing * getMatrixScaleY() + headHeight + borderHeight;//處理上下滑動if (currentSeatBitmapHeight+headHeight < getHeight()) {if (getTranslateY() < startYPosition) {moveYLength = startYPosition - getTranslateY();} else {moveYLength = -(getTranslateY() - (startYPosition));}} else {if (getTranslateY() < 0 && getTranslateY() + currentSeatBitmapHeight > getHeight()) {} else {//往上滑動if (getTranslateY() + currentSeatBitmapHeight < getHeight()) {moveYLength = getHeight() - (getTranslateY() + currentSeatBitmapHeight);} else {moveYLength = -(getTranslateY() - (startYPosition));}}}Point start = new Point();start.x = (int) getTranslateX();start.y = (int) getTranslateY();Point end = new Point();end.x = (int) (start.x + moveXLength);end.y = (int) (start.y + moveYLength);moveAnimate(start, end);}private void autoScale() {if (getMatrixScaleX() > 2.2) {zoomAnimate(getMatrixScaleX(), 2.0f);} else if (getMatrixScaleX() < 0.98) {zoomAnimate(getMatrixScaleX(), 1.0f);}}Handler handler = new Handler();ArrayList<Integer> selects = new ArrayList<>();public ArrayList<String> getSelectedSeat(){ArrayList<String> results=new ArrayList<>();for(int i=0;i<this.row;i++){for(int j=0;j<this.column;j++){if(isHave(getID(i,j))>=0){results.add(i+","+j);}}}return results;}private int isHave(Integer seat) {return Collections.binarySearch(selects, seat);}private void remove(int index) {selects.remove(index);}float[] m = new float[9];private float getTranslateX() {matrix.getValues(m);return m[2];}private float getTranslateY() {matrix.getValues(m);return m[5];}private float getMatrixScaleY() {matrix.getValues(m);return m[4];}private float getMatrixScaleX() {matrix.getValues(m);return m[Matrix.MSCALE_X];}private float dip2Px(float value) {return getResources().getDisplayMetrics().density * value;}private float getBaseLine(Paint p, float top, float bottom) {Paint.FontMetrics fontMetrics = p.getFontMetrics();int baseline = (int) ((bottom + top - fontMetrics.bottom - fontMetrics.top) / 2);return baseline;}private void moveAnimate(Point start, Point end) {ValueAnimator valueAnimator = ValueAnimator.ofObject(new MoveEvaluator(), start, end);valueAnimator.setInterpolator(new DecelerateInterpolator());MoveAnimation moveAnimation = new MoveAnimation();valueAnimator.addUpdateListener(moveAnimation);valueAnimator.setDuration(400);valueAnimator.start();}private void zoomAnimate(float cur, float tar) {ValueAnimator valueAnimator = ValueAnimator.ofFloat(cur, tar);valueAnimator.setInterpolator(new DecelerateInterpolator());ZoomAnimation zoomAnim = new ZoomAnimation();valueAnimator.addUpdateListener(zoomAnim);valueAnimator.addListener(zoomAnim);valueAnimator.setDuration(400);valueAnimator.start();}private float zoom;private void zoom(float zoom) {float z = zoom / getMatrixScaleX();matrix.postScale(z, z, scaleX, scaleY);invalidate();}private void move(Point p) {float x = p.x - getTranslateX();float y = p.y - getTranslateY();matrix.postTranslate(x, y);invalidate();}class MoveAnimation implements ValueAnimator.AnimatorUpdateListener {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {Point p = (Point) animation.getAnimatedValue();move(p);}}class MoveEvaluator implements TypeEvaluator {@Overridepublic Object evaluate(float fraction, Object startValue, Object endValue) {Point startPoint = (Point) startValue;Point endPoint = (Point) endValue;int x = (int) (startPoint.x + fraction * (endPoint.x - startPoint.x));int y = (int) (startPoint.y + fraction * (endPoint.y - startPoint.y));return new Point(x, y);}}class ZoomAnimation implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {zoom = (Float) animation.getAnimatedValue();zoom(zoom);if (DBG) {Log.d("zoomTest", "zoom:" + zoom);}}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}@Overridepublic void onAnimationStart(Animator animation) {}}public void setData(int row, int column) {this.row = row;this.column = column;init();invalidate();}ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.OnScaleGestureListener() {@Overridepublic boolean onScale(ScaleGestureDetector detector) {isScaling = true;float scaleFactor = detector.getScaleFactor();if (getMatrixScaleY() * scaleFactor > 3) {scaleFactor = 3 / getMatrixScaleY();}if (firstScale) {scaleX = detector.getCurrentSpanX();scaleY = detector.getCurrentSpanY();firstScale = false;}if (getMatrixScaleY() * scaleFactor < 0.5) {scaleFactor = 0.5f / getMatrixScaleY();}matrix.postScale(scaleFactor, scaleFactor, scaleX, scaleY);invalidate();return true;}@Overridepublic boolean onScaleBegin(ScaleGestureDetector detector) {return true;}@Overridepublic void onScaleEnd(ScaleGestureDetector detector) {isScaling = false;firstScale = true;}});GestureDetector gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {@Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {isOnClick = true;int x = (int) e.getX();int y = (int) e.getY();for (int i = 0; i < row; i++) {for (int j = 0; j < column; j++) {int tempX = (int) ((j * seatWidth + (j+1) * spacing) * getMatrixScaleX() + getTranslateX());int maxTemX = (int) (tempX + seatWidth * getMatrixScaleX());int tempY = (int) ((i * seatHeight + i * verSpacing) * getMatrixScaleY() + getTranslateY());int maxTempY = (int) (tempY + seatHeight * getMatrixScaleY());if (seatChecker != null && seatChecker.isValidSeat(i, j) && !seatChecker.isSold(i, j)) {if (x >= tempX && x <= maxTemX && y >= tempY && y <= maxTempY) {int id = getID(i, j);int index = isHave(id);if (index >= 0) {remove(index);if (seatChecker != null) {seatChecker.unCheck(i, j);}} else {if (selects.size() >= maxSelected) {Toast.makeText(getContext(), "最多只能選擇" + maxSelected + "個", Toast.LENGTH_SHORT).show();return super.onSingleTapConfirmed(e);} else {addChooseSeat(i, j);if (seatChecker != null) {seatChecker.checked(i, j);}}}isNeedDrawSeatBitmap = true;isDrawOverviewBitmap = true;float currentScaleY = getMatrixScaleY();if (currentScaleY < 1.7) {scaleX = x;scaleY = y;zoomAnimate(currentScaleY, 1.9f);}invalidate();break;}}}}return super.onSingleTapConfirmed(e);}});private void addChooseSeat(int row, int column) {int id = getID(row, column);for (int i = 0; i < selects.size(); i++) {int item = selects.get(i);if (id < item) {selects.add(i, id);return;}}selects.add(id);}public interface SeatChecker {/*** 是否可用座位** @param row* @param column* @return*/boolean isValidSeat(int row, int column);/*** 是否已售** @param row* @param column* @return*/boolean isSold(int row, int column);void checked(int row, int column);void unCheck(int row, int column);/*** 獲取選中后座位上顯示的文字* @param row* @param column* @return 返回2個元素的數組,第一個元素是第一行的文字,第二個元素是第二行文字,如果只返回一個元素則會繪制到座位圖的中間位置*/String[] checkedSeatTxt(int row, int column);}public void setScreenName(String screenName) {this.screenName = screenName;}public void setMaxSelected(int maxSelected) {this.maxSelected = maxSelected;}public void setSeatChecker(SeatChecker seatChecker) {this.seatChecker = seatChecker;invalidate();}private int getRowNumber(int row){int result=row;if(seatChecker==null){return -1;}for(int i=0;i<row;i++){for (int j=0;j<column;j++){if(seatChecker.isValidSeat(i,j)){break;}if(j==column-1){if(i==row){return -1;}result--;}}}return result;}private int getColumnNumber(int row,int column){int result=column;if(seatChecker==null){return -1;}for(int i=row;i<=row;i++){for (int j=0;j<column;j++){if(!seatChecker.isValidSeat(i,j)){if(j==column){return -1;}result--;}}}return result;} }第二步:
在values文件下寫
<?xml version="1.0" encoding="utf-8"?> <resources><declare-styleable name="styleable"><attr name="seat_checked" format="reference" /><attr name="seat_sold" format="reference" /><attr name="seat_available" format="reference" /><attr name="overview_checked" format="color" /><attr name="overview_sold" format="color" /><attr name="txt_color" format="color"/></declare-styleable><declare-styleable name="LinearGradientTextView4"><attr name="lineNumber" format="integer"></attr><attr name="showTime" format="integer"></attr><attr name="textColor" format="color"></attr><attr name="showStyle"><enum name="UNIDIRECTION" value="0"></enum><enum name="TWOWAY" value="1"></enum></attr></declare-styleable> </resources>第三步:
布局頁面
<com.bw.movie.activity.cinema_activity.SeatTableandroid:id="@+id/mSearchView"android:layout_below="@+id/image"android:layout_width="match_parent"android:layout_height="match_parent"/>第四步:
我這是在Activity中寫的
找控件
seatTableView = (SeatTable)findViewById(R.id.mSearchView); seatTableView.setScreenName("8號廳熒幕");//設置屏幕名稱 seatTableView.setMaxSelected(3);//設置最多選中seatTableView.setSeatChecker(new SeatTable.SeatChecker() {@Overridepublic boolean isValidSeat(int row, int column) {if(column==2) {return false;}return true;}@Overridepublic boolean isSold(int row, int column) {if(row==6&&column==6){return true;}return false;}@Overridepublic void checked(int row, int column) {}@Overridepublic void unCheck(int row, int column) {}@Overridepublic String[] checkedSeatTxt(int row, int column) {return null;}}); seatTableView.setData(10,15);?
?
?
?
?
總結
以上是生活随笔為你收集整理的Android影院选座的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 比特大陆招股书讲了个AI的故事,但资本市
- 下一篇: 基础数论入门