美文网首页Android
Android 飞机选座

Android 飞机选座

作者: 遇见编程 | 来源:发表于2021-07-23 08:14 被阅读0次

    FlightSeatView.java

    import android.animation.Animator;
    import android.animation.AnimatorListenerAdapter;
    import android.animation.ValueAnimator;
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.animation.LinearInterpolator;
    import android.widget.Toast;
    import com.demo2.R;
    import java.io.ByteArrayOutputStream;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * Created by lumingmin on 16/7/22.
     */
    
    
    public class FlightSeatView extends View {
    
    
        private Paint mPaint;
        private Paint mPaintOther;
        private Paint mPaintMap;
    
    
        private RectF rectFCabin;
        RectF rectFWall;
        RectF rectFWC;
    
        private HashMap<String, RectF> mSeats
                = new HashMap<>();
    
        private HashMap<String, SeatState> mSeatSelecting
                = new HashMap<>();
    
        private HashMap<String, SeatState> mSeatSelected
                = new HashMap<>();
    
        private HashMap<String, RectF> mSeatSelectingRectF = new HashMap<>();
    
    
        private Path pathFuselage;
        private Path pathArrow;
        private Path pathTail;
    
        Bitmap mBitmapCabin = null;
    
        Bitmap mBitmapFuselage = null;
        Bitmap mBitmapArrow = null;
        Bitmap mBitmapTail = null;
        Bitmap mBitmapSeat_normal = null;
        Bitmap mBitmapSeat_selected = null;
        Bitmap mBitmapSeat_selecting = null;
    
        float scaleValue = 2.0f;
        float scaleMaxValue = 3f;
        float scaleMap = 10f;
        private int maxSelectStates = 10;
        float moveY = 0;
    
    
        private String getSeatKeyName(int row, int column) {
            return String.valueOf(row + "#" + column);
        }
    
    
        public void setSeatSelected(int row, int column) {
    
            mSeatSelected.put(getSeatKeyName(row, column), SeatState.Selected);
        }
    
    
        public void goCabinPosition(CabinPosition mCabinPosition) {
            if (mAnimatedValue > 0) {
    
                if (mCabinPosition == CabinPosition.Top) {
                    moveY = 0;
    
                } else if (mCabinPosition == CabinPosition.Last) {
                    moveY = rectFCabin.height() - rectFCabin.width() * 2.5f;
                } else if (mCabinPosition == CabinPosition.Middle) {
                    moveY = (rectFCabin.height() - rectFCabin.width() * 2.5f) / 2;
                }
                invalidate();
    
    
            }
        }
    
    
        public void setEmptySelecting() {
            mSeatSelecting.clear();
            mSeatSelectingRectF.clear();
            invalidate();
        }
    
        public void setMaxSelectStates(int count) {
            maxSelectStates = count;
        }
    
    
        public FlightSeatView(Context context) {
            this(context, null);
        }
    
        public FlightSeatView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public FlightSeatView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initPaint();
        }
    
        private int dip2px(float dpValue) {
            final float scale = getContext().getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
            if (widthSpecMode == MeasureSpec.AT_MOST
                    && heightSpecMode == MeasureSpec.AT_MOST) {
                setMeasuredDimension(dip2px(150), dip2px(200));
            } else if (widthSpecMode == MeasureSpec.AT_MOST) {
                setMeasuredDimension((int) (heightSpecSize * 0.75f), heightSpecSize);
            } else if (heightSpecMode == MeasureSpec.AT_MOST) {
                setMeasuredDimension(widthSpecSize, (int) (widthSpecSize / 0.75f));
            }
        }
    
    
        private void initPaint() {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.WHITE);
            mPaint.setStyle(Paint.Style.FILL);
    
    
            mPaintOther = new Paint();
            mPaintOther.setAntiAlias(true);
            mPaintOther.setColor(Color.rgb(138, 138, 138));
            mPaintOther.setStyle(Paint.Style.FILL);
            mPaintMap = new Paint();
            mPaintMap.setAntiAlias(true);
            mPaintMap.setColor(Color.rgb(138, 138, 138));
            mPaintMap.setStyle(Paint.Style.FILL);
    
            rectFCabin = new RectF();
            rectFWall = new RectF();
            rectFWC = new RectF();
    
            pathFuselage = new Path();
            pathFuselage.reset();
            pathArrow = new Path();
            pathArrow.reset();
            pathTail = new Path();
            pathTail.reset();
    
            setOnTouchListener(new MoveListerner((Activity) getContext()) {
                @Override
                public void moveDirection(View v, int direction, float distanceX, float distanceY) {
    
    
                }
    
                @Override
                public void moveUpAndDownDistance(MotionEvent event, int distance, int distanceY) {
    
    //                System.out.println("-----moveUpAndDownDistance:" + distance + "----:" + distanceY);
    
                    if (mAnimatedValue > 0) {
    
                        if (moveY >= 0 && moveY <= rectFCabin.height() - rectFCabin.width() * 2.5f) {
                            moveY = moveY + distanceY;
                            invalidate();
                        }
                        if (moveY < 0) {
                            moveY = 0;
                        }
                        if (moveY > rectFCabin.height() - rectFCabin.width() * 2.5f) {
                            moveY = rectFCabin.height() - rectFCabin.width() * 2.5f;
                        }
                    }
    
    
                }
    
                @Override
                public void moveOver() {
    //                System.out.println("-----moveOver:");
    
                }
    
                @Override
                public void Touch(float x, float y) {
                    if (mAnimatedValue == 0) {
                        startAnim(false);
                    } else {
    
    
                        RectF selecting = new RectF();
    
    
                        Iterator iter = mSeats.entrySet().iterator();
                        while (iter.hasNext()) {
                            Map.Entry entry = (Map.Entry) iter.next();
                            String key = (String) entry.getKey();
                            RectF val = (RectF) entry.getValue();
    //                        x=x-moveY;
    
    
                            if (val.contains(x, y)) {
    //                            System.out.println("----key" + key);
                                if (mSeatSelecting.containsKey(key)) {
    
                                    if (mSeatSelecting.get(key) != SeatState.Selected) {
                                        mSeatSelecting.remove(key);
                                        mSeatSelectingRectF.remove(key);
                                        invalidate();
                                    }
    
    
                                } else {
                                    if (mSeatSelecting.size()
                                            >= maxSelectStates) {
                                        Toast.makeText(getContext(),
                                                "Choose a maximum of " + maxSelectStates,
                                                Toast.LENGTH_SHORT).show();
                                        return;
    
                                    } else {
                                        if (!mSeatSelected.containsKey(key)) {
                                            mSeatSelecting.put(key,
                                                    SeatState.Selecting);
    
                                            selecting.top = val.top / scaleMap
                                                    + rectFCabin.top + rectFCabin.width() * 0.8f
                                                    + moveY / scaleMap;
                                            selecting.bottom = val.bottom / scaleMap
                                                    + rectFCabin.top + rectFCabin.width() * 0.8f
                                                    + moveY / scaleMap;
                                            selecting.left = val.centerX() / scaleMap - val.width() / scaleMap / 2f
                                                    - val.width() / scaleMap / 2f
                                                    + rectFCabin.left;
                                            selecting.right = val.centerX() / scaleMap + val.width() / scaleMap / 2f
                                                    - val.width() / scaleMap / 2f
                                                    + rectFCabin.left;
    
    
                                            mSeatSelectingRectF.put(key, selecting);
    
                                            invalidate();
    
                                        }
    //                                    else
    //                                    {
    //                                        Toast.makeText(getContext(),
    //                                               "The selected",
    //                                                Toast.LENGTH_SHORT).show();
    //                                    }
                                    }
                                }
    
                            }
    
    
                        }
    
    
                    }
    
                }
            });
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            canvas.save();
    
            scaleValue = scaleMaxValue * mAnimatedValue;
    
    
            Matrix matrix = new Matrix();
            matrix.postScale(1 + scaleValue * 2f, 1 + scaleValue * 2f);
            matrix.postTranslate(getMeasuredWidth() * -1 * scaleValue,
                    scaleValue * 2f * (getMeasuredHeight() / 3f / 3f + getMeasuredWidth() / 8f) * -1 - moveY);
            float rectFCabinWidth = getMeasuredWidth() / 8f;
            rectFCabin.top = getMeasuredHeight() / 3f / 3f;
            rectFCabin.left = getMeasuredWidth() / 2f - rectFCabinWidth / 2f;
            rectFCabin.right = getMeasuredWidth() / 2f + rectFCabinWidth / 2f;
            rectFCabin.bottom = getMeasuredHeight() / 3f / 3f + getMeasuredHeight() / 3f * 2f;
            canvas.drawBitmap(getBitmapFuselage(rectFCabinWidth), matrix, mPaint);
            canvas.drawBitmap(getBitmapArrow(), matrix, mPaint);
            canvas.drawBitmap(getBitmapTail(), matrix, mPaint);
            canvas.drawBitmap(getBitmapCabin(), matrix, mPaint);
            rectFCabinWidth = getMeasuredWidth() / 8f * (1 + scaleValue * 2f);
            rectFCabin.top = getMeasuredHeight() / 3f / 3f;
            rectFCabin.left = getMeasuredWidth() / 2f - rectFCabinWidth / 2f;
            rectFCabin.right = getMeasuredWidth() / 2f + rectFCabinWidth / 2f;
            rectFCabin.bottom = getMeasuredHeight() / 3f / 3f + getMeasuredHeight() / 3f * 2f * (1 + scaleValue * 2f);
            canvas.translate(0,
                    scaleValue * (1 - 0.1f * (scaleMaxValue - 2))
                            * (getMeasuredHeight() / 3f / 3f + getMeasuredWidth() / 8f) * -1 - moveY);
            drawSeatFirst(canvas);
            drawSeatTourist(canvas);
            drawSeatLast(canvas);
            drawSeatMap(canvas);
            canvas.restore();
    
    
        }
    
    
        public enum CabinPosition {
            Top, Middle, Last
        }
    
        enum SeatType {
            Left, Middle, Right
        }
    
        enum SeatState {
            Normal, Selected, Selecting
        }
    
        enum CabinType {
            Frist, Second, Tourist, Last
        }
    
    
        private void setSeat(int i, int j, Canvas canvas, float seatWH, SeatType type
                , CabinType cabinType) {
            float top = 0f;
            float left = 0f;
            if (cabinType == CabinType.Frist) {
                if (type == SeatType.Left) {
                    top = rectFCabin.top + rectFCabin.width() / 2 +
                            seatWH + i * (seatWH) + seatWH / 2;
    
                    left = rectFCabin.left + j * (seatWH) + seatWH / 3;
                } else if (type == SeatType.Middle) {
                    top = rectFCabin.top + rectFCabin.width() / 2 +
                            seatWH + i * (seatWH) + seatWH / 2 + seatWH / 2;
                    left = rectFCabin.left + j * (seatWH) + seatWH * 1f;
                } else if (type == SeatType.Right) {
                    top = rectFCabin.top + rectFCabin.width() / 2 +
                            seatWH + i * (seatWH) + seatWH / 2;
                    left = rectFCabin.left + j * (seatWH) + seatWH * 2f
                            - seatWH / 3f;
                }
            } else if (cabinType == CabinType.Second) {
                if (type == SeatType.Left) {
    
                    left = rectFCabin.left + j * (seatWH) + seatWH / 3;
                    top = rectFCabin.top + seatWH * 14f
                            + rectFCabin.width() / 2 +
                            seatWH + i * (seatWH) + seatWH / 2;
    
    
                } else if (type == SeatType.Middle) {
    
    
                    left = rectFCabin.left + j * (seatWH) + seatWH / 1f;
                    top = rectFCabin.top + rectFCabin.width() / 2
                            + seatWH * 14f +
                            seatWH + i * (seatWH) + seatWH / 2 + seatWH / 2;
                } else if (type == SeatType.Right) {
    
    
                    left = rectFCabin.left + j * (seatWH) + seatWH * 2f
                            - seatWH / 3f;
                    top = rectFCabin.top
                            + seatWH * 14f
                            + rectFCabin.width() / 2 +
                            seatWH + i * (seatWH) + seatWH / 2;
    
    
                }
            } else if (cabinType == CabinType.Tourist) {
                if (type == SeatType.Left) {
                    left = rectFCabin.left + j * (seatWH)
                            + seatWH / 3;
                    top = rectFWall.bottom
                            + seatWH * 1.5f
                            +
                            i * (seatWH);
    
    
                } else if (type == SeatType.Middle) {
                    left = rectFCabin.left + j * (seatWH)
                            + seatWH * 1f
                    ;
                    top = rectFWall.bottom
                            + seatWH * 1.5f
                            +
                            i * (seatWH);
    
    
                } else if (type == SeatType.Right) {
                    left = rectFCabin.left + j * (seatWH)
                            + seatWH * 2.0f -
                            seatWH / 3f
                    ;
                    top = rectFWall.bottom
                            + seatWH * 1.5f
                            +
                            i * (seatWH);
    
    
                }
            } else if (cabinType == CabinType.Last) {
                if (type == SeatType.Left) {
    
    
                    left = rectFCabin.left + j * (seatWH)
                            + seatWH / 3
                    ;
                    top = rectFWC.bottom
                            + seatWH * 1.5f
                            +
                            i * (seatWH);
    
    
                } else if (type == SeatType.Middle) {
    
                    left = rectFCabin.left + j * (seatWH)
                            + seatWH * 1f
                    ;
                    top = rectFWC.bottom
                            + seatWH * 1.5f
                            +
                            i * (seatWH);
    
    
                } else if (type == SeatType.Right) {
    
                    left = rectFCabin.left + j * (seatWH)
                            + seatWH * 2.0f -
                            seatWH / 3f
                    ;
                    top = rectFWC.bottom
                            + seatWH * 1.5f
                            +
                            i * (seatWH);
    
    
                }
            }
    
    
            RectF sRectF = new RectF();
    
            sRectF = new RectF(left, top,
                    left + seatWH, top + seatWH);
            PointSeat point = null;
            if (cabinType == CabinType.Frist) {
                point = new PointSeat(i, j);
            } else if (cabinType == CabinType.Second) {
                point = new PointSeat(i + 7, j);
    
            } else if (cabinType == CabinType.Tourist) {
                point = new PointSeat(i + 10, j);
    
            } else if (cabinType == CabinType.Last) {
                point = new PointSeat(i + 35, j);
    
            }
    
    
            if (mAnimatedValue == 1) {
                if (cabinType == CabinType.Frist) {
    
                    if (type == SeatType.Left || type == SeatType.Right) {
    
                        sRectF.top = sRectF.top - rectFCabin.top - rectFCabin.width() / 2
                                - seatWH * (scaleMaxValue - 1.51f) - moveY;
                        sRectF.bottom = sRectF.bottom - rectFCabin.top - rectFCabin.width() / 2
                                - seatWH * (scaleMaxValue - 1.51f) - moveY;
    
                    }
                    if (type == SeatType.Middle) {
    
                        sRectF.top = sRectF.top - rectFCabin.top - rectFCabin.width() / 2
                                - seatWH * (scaleMaxValue - 1.8f) - seatWH / 2f - moveY;
                        sRectF.bottom = sRectF.bottom - rectFCabin.top - rectFCabin.width() / 2
                                - seatWH * (scaleMaxValue - 1.8f) - seatWH / 2f - moveY;
    
                    }
    
    
                } else if (cabinType == CabinType.Second) {
    
    
                    if (type == SeatType.Left || type == SeatType.Right) {
    
                        sRectF.top = sRectF.top - rectFCabin.top - rectFCabin.width() / 2
                                - seatWH * (scaleMaxValue - 1.25f) - moveY;
                        sRectF.bottom = sRectF.bottom - rectFCabin.top - rectFCabin.width() / 2
                                - seatWH * (scaleMaxValue - 1.25f) - moveY;
    
                    }
                    if (type == SeatType.Middle) {
    
                        sRectF.top = sRectF.top - rectFCabin.top - rectFCabin.width() / 2
                                - seatWH * (scaleMaxValue - 1.75f) - seatWH / 2f - moveY;
                        sRectF.bottom = sRectF.bottom - rectFCabin.top - rectFCabin.width() / 2
                                - seatWH * (scaleMaxValue - 1.75f) - seatWH / 2f - moveY;
    
                    }
    
    
    //                sRectF.top = sRectF.top - rectFCabin.top - rectFCabin.width() / 2 - seatWH * (scaleMaxValue - 1) - moveY;
    //                sRectF.bottom = sRectF.bottom - rectFCabin.top - rectFCabin.width() / 2 - seatWH * (scaleMaxValue - 1) - moveY;
                } else if (cabinType == CabinType.Tourist) {
                    sRectF.top = sRectF.top - rectFCabin.top - rectFCabin.width() / 2 - seatWH * (scaleMaxValue - 1) - moveY;
                    sRectF.bottom = sRectF.bottom - rectFCabin.top - rectFCabin.width() / 2 - seatWH * (scaleMaxValue - 1) - moveY;
    
                } else if (cabinType == CabinType.Last) {
                    sRectF.top = sRectF.top - rectFCabin.top - rectFCabin.width() / 2 - seatWH * (scaleMaxValue - 1) - moveY;
                    sRectF.bottom = sRectF.bottom - rectFCabin.top - rectFCabin.width() / 2 - seatWH * (scaleMaxValue - 1) - moveY;
    
                }
    
                if (sRectF.top > 0 && sRectF.bottom < getMeasuredHeight()) {
                    mSeats.put(getSeatKeyName(point.row, point.column), sRectF);
                }
    
    
            }
    
    
            if (mSeatSelected.containsKey(getSeatKeyName(point.row, point.column))) {
    
    
                canvas.drawBitmap(getSeat(seatWH, mSeatSelected.get(getSeatKeyName(point.row, point.column)))
                        , left
                        ,
                        top
                        ,
                        mPaint
                );
            } else if (mSeatSelecting.containsKey(getSeatKeyName(point.row, point.column))) {
    //            System.out.println("-----" + point.row + "--" + point.column);
    
                canvas.drawBitmap(getSeat(seatWH, mSeatSelecting.get(getSeatKeyName(point.row, point.column)))
                        , left
                        ,
                        top
                        ,
                        mPaint
    
    
                );
    
                if (mAnimatedValue == 1) {
                    if (mSeatSelecting.get(getSeatKeyName(point.row, point.column)) == SeatState.Selecting) {
                        String text = (point.row + 1) + "," + (point.column + 1);
                        mPaintOther.setColor(Color.WHITE);
                        mPaintOther.setTextSize(seatWH / 4f);
                        canvas.drawText(
                                text, left + seatWH / 2f - getFontlength(mPaintOther, text) / 2,
                                top + seatWH / 2f + getFontHeight(mPaintOther, text) / 3,
                                mPaintOther
                        );
                        mPaintOther.setColor(Color.rgb(138, 138, 138));
    
                    }
                }
            } else {
                canvas.drawBitmap(getSeat(seatWH, SeatState.Normal)
                        , left
                        ,
                        top
                        ,
                        mPaint
    
                );
    
    
            }
        }
    
    
        private void drawSeatMap(Canvas canvas) {
            if (mAnimatedValue == 1) {
    
    
                float mapW = rectFCabin.width() / scaleMap;
                float mapH = (rectFCabin.height() - rectFCabin.width() * 2.5f) / scaleMap
                        + getMeasuredHeight() / scaleMap;
                RectF rectFMap = new RectF(rectFCabin.left, rectFCabin.top + rectFCabin.width() * 0.8f + moveY
                        , rectFCabin.left + mapW, rectFCabin.top + rectFCabin.width() * 0.8f + mapH + moveY);
                mPaintMap.setColor(Color.rgb(138, 138, 138));
                mPaintMap.setAlpha(80);
    
                mPaintMap.setStyle(Paint.Style.FILL);
                canvas.drawRect(rectFMap, mPaintMap);
    
    
                mapH = getHeight() / scaleMap;
    
                RectF rectFMapSee = new RectF(rectFCabin.left,
                        rectFCabin.top + rectFCabin.width() * 0.8f + moveY + moveY / scaleMap
                        , rectFCabin.left + mapW,
                        rectFCabin.top + rectFCabin.width() * 0.8f + mapH + moveY + moveY / scaleMap);
                mPaintMap.setStyle(Paint.Style.STROKE);
                mPaintMap.setStrokeWidth(dip2px(0.75f));
                mPaintMap.setColor(Color.RED);
    
                canvas.drawRect(rectFMapSee, mPaintMap);
    
                mPaintMap.setStrokeWidth(0);
    
                if (mSeatSelectingRectF.size() > 0) {
                    mPaintMap.setStyle(Paint.Style.FILL);
                    mPaintMap.setColor(Color.RED);
                    mPaintMap.setAlpha(80);
                    RectF r = new RectF();
    
                    Iterator iter = mSeatSelectingRectF.entrySet().iterator();
                    while (iter.hasNext()) {
                        Map.Entry entry = (Map.Entry) iter.next();
                        String key = (String) entry.getKey();
                        RectF val = (RectF) entry.getValue();
    
    
                        r.top = val.top + moveY;
                        r.bottom = val.bottom + moveY;
                        r.left = val.left - dip2px(0.5f);
                        r.right = val.right - dip2px(0.5f);
    
    
                        canvas.drawRect(r, mPaintMap);
    
    
                    }
    
    
                }
    
    
            }
    
        }
    
    
        private void drawSeatFirst(Canvas canvas) {
    
            int row = 7;
            int column = 7;
            mSeats.clear();
    
            float seatWH = (float) (rectFCabin.width() / 9.0f);
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < column; j++) {
                    if (i >= 0 && j < 2) {
    
                        setSeat(i, j, canvas, seatWH, SeatType.Left, CabinType.Frist);
    //                    setBitmap
    
                    } else if (j >= 2 && j < 5 && i < row - 1) {
                        setSeat(i, j, canvas, seatWH, SeatType.Middle, CabinType.Frist);
    
    
                    } else if (j >= 5) {
    
                        setSeat(i, j, canvas, seatWH, SeatType.Right, CabinType.Frist);
    
                    }
    
    
                }
    
            }
    
    //        RectF rectFWC = new RectF();
    
            rectFWC.top = rectFCabin.top + rectFCabin.width() / 2 +
                    seatWH + (row + 2.5f) * (seatWH) + seatWH / 2;
    
            rectFWC.bottom = rectFCabin.top + rectFCabin.width() / 2 +
                    seatWH + (row + 4.5f) * (seatWH) + seatWH / 2;
    
    
            rectFWC.left = rectFCabin.left + seatWH / 3;
            rectFWC.right = rectFCabin.left + seatWH / 3 + seatWH * 2
    
    
            ;
            mPaintOther.setStyle(Paint.Style.STROKE);
    
            canvas.drawRect(rectFWC, mPaintOther);
    
    
            drawWcText(rectFWC, canvas);
    
    
            RectF rectFWifi = new RectF();
    
    
            rectFWifi.top = rectFCabin.top + rectFCabin.width() / 2 +
                    seatWH + (row + 1f) * (seatWH) + seatWH / 2;
            rectFWifi.bottom = rectFCabin.top + rectFCabin.width() / 2 +
                    seatWH + (row + 4.5f) * (seatWH) + seatWH / 2;
    
            rectFWifi.left = rectFWC.right + seatWH / 2f;
    
            rectFWifi.right = rectFCabin.left + column * (seatWH) + seatWH * 2f
                    - seatWH / 3f - seatWH * 2 - seatWH / 2f;
    
            canvas.drawRect(rectFWifi, mPaintOther);
    
    
            drawWifiLogo(rectFWifi, canvas);
    
    
            rectFWC.top = rectFCabin.top + rectFCabin.width() / 2 +
                    seatWH + (row + 2.5f) * (seatWH) + seatWH / 2;
    
            rectFWC.bottom = rectFCabin.top + rectFCabin.width() / 2 +
                    seatWH + (row + 4.5f) * (seatWH) + seatWH / 2;
    
    
            rectFWC.right = rectFCabin.left + column * (seatWH) + seatWH * 2f
                    - seatWH / 3f;
            rectFWC.left = rectFCabin.left + column * (seatWH) + seatWH * 2f
                    - seatWH / 3f - seatWH * 2
    
            ;
            mPaintOther.setStyle(Paint.Style.STROKE);
            canvas.drawRect(rectFWC, mPaintOther);
            drawWcText(rectFWC, canvas);
            drawSeatSecond(canvas, seatWH);
    
        }
    
    
        private void drawSeatSecond(Canvas canvas, float seatWH) {
            int row = 3;
            int column = 8;
    
            float seatWH2 = (float) (rectFCabin.width() / 10.0f);
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < column; j++) {
                    if (i >= 0 && j < 2) {
    
    
                        setSeat(i, j, canvas, seatWH2, SeatType.Left, CabinType.Second);
    
    
                    } else if (j >= 2 && j < 6) {
    
    
                        setSeat(i, j, canvas, seatWH2, SeatType.Middle, CabinType.Second);
    
    
                    } else if (j >= 6) {
    
                        setSeat(i, j, canvas, seatWH2, SeatType.Right, CabinType.Second);
    
                    }
    
    
                }
    
            }
    
            mPaintOther.setStyle(Paint.Style.FILL);
    
            rectFWall.top = rectFCabin.top
                    + seatWH * 13
                    + rectFCabin.width() / 2 +
                    seatWH + (row + 1) * (seatWH2) + seatWH2 / 2;
            rectFWall.left = rectFCabin.left + seatWH2 / 3;
            rectFWall.right = rectFCabin.left + seatWH2 / 3
                    + 2.5f * seatWH2;
            rectFWall.bottom = rectFCabin.top
                    + seatWH * 13
                    + rectFCabin.width() / 2 +
                    seatWH + (row + 1) * (seatWH2) + seatWH2 / 2
                    + ((int) (dip2px(2) * mAnimatedValue < 1 ? 1 : (int) (dip2px(2) * mAnimatedValue)));
            canvas.drawRoundRect(rectFWall, dip2px(1), dip2px(1), mPaintOther);
            rectFWall.top = rectFCabin.top
                    + seatWH * 13
                    + rectFCabin.width() / 2 +
                    seatWH + (row + 1) * (seatWH2) + seatWH2 / 2;
            rectFWall.left = rectFCabin.left + column * (seatWH2) + seatWH2 * 2f
                    - seatWH / 3f - 2.5f * seatWH2;
            rectFWall.right = rectFCabin.left + column * (seatWH2) + seatWH2 * 2f
                    - seatWH / 3f;
            rectFWall.bottom = rectFCabin.top
                    + seatWH * 13
                    + rectFCabin.width() / 2 +
                    seatWH + (row + 1) * (seatWH2) + seatWH2 / 2
                    + ((int) (dip2px(2) * mAnimatedValue < 1 ? 1 : (int) (dip2px(2) * mAnimatedValue)));
            canvas.drawRoundRect(rectFWall, dip2px(1), dip2px(1), mPaintOther);
    
        }
    
    
        private void drawSeatTourist(Canvas canvas) {
            int row = 25;
            int column = 10;
            int seatWH = (int) (rectFCabin.width() / 12);
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < column; j++) {
    
    
                    if (j >= 0 && j < 3) {
    
    
                        setSeat(i, j, canvas, seatWH, SeatType.Left, CabinType.Tourist);
    
    
                    } else if (j >= 3 && j < 7) {
    
                        setSeat(i, j, canvas, seatWH, SeatType.Middle, CabinType.Tourist);
    
    
                    } else if (j >= 7) {
                        setSeat(i, j, canvas, seatWH, SeatType.Right, CabinType.Tourist);
    
                    }
    
    
                }
    
            }
    
    
            rectFWC.top = rectFWall.bottom
                    + seatWH * 1.5f
                    +
                    26 * (seatWH);
            rectFWC.bottom = rectFWC.top + seatWH * 3;
    
    
            rectFWC.left = rectFCabin.left + seatWH / 3;
            rectFWC.right = rectFCabin.left + seatWH / 3 + seatWH * 3;
            mPaintOther.setStyle(Paint.Style.STROKE);
    
            canvas.drawRect(rectFWC, mPaintOther);
    
            drawWcText(rectFWC, canvas);
    
    
            RectF rectFWifi = new RectF();
    
            rectFWifi.top = rectFWall.bottom
                    + seatWH * 1.5f
                    +
                    26 * (seatWH);
            rectFWifi.bottom = rectFWifi.top + seatWH * 3;
    
    
            rectFWifi.left = rectFWC.right + seatWH / 2f;
    
            rectFWifi.right = rectFCabin.left + column * (seatWH) + seatWH * 2f
                    - seatWH / 3f - seatWH * 3 - seatWH / 2f
            ;
    
            canvas.drawRect(rectFWifi, mPaintOther);
    
    
            drawWifiLogo(rectFWifi, canvas);
    
    
            rectFWC.top = rectFWall.bottom
                    + seatWH * 1.5f
                    +
                    26 * (seatWH);
            rectFWC.bottom = rectFWC.top + seatWH * 3;
    
    
            rectFWC.left = rectFCabin.left + column * (seatWH) + seatWH * 2f
                    - seatWH / 3f - seatWH * 3;
            rectFWC.right = rectFCabin.left + column * (seatWH) + seatWH * 2f
                    - seatWH / 3f;
            mPaintOther.setStyle(Paint.Style.STROKE);
    
            canvas.drawRect(rectFWC, mPaintOther);
    
    
            drawWcText(rectFWC, canvas);
    
    
        }
    
        private void drawSeatLast(Canvas canvas) {
            int row = 19;
            int column = 10;
            int seatWH = (int) (rectFCabin.width() / 12);
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < column; j++) {
    
    
                    if (j >= 0 && j < 3) {
    
                        setSeat(i, j, canvas, seatWH, SeatType.Left, CabinType.Last);
    
                    } else if (j >= 3 && j < 7) {
    
                        setSeat(i, j, canvas, seatWH, SeatType.Middle, CabinType.Last);
    
                    } else if (j >= 7) {
    
                        setSeat(i, j, canvas, seatWH, SeatType.Right, CabinType.Last);
    
                    }
    
    
                }
    
            }
    
        }
    
    
        private Bitmap setBitmapSize(int iconId, float w) {
            Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), iconId);
            float s = w * 1.0f / bitmap.getWidth();
            bitmap = Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * s),
                    (int) (bitmap.getHeight() * s), true);
            return bitmap;
        }
    
    
        private Bitmap getSeat(float width, SeatState type) {
            if (type == SeatState.Normal) {
                if (mBitmapSeat_normal == null) {
                    mBitmapSeat_normal = setBitmapSize(R.drawable.seat_normal, width);
    
                } else if (Math.abs(mBitmapSeat_normal.getWidth() - width) > 1) {
                    mBitmapSeat_normal = setBitmapSize(R.drawable.seat_normal, width);
    
                }
    
                return mBitmapSeat_normal;
            }
            if (type == SeatState.Selected) {
                if (mBitmapSeat_selected == null) {
                    mBitmapSeat_selected = setBitmapSize(R.drawable.seat_select, width);
                } else if (Math.abs(mBitmapSeat_selected.getWidth() - width) > 1) {
                    mBitmapSeat_selected = setBitmapSize(R.drawable.seat_select, width);
    
                }
    
    
                return mBitmapSeat_selected;
    
            }
            if (type == SeatState.Selecting) {
                if (mBitmapSeat_selecting == null) {
                    mBitmapSeat_selecting = setBitmapSize(R.drawable.seat_unselect, width);
                } else if (Math.abs(mBitmapSeat_selecting.getWidth() - width) > 1) {
                    mBitmapSeat_selecting = setBitmapSize(R.drawable.seat_unselect, width);
    
                }
                return mBitmapSeat_selecting;
    
            }
            return null;
        }
    
    
        public Bitmap getBitmapFuselage(float rectFCabinWidth) {
            Canvas canvas = null;
    
            int w = getMeasuredWidth();
            int h = getMeasuredHeight();
    
    
            if (mBitmapFuselage == null) {
                mBitmapFuselage = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
                canvas = new Canvas(mBitmapFuselage);
                pathFuselage.moveTo(w / 2f - rectFCabinWidth / 2f - dip2px(2),
                        rectFCabin.top + rectFCabinWidth / 2f);
                pathFuselage.cubicTo(
                        w / 2f - rectFCabinWidth / 4f,
    
                        rectFCabin.top - rectFCabinWidth * 1.2f,
                        w / 2f + rectFCabinWidth / 4f,
                        rectFCabin.top - rectFCabinWidth * 1.2f,
                        w / 2f + rectFCabinWidth / 2f + dip2px(2),
                        rectFCabin.top + rectFCabinWidth / 2f
                );
    
    
                rectFCabin.top = rectFCabin.top + dip2px(10);//机翼向下平移距离
                pathFuselage.lineTo(w / 2f + rectFCabinWidth / 2f + dip2px(2)
                        , rectFCabin.top + rectFCabin.height() / 3f);
    
                pathFuselage.lineTo(w
                        , rectFCabin.top + rectFCabin.height() * 0.55f);
    
                pathFuselage.lineTo(w
                        , rectFCabin.top + rectFCabin.height() * 0.55f + rectFCabin.width() * 0.8f);
    
                pathFuselage.lineTo(rectFCabin.right + rectFCabin.width() / 2 * 1.5f
                        , rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f);
    
                pathFuselage.lineTo(w / 2f + rectFCabinWidth / 2f + dip2px(2)
                        , rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f);
    //
                pathFuselage.lineTo(w / 2f + rectFCabinWidth / 2f + dip2px(2)
                        , rectFCabin.bottom - rectFCabinWidth / 2f);
    
    
                pathFuselage.cubicTo(
                        w / 2f + rectFCabinWidth / 4f,
    
                        rectFCabin.bottom + rectFCabinWidth * 2.5f,
                        w / 2f - rectFCabinWidth / 4f,
                        rectFCabin.bottom + rectFCabinWidth * 2.5f,
                        w / 2f - rectFCabinWidth / 2f - dip2px(2)
                        , rectFCabin.bottom - rectFCabinWidth / 2f
                );
    
                pathFuselage.lineTo(w / 2f - rectFCabinWidth / 2f - dip2px(2)
                        , rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f);
                pathFuselage.lineTo(rectFCabin.left - rectFCabin.width() / 2 * 1.5f
                        , rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f);
                pathFuselage.lineTo(0
                        , rectFCabin.top + rectFCabin.height() * 0.55f + rectFCabin.width() * 0.8f);
    
                pathFuselage.lineTo(0
                        , rectFCabin.top + rectFCabin.height() * 0.55f);
    
                pathFuselage.lineTo(w / 2f - rectFCabinWidth / 2f - dip2px(2)
                        , rectFCabin.top + rectFCabin.height() / 3f);
                pathFuselage.close();
                mPaint.setColor(Color.WHITE);
                mPaint.setAlpha(150);
                canvas.drawPath(pathFuselage, mPaint);
            }
    
            return mBitmapFuselage;
        }
    
        private Bitmap getBitmapCabin() {
            Canvas canvas = null;
    
            if (mBitmapCabin == null) {
                mBitmapCabin = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
                canvas = new Canvas(mBitmapCabin);
                mPaint.setColor(Color.WHITE);
                rectFCabin.top = rectFCabin.top - dip2px(10);
                rectFCabin.bottom = rectFCabin.bottom + dip2px(5);
                canvas.drawRoundRect(rectFCabin, getMeasuredWidth() / 8f / 2f, getMeasuredWidth() / 8f / 2f, mPaint);
    
            }
    
            return mBitmapCabin;
        }
    
        public Bitmap getBitmapArrow() {
            Canvas canvas = null;
    
            if (mBitmapArrow == null) {
                mBitmapArrow = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
                canvas = new Canvas(mBitmapArrow);
    
                pathArrow.reset();
    
                pathArrow.moveTo(rectFCabin.right + rectFCabin.width() / 2 * 1.2f
                        , rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f);
    
    
                pathArrow.quadTo(
                        rectFCabin.right + rectFCabin.width() / 2 * 1.3f,
                        rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 5f,
    
                        rectFCabin.right + rectFCabin.width() / 2 * 1.4f
                        , rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f);
    
                pathArrow.close();
                canvas.drawPath(pathArrow, mPaint);
                pathArrow.reset();
                pathArrow.moveTo(rectFCabin.left - rectFCabin.width() / 2 * 1.2f
                        , rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f);
                pathArrow.quadTo(
                        rectFCabin.left - rectFCabin.width() / 2 * 1.3f,
                        rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 5f,
    
                        rectFCabin.left - rectFCabin.width() / 2 * 1.4f
                        , rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f);
    
                pathArrow.close();
                canvas.drawPath(pathArrow, mPaint);
                pathArrow.reset();
                float right1x = getMeasuredWidth();
                float right1y = rectFCabin.top + rectFCabin.height() * 0.55f + rectFCabin.width() * 0.8f;
                float right2x = rectFCabin.right + rectFCabin.width() / 2 * 1.5f;
                float right2y = rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f;
                pathArrow.moveTo(
                        (right1x + right2x) / 2f,
                        (right1y + right2y) / 2f);
                pathArrow.quadTo(
                        (right1x + right2x) / 2f + rectFCabin.width() / 2 * 0.1f,
                        (right1y + right2y) / 2f + rectFCabin.height() / 60f * 7f,
                        (right1x + right2x) / 2f + rectFCabin.width() / 2 * 0.2f,
                        (right1y + right2y) / 2f
                );
                canvas.drawPath(pathArrow, mPaint);
                pathArrow.reset();
                float left1x = 0;
                float left1y = rectFCabin.top + rectFCabin.height() * 0.55f + rectFCabin.width() * 0.8f;
                float left2x = rectFCabin.left - rectFCabin.width() / 2 * 1.5f;
                float left2y = rectFCabin.top + rectFCabin.height() / 2f + rectFCabin.height() / 6f / 2f;
                pathArrow.moveTo(
                        (left1x + left2x) / 2f,
                        (left1y + left2y) / 2f);
                pathArrow.quadTo(
                        (left1x + left2x) / 2f - rectFCabin.width() / 2 * 0.1f,
                        (left1y + left2y) / 2f + rectFCabin.height() / 60f * 7f,
                        (left1x + left2x) / 2f - rectFCabin.width() / 2 * 0.2f,
                        (left1y + left2y) / 2f
                );
                mPaint.setColor(Color.WHITE);
                mPaint.setAlpha(150);
                canvas.drawPath(pathArrow, mPaint);
            }
    
            return mBitmapArrow;
        }
    
        private Bitmap getBitmapTail() {
    
            Canvas canvas = null;
    
            if (mBitmapTail == null) {
                mBitmapTail = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
                canvas = new Canvas(mBitmapTail);
                pathTail.reset();
                rectFCabin.bottom = rectFCabin.bottom - dip2px(5);
                pathTail.moveTo(rectFCabin.centerX(),
                        rectFCabin.bottom + rectFCabin.width() / 2);
    
                pathTail.lineTo(rectFCabin.centerX() + rectFCabin.width() * 1.5f,
                        rectFCabin.bottom + rectFCabin.width() * 1.5f);
                pathTail.lineTo(rectFCabin.centerX() + rectFCabin.width() * 1.5f,
                        rectFCabin.bottom + rectFCabin.width() * 2f);
                pathTail.lineTo(rectFCabin.centerX(),
                        rectFCabin.bottom + rectFCabin.width() * 1.5f);
                pathTail.lineTo(rectFCabin.centerX() - rectFCabin.width() * 1.5f,
                        rectFCabin.bottom + rectFCabin.width() * 2f);
                pathTail.lineTo(rectFCabin.centerX() - rectFCabin.width() * 1.5f,
                        rectFCabin.bottom + rectFCabin.width() * 1.5f);
                pathTail.close();
    
                canvas.drawPath(pathTail, mPaint);
    
                pathTail.reset();
                pathTail.moveTo(rectFCabin.centerX() - rectFCabin.width() / 2 * 0.1f,
                        rectFCabin.bottom + rectFCabin.width() * 1.5f);
                pathTail.quadTo(
                        rectFCabin.centerX(),
                        rectFCabin.bottom + rectFCabin.width() * 3f,
                        rectFCabin.centerX() + rectFCabin.width() / 2 * 0.1f,
                        rectFCabin.bottom + rectFCabin.width() * 1.5f);
    
                pathTail.close();
                mPaint.setColor(Color.WHITE);
                mPaint.setAlpha(150);
                canvas.drawPath(pathTail, mPaint);
    
            }
            return mBitmapTail;
        }
    
        public void startAnim(boolean zoomOut) {// false zoom in,true zoom out
            stopAnim();
            startViewAnim(0f, 1f, 280, zoomOut);
        }
    
        private ValueAnimator valueAnimator;
        private float mAnimatedValue = 0f;
    
        public void stopAnim() {
            if (valueAnimator != null) {
                clearAnimation();
                valueAnimator.setRepeatCount(0);
                valueAnimator.cancel();
                valueAnimator.end();
                mAnimatedValue = 0f;
                postInvalidate();
            }
        }
    
        private ValueAnimator startViewAnim(float startF, final float endF, long time, final boolean zoomOut) {
    
            if (zoomOut && moveY > 0) {
                moveY = 0;
                invalidate();
            }
    
            valueAnimator = ValueAnimator.ofFloat(startF, endF);
            valueAnimator.setDuration(time);
            valueAnimator.setInterpolator(new LinearInterpolator());
            valueAnimator.setRepeatCount(0);//无限循环
            valueAnimator.setRepeatMode(ValueAnimator.RESTART);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
    
                    mAnimatedValue = (float) valueAnimator.getAnimatedValue();
    
                    if (zoomOut) {
                        mAnimatedValue = 1 - mAnimatedValue;
                    }
    
                    invalidate();
                }
            });
            valueAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
    
                }
    
                @Override
                public void onAnimationStart(Animator animation) {
                    super.onAnimationStart(animation);
                }
    
                @Override
                public void onAnimationRepeat(Animator animation) {
                    super.onAnimationRepeat(animation);
                }
            });
            if (!valueAnimator.isRunning()) {
                valueAnimator.start();
            }
            return valueAnimator;
        }
    
        public float getFontlength(Paint paint, String str) {
            Rect rect = new Rect();
            paint.getTextBounds(str, 0, str.length(), rect);
            return rect.width();
        }
    
        public float getFontHeight(Paint paint, String str) {
            Rect rect = new Rect();
            paint.getTextBounds(str, 0, str.length(), rect);
            return rect.height();
        }
    
        public class PointSeat {
            public int row;
            public int column;
    
            public PointSeat(int row, int column) {
                this.row = row;
                this.column = column;
            }
        }
    
        private void drawWcText(RectF rectFWC, Canvas canvas) {
            mPaintOther.setTextSize(rectFWC.width() / 4);
            mPaintOther.setAlpha(150);
            canvas.drawText("WC",
                    rectFWC.centerX()
                            - getFontlength(mPaintOther, "WC") / 2f
                    ,
                    rectFWC.centerY() + getFontHeight(mPaintOther, "WC") / 3f,
                    mPaintOther
            );
            mPaintOther.setAlpha(255);
    
        }
    
        private void drawWifiLogo(RectF rectFWifi, Canvas canvas) {
            float signalRadius = rectFWifi.height() / 2 / 4;
            RectF rect = null;
            mPaintOther.setStrokeWidth(signalRadius / 4);
            mPaintOther.setAlpha(150);
            float marginTop = signalRadius * (3 + 0.5f) / 2f;
    
            for (int i = 0; i < 4; i++) {
    
                float radius = signalRadius * (i + 0.5f);
                if (i == 0) {
                    radius = signalRadius / 2f;
                }
                rect = new RectF(
                        rectFWifi.centerX() - radius,
                        rectFWifi.centerY() - radius + marginTop,
                        rectFWifi.centerX() + radius,
                        rectFWifi.centerY() + radius + marginTop);
                if (i != 0) {
                    mPaintOther.setStyle(Paint.Style.STROKE);
                    canvas.drawArc(rect, -135, 90
                            , false, mPaintOther);
                } else {
                    mPaintOther.setStyle(Paint.Style.FILL);
                    canvas.drawArc(rect, -135, 90
                            , true, mPaintOther);
                }
            }
            mPaintOther.setStrokeWidth(0);
            mPaintOther.setAlpha(255);
        }
    
        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            stopAnim();
        }
    
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
    
        private void setBitmap(final Canvas canvas, final float seatWH, final SeatState type, final float left, final float top) {
            fixedThreadPool.execute(new Runnable() {
    
                @Override
                public void run() {
    //                canvas.drawBitmap(getSeat(seatWH, mSeatSelected.get(getSeatKeyName(point.row, point.column)))
    //                        , left
    //                        ,
    //                        top
    //                        ,
    //                        mPaint
    //                );
                    Bitmap b = getSeat(seatWH, type);
                    if (b != null) {
    //                    canvas.drawBitmap(b,left,top,mPaint);
                        Message msg = mHandler.obtainMessage();
                        Bundle bundle = new Bundle();
                        bundle.putFloat("left", left);
                        bundle.putFloat("top", top);
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        b.compress(Bitmap.CompressFormat.PNG, 100, baos);
                        byte[] bitmapByte = baos.toByteArray();
                        bundle.putByteArray("bitmap", bitmapByte);
                        msg.setData(bundle);
                        msg.obj = canvas;
                        mHandler.sendMessage(msg);
                    }
    //                b.recycle();
                }
            });
        }
    
        private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
    
                Canvas c = (Canvas) msg.obj;
    
                Bundle bundle = msg.getData();
    
                if (bundle != null && c != null) {
    
                    float left = bundle.getFloat("left");
                    float top = bundle.getFloat("top");
                    byte[] bis = bundle.getByteArray("bitmap");
                    Bitmap bitmap = BitmapFactory.decodeByteArray(bis, 0, bis.length);
                    if (bitmap != null) {
                        c.drawBitmap(bitmap, left, top, mPaint);
                    }
                }
            }
        };
    }
    

    MoveListerner.java

    import android.app.Activity;
    import android.view.GestureDetector;
    import android.view.GestureDetector.OnGestureListener;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    
    public abstract class MoveListerner implements OnTouchListener,
            OnGestureListener {
        public static final int MOVE_TO_LEFT = 0;
        public static final int MOVE_TO_RIGHT = MOVE_TO_LEFT + 1;
        public static final int MOVE_TO_UP = MOVE_TO_RIGHT + 1;
        public static final int MOVE_TO_DOWN = MOVE_TO_UP + 1;
    
        private static final int FLING_MIN_DISTANCE = 150;
        private static final int FLING_MIN_VELOCITY = 50;
        private boolean isScorllStart = false;
        private boolean isUpAndDown = false;
        GestureDetector mGestureDetector;
        float x1 = 0;
        float x2 = 0;
        float y1 = 0;
        float y2 = 0;
    
        public MoveListerner(Activity context) {
            super();
            mGestureDetector = new GestureDetector(context, this);
        }
    
        float startX = 0;
        float startY = 0;
    
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (mGestureDetector.onTouchEvent(event)) {
                if (MotionEvent.ACTION_DOWN == event.getAction()) {
    //                Touch(event.getX(), event.getY());
                    startX = event.getX();
                    startY = event.getY();
                    return true;
                } else if (MotionEvent.ACTION_UP == event.getAction()) {
                    if (Math.abs(event.getX() - startX) < 5 &&
                            Math.abs(event.getY() - startY) < 5) {
                        Touch(event.getX(), event.getY());
                        return true;
    
                    }
    
                }
            }
            // 处理手势结束
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_UP:
                    endGesture();
                    break;
            }
            return false;
        }
    
        private void endGesture() {
            isScorllStart = false;
            isUpAndDown = false;
    //        Log.e("a", "AA:over");
            moveOver();
        }
    
        public abstract void moveDirection(View v, int direction, float distanceX, float distanceY);
    
        public abstract void moveUpAndDownDistance(MotionEvent event, int distance, int distanceY);
    
        public abstract void moveOver();
    
        public abstract void Touch(float x, float y);
    
    
        @Override
        public boolean onDown(MotionEvent e) {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public void onShowPress(MotionEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public void onLongPress(MotionEvent e) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                                float distanceY) {
            float mOldY = e1.getY();
            int y = (int) e2.getRawY();
            if (!isScorllStart) {
                if (Math.abs(distanceX) / Math.abs(distanceY) > 2) {
                    // 左右滑动
                    isUpAndDown = false;
                    isScorllStart = true;
                } else if (Math.abs(distanceY) / Math.abs(distanceX) > 3) {
                    // 上下滑动
                    isUpAndDown = true;
                    isScorllStart = true;
                } else {
                    isScorllStart = false;
                }
            } else {
                // 算滑动速度的问题了
                if (isUpAndDown) {
                    // 是上下滑动,关闭左右检测
                    if (mOldY + 5 < y) {
                        moveUpAndDownDistance(e2, -3, (int) distanceY);
                    } else if (mOldY + 5 > y) {
                        moveUpAndDownDistance(e2, 3, (int) distanceY);
                    }
                }
            }
            return true;
        }
    
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                               float velocityY) {
    //        Log.e("a", "AA:A" + velocityX + ":" + velocityY);
            if (isUpAndDown)
                return false;
            if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
                    && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
                // Fling left
                moveDirection(null, MOVE_TO_LEFT, e1.getX() - e2.getX(), e1.getY() - e2.getY());
            } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
                    && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
                // Fling right
                moveDirection(null, MOVE_TO_RIGHT, e2.getX() - e1.getX(), e2.getY() - e1.getY());
            } else if (e1.getY() - e2.getY() > FLING_MIN_DISTANCE
                    && Math.abs(velocityY) > FLING_MIN_VELOCITY) {
                // Fling up
                moveDirection(null, MOVE_TO_UP, 0, e1.getY() - e2.getY());
            } else {
                // Fling down
                moveDirection(null, MOVE_TO_DOWN, 0, e2.getY() - e1.getY());
            }
            return false;
        }
    }
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#70c8f9"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <com.demo2.fly.FlightSeatView
                android:id="@+id/fsv"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="30dp"
                android:layout_weight="1" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <Button
                    android:id="@+id/btn_clear"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@android:color/transparent"
                    android:onClick="clear"
                    android:text="clear"
                    android:textColor="@android:color/white"
                    tools:ignore="UsingOnClickInXml" />
    
                <Button
                    android:id="@+id/btn_zoom"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@android:color/transparent"
                    android:onClick="zoom"
                    android:text="ok"
                    android:textColor="@android:color/white"
                    tools:ignore="UsingOnClickInXml" />
    
                <Button
                    android:id="@+id/btn_goto"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@android:color/transparent"
                    android:onClick="gotoposition"
                    android:text="goto"
                    android:textColor="@android:color/white"
                    tools:ignore="UsingOnClickInXml" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    
    

    MainActivity.class

    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import com.demo2.fly.FlightSeatView;
    
    public class MainActivity extends AppCompatActivity {
    
        FlightSeatView mFlightSeatView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getSupportActionBar().hide();
            setContentView(R.layout.activity_fly_main);
            mFlightSeatView = findViewById(R.id.fsv);
    
            // 用户最多选着10个位置
            mFlightSeatView.setMaxSelectStates(10);
    
            // 模拟已经被选中
            setTestData();
        }
    
        // 显示飞机动画
        public void zoom(View v) {
            mFlightSeatView.startAnim(true);
        }
    
        // 指定位置
        public void gotoposition(View v) {
            mFlightSeatView.goCabinPosition(FlightSeatView.CabinPosition.Middle);
        }
    
        // 出清选中
        public void clear(View v) {
            mFlightSeatView.setEmptySelecting();
        }
    
        private void setTestData() {
            for (int i = 0; i < 6; i++) {
                for (int j = 0; j < 9; j = j + 2) {
                    mFlightSeatView.setSeatSelected(j, i);
    
                }
            }
    
            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < 8; j = j + 2) {
                    mFlightSeatView.setSeatSelected(i + 20, j);
    
                }
            }
    
            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < 8; j = j + 3) {
                    mFlightSeatView.setSeatSelected(i + 35, j);
    
                }
            }
    
            for (int i = 11; i < 20; i++) {
                for (int j = 0; j < 8; j = j + 4) {
                    mFlightSeatView.setSeatSelected(i + 35, j);
    
                }
            }
            mFlightSeatView.invalidate();
        }
    }
    

    相关文章

      网友评论

        本文标题:Android 飞机选座

        本文链接:https://www.haomeiwen.com/subject/hakbpltx.html