android 自定义view 实现电影选座功能

电影选座

绘制思路

1、现有的组件不能满足我的需求
2、通过自定义view实现
3、绘制一个可方便方便设置每一行需要显示的座位数量、显示排数、点击选择/取消等功能的view

绘制步骤

1、继承view
class MyGridView extends View
2、实现相应的方法

  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getMeasuredWidth();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

    }
    
    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        }

3、绘制

a、初始化画笔

  private Paint paint = new Paint();//绘制图片的画笔
    private TextPaint textPaintXH = new TextPaint();//绘制序号的画笔
    private TextPaint textPaint = new TextPaint();//绘制提示文字的画笔

 textPaint.setColor(getResources().getColor(R.color.color_BF_BF_BF));
        textPaint.setTextSize(12);
        textPaintXH.setColor(getResources().getColor(R.color.color_D9_D9_D9));
        textPaintXH.setTextSize(12);

b、初始化需要绘制的bitmap

  private Bitmap checkBit;//选中的图片
    private Bitmap uncheckBit;//未选中的图片
    private Bitmap payed;//已售的图片
    private Bitmap checkedBit;//选中的图片说明

  checkBit = getImageSize2(2,R.drawable.in_check);
        uncheckBit = getImageSize2(2,R.drawable.write_check);
        payed = getImageSize2(2,R.drawable.gay_check);
        checkedBit = getImageSize2(2,R.drawable.red_check);

c、设定一个默认的座位的宽高

/默认图片的宽高
    private int defaultImgW = 80;
    private int defaultImgH = 80;

d、绘制bitmap

 canvas.drawBitmap(uncheckBit,left,top,paint);

e、绘制文字

 canvas.drawText(text,left,getBaseLine(textPaint,top,top+ceter),textPaint);

f、绘制提示的色块和文字

  //绘制底部提示快
        canvas.drawBitmap(uncheckBit,3*defaultImgW,(cow+1)*defaultImgH,paint);
        canvas.drawText("未选",3*defaultImgW+uncheckBit.getWidth()+10,getBaseLine(textPaint,(cow+1)*defaultImgH,(cow+1)*defaultImgH+defaultImgH/2),textPaint);

        canvas.drawBitmap(payed,6*defaultImgW,(cow+1)*defaultImgH,paint);
        canvas.drawText("已售",6*defaultImgW+payed.getWidth()+10,getBaseLine(textPaint,(cow+1)*defaultImgH,(cow+1)*defaultImgH+defaultImgH/2),textPaint);

        canvas.drawBitmap(checkedBit,9*defaultImgW,(cow+1)*defaultImgH,paint);
        canvas.drawText("已选",9*defaultImgW+checkedBit.getWidth()+10,getBaseLine(textPaint,(cow+1)*defaultImgH,(cow+1)*defaultImgH+defaultImgH/2),textPaint);

4、配置点击事件并返回选中的座位集合

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN){
            int x = (int) event.getX();
            int y  = (int) event.getY();
            for (Seat seat : list) {
                if (x>seat.getLeft()&&x<seat.getRight()&&y>seat.getTop()&&y<seat.getBottown()){

                    if (seat.getCheckstaues()==0){
                        seats.add(seat);
                    }else {
                        for (int i = 0; i < seats.size(); i++) {
                            if (seats.get(i).getText().equals(seat.getText())){
                                seats.remove(i);
                            }
                        }
                    }
                    oncheckClick.checked(seat.getText(),seats);
                }
            }

        }
        return true;
    }

5、优化

//缩放bitmap
  private Bitmap getImageSize2(int scall,int id){
        Bitmap srcBitmap= BitmapFactory.decodeResource(getResources(), id);
        Log.i("byte","srcbyte "+srcBitmap.getByteCount());

        Bitmap newBitmap =Bitmap.createBitmap(
                srcBitmap.getWidth()/scall,srcBitmap.getHeight()/scall, Bitmap.Config.ARGB_8888);
        Canvas canvas =new Canvas(newBitmap);
        //同时缩放会显示原图大小
        canvas.scale((1f/scall),(1f/scall));
        canvas.drawBitmap(srcBitmap,0,0,new Paint());
        Log.i("byte","newBitmap "+newBitmap.getByteCount());
        return newBitmap;
    }

