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;
}
}
}