完整代码

public class MyGridView extends View {
    private Paint paint = new Paint();//绘制图片的画笔
    private TextPaint textPaintXH = new TextPaint();//绘制序号的画笔
    private TextPaint textPaint = new TextPaint();//绘制提示文字的画笔
    private Context context;//上下文
    private ArrayList mList;//需要绘制的座位的集合
    private int cow = 0;//行数
    private int row = 0;//列数
    private Bitmap checkBit;//选中的图片
    private Bitmap uncheckBit;//未选中的图片
    private Bitmap payed;//已售的图片
    private Bitmap checkedBit;//选中的图片说明
    //默认图片的宽高
    private int defaultImgW = 80;
    private int defaultImgH = 80;
    List<Seat> list = new ArrayList<>();//存储绘制的座位的信息
    List<Seat> checkedSeat = new ArrayList<>();//选中的座位信息
    private OncheckClick oncheckClick;

    public void setOncheckClick(OncheckClick oncheckClick) {
        this.oncheckClick = oncheckClick;
    }

    //    List<T> mlist = new ArrayList<T>();
    public MyGridView(Context context) {
        super(context);
        this.context = context;
    }

    public MyGridView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    public MyGridView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }
    private int width=0;
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getMeasuredWidth();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        this.canvas = canvas;
        initSetting();
        onDraws(canvas,context,row,cow);

    }

    private void initSetting() {
        if (mList!=null&&mList.size()>0){
            if (row>0){
                cow = (mList.size() /row) ;
                defaultImgW = width/(row+1);
            }

        }
        checkBit = getImageSize2(2,R.drawable.in_check);
        uncheckBit = getImageSize2(2,R.drawable.write_check);
        payed = getImageSize2(2,R.drawable.gay_check);
        checkedBit = getImageSize2(2,R.drawable.red_check);
        textPaint.setColor(getResources().getColor(R.color.color_BF_BF_BF));
        textPaint.setTextSize(12);
        textPaintXH.setColor(getResources().getColor(R.color.color_D9_D9_D9));
        textPaintXH.setTextSize(12);
    }

    public void setNum(int num){
        this.row = num;
    }
    public  void setData(ArrayList mlist){
        this.mList = mlist;
        invalidate();
    }


    private Bitmap getImageSize2(int scall,int id){
        Bitmap srcBitmap= BitmapFactory.decodeResource(getResources(), id);
        Log.i("byte","srcbyte "+srcBitmap.getByteCount());

        Bitmap newBitmap =Bitmap.createBitmap(
                srcBitmap.getWidth()/scall,srcBitmap.getHeight()/scall, Bitmap.Config.ARGB_8888);
        Canvas canvas =new Canvas(newBitmap);
        //同时缩放会显示原图大小
        canvas.scale((1f/scall),(1f/scall));
        canvas.drawBitmap(srcBitmap,0,0,new Paint());
        Log.i("byte","newBitmap "+newBitmap.getByteCount());
        return newBitmap;
    }


    private int 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 Canvas canvas;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    public void UpDipmap(List<Seat> seat){
        this.checkedSeat = seat;
        invalidate();
    }
    private boolean istag = false;

    private void onDraws(Canvas canvas, Context context, int row, int cow) {
        list.clear();
        for (int i = 1; i <=cow+1; i++) {
            for (int j = 0; j <=row; j++) {
                istag= false;
                int left = (int) (j*defaultImgW);
                int top = (int) ((i-1)*defaultImgH);
                int right = left+defaultImgW;
                int bottown = top+defaultImgH;
                int ceter = defaultImgH/2;
                if (j==0){
                    canvas.drawText(i+"",defaultImgW-20,getBaseLine(textPaint,top,top+ceter),textPaintXH);
                }else if (i*j<mList.size()){
                    String seatnum = new StringBuilder().append(i).append("排").append(j).append("坐").toString();
                    int num = j-1+((i-1)*row);
                    Log.e("onDraws: ------",num+"" );
                    if (num<mList.size()){
                        Seat seat = new Seat();
                        seat.setLeft(left);
                        seat.setRight(right);
                        seat.setTop(top);
                        seat.setBottown(bottown);
                        seat.setText(seatnum);
                        seat.setPosition(num);
                        String text = new StringBuilder().append(i).append(",").append(j).append(",").append(mList.get(num)).toString();
                        if (checkedSeat.size()>0&&checkedSeat!=null){
                            for (Seat seat1 : checkedSeat) {
                                if (num == seat1.position ){
                                    istag = true;
                                }
                            }
                        }
                        if (istag){
                            seat.setCheckstaues(1);
                            canvas.drawBitmap(checkBit,left,top,paint);
                        }else {
                            seat.setCheckstaues(0);
                            canvas.drawBitmap(uncheckBit,left,top,paint);
                        }
                        canvas.drawText(text,left,getBaseLine(textPaint,top,top+ceter),textPaint);
                        list.add(seat);
                    }
                }

            }
        }
        //绘制底部提示快
        canvas.drawBitmap(uncheckBit,3*defaultImgW,(cow+1)*defaultImgH,paint);
        canvas.drawText("未选",3*defaultImgW+uncheckBit.getWidth()+10,getBaseLine(textPaint,(cow+1)*defaultImgH,(cow+1)*defaultImgH+defaultImgH/2),textPaint);

        canvas.drawBitmap(payed,6*defaultImgW,(cow+1)*defaultImgH,paint);
        canvas.drawText("已售",6*defaultImgW+payed.getWidth()+10,getBaseLine(textPaint,(cow+1)*defaultImgH,(cow+1)*defaultImgH+defaultImgH/2),textPaint);

        canvas.drawBitmap(checkedBit,9*defaultImgW,(cow+1)*defaultImgH,paint);
        canvas.drawText("已选",9*defaultImgW+checkedBit.getWidth()+10,getBaseLine(textPaint,(cow+1)*defaultImgH,(cow+1)*defaultImgH+defaultImgH/2),textPaint);
    }
    private List<Seat> seats = new ArrayList<>();

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN){
            int x = (int) event.getX();
            int y  = (int) event.getY();
            for (Seat seat : list) {
                if (x>seat.getLeft()&&x<seat.getRight()&&y>seat.getTop()&&y<seat.getBottown()){

                    if (seat.getCheckstaues()==0){
                        seats.add(seat);
                    }else {
                        for (int i = 0; i < seats.size(); i++) {
                            if (seats.get(i).getText().equals(seat.getText())){
                                seats.remove(i);
                            }
                        }
                    }
                    oncheckClick.checked(seat.getText(),seats);
                }
            }

        }
        return true;
    }
    interface OncheckClick{
        void checked(String text,List<Seat> seats);
    }
    class Seat{
        private int left ;
        private int top ;
        private int right ;
        private int bottown;
        private String text;
        private int position;
        private int checkstaues;

        public int getCheckstaues() {
            return checkstaues;
        }

        public void setCheckstaues(int checkstaues) {
            this.checkstaues = checkstaues;
        }

        public int getLeft() {
            return left;
        }

        public void setLeft(int left) {
            this.left = left;
        }

        public int getTop() {
            return top;
        }

        public void setTop(int top) {
            this.top = top;
        }

        public int getRight() {
            return right;
        }

        public void setRight(int right) {
            this.right = right;
        }

        public int getBottown() {
            return bottown;
        }

        public void setBottown(int bottown) {
            this.bottown = bottown;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

        public int getPosition() {
            return position;
        }

        public void setPosition(int position) {
            this.position = position;
        }
    }
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