你买美团电影票选座位失败的时候,你选座位是怎么选的?

本篇文章已经授权微信公共账号 guolin_blog(郭霖)独家发布
不知道大家有没有跟我一样的感觉,看了那么多的介绍自定义控件原理、事件分发机制的书籍,文章,教程,依然还是不能随心所欲的自定义控件。甚至是看了再忘,忘了再看,很尴尬有木有。有的时候真正遇到了事件冲突一脸懵逼有木有。其实导致这些问题原因很简单,一句话就可以说明问题了“纸上得来终觉浅,绝知此事要躬行。”正如这篇介绍的文章里所说的,从不会到会,秘诀是重复。我们需要一遍一遍仔细的阅读理解,并用代码实践来验证,学到的这些概念流程知识,这样才会在脑海里留下比较深刻的印象,才能自如的应用学到的知识。学习view的绘制原理,事件分发机制的目的是为了自定义控件,所以学了这些知识后,就需要通过实战多自定义几个控件,来不停的应用,消化这些知识。当你真正自己写了几个自定义控件后,你会发现view的绘制原理,事件分发机制这些东西都是死的,真正麻烦的是绘制逻辑,绘图逻辑,计算逻辑以及一些相关的数学知识。
下面开始正题,不知道大家有没有用过,淘宝电影客户端(淘票票)买过电影票,纵观各类在线选座app的在线选座功能 淘宝在线选座功能用户体验最好,用起来最顺手,夸张点说已经到了炉火纯青的地步,下面我们看一下效果:
效果分析:
整个控件分成几个部分,座位图区域、座位缩略图区域、行号区域、屏幕区域
1、座位图可以自由的移动缩放,放大缩小移动后会自动回弹到合适的位置,选中座位会自动放大到合适比例。
2、行号部分跟着座位图缩放以及上下移动,屏幕区域跟着座位图左右移动缩放。
3、当手指按下的时候会出现缩略图,缩略图上有个红色的方框表示,当前能看到的区域,并且跟随缩略图的移动。
涉及到的知识点:
view的绘制原理、事件分发机制这些就不说了,这些是基础,这里并不打算介绍,网上有非常多的这方面的资料。
1、矩阵Matrix使用,通过Matrix来进行移动、缩放
2、弹性移动、弹性缩放。
3、手势监听的使用通过GestureDetector、ScaleGestureDetector来获得缩放比例幅度。
通过以下几个核心部分来介绍,其他部分都是类似的思路实现
1、绘制座位图
2、座位图的缩放和移动
3、座位图自动回弹、自动缩放
4、缩略图部分的绘制实现
至于其他部分比如影院荧幕,左侧的行号部分思路跟座位图的实现思路是一致的。
1、绘制座位图
座位图实际上就是个二维矩阵,有行数和列数,我们只需要根据行数和列数加上一定的间距绘制即可。
void drawSeat() {
for (int i = 0; i & i++) {
for (int j = 0; j & j++) {
int left = j * seatBitmap.getWidth() + j *
int top = i * seatBitmap.getHeight() + i * verS
int seatType = getSeatType(i, j);
switch (seatType) {
case SEAT_TYPE_AVAILABLE:
seatCanvas.drawBitmap(seatBitmap, left, top, paint);
case SEAT_TYPE_NOT_AVAILABLE:
case SEAT_TYPE_SELECTED:
seatCanvas.drawBitmap(checkedSeatBitmap, left, top, paint);
case SEAT_TYPE_SOLD:
seatCanvas.drawBitmap(seatSoldBitmap, left, top, paint);
isNeedDrawSeatBitmap = false;
getSeatType()方法是用来判断当前的座位是否可用,是否已经卖出去,是否已经选中,根据这些状态绘制不同的座位图。
2、座位图的缩放和移动
移动缩放功能使用 Matirx来实现,Matrix在android中可以用来对图片进行缩放、移动、旋转等变换。
matrix本身是一个3*3的矩阵,矩阵中的每一个值都代表一个变换属性,如下
实际上就是一个有9个元素的数组
float[] value=new float[9];
通过 matrix.getValues(value);可以获得具体的值。
value[0]表示的是缩放的x值
value[1]表示的是斜切的x值
value[2] 表示x轴上平移的值
value[3]表示的是斜切的y值
value[4]表示的y轴上的缩放比例
value[5]表示的是y轴上的平移的值
Matrix类有一些方法可以对这些值进行改变
setScale(float sx, float sy, float px, float py) :设置x轴和y周上的缩放比例,px,py表示缩放的中心点。
setTranslate(float dx, float dy) :设置x轴和y周上的偏移量。
与之对应的还有这么两个方法:
postScale(float sx, float sy, float px, float py)
postTranslate(float dx, float dy)
那么post跟set有什么区别呢,简单理解就是set直接,把之前的值给覆盖了,而post是在之前的值的基础上进行变换。比如现在你已经向左移动了10个像素,这时候你用setTranslate(5,5)这个时候直接变成了移动5个像素了,而用post就是在10的基础上在移动5个像素就变成15了。
以上是Matrix的使用方法,Canvas对象有个drawBitmap方法可以接收一个matrix,这样就可以在绘图的时候使用matrix进行变换了。
座位图平移缩放的实现思路:
要做两件事情来实现座位图的缩放移动
1、获取平移的值和放大缩小的比例
重写onTouchEvent方法来计算获取移动的x值和y值
使用ScaleGestureDetector这个类来帮我们获取放大缩小的比例,使用非常简单,创建一个ScaleGestureDetector的对象,然后在onTouchEvent方法了调用一下ScaleGestureDetector.onTouchEvent(event);即可
2、根据获取到的值对座位图进行平移和缩放
获取到了平移的值和缩放的比例后,使用matrix.postScale(x,y)和matrix.postTrans(x,y)进行对应的变换即可,变换完了调用view的invalidate方法让view重新绘制matrix即可生效。
下面只列出了核心代码,省掉了一些逻辑,完整代码请到github中查看。
ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.OnScaleGestureListener() {
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = detector.getScaleFactor();
matrix.postScale(scaleFactor, scaleFactor, scaleX, scaleY);
invalidate();
return true;
onTouchEvent处理逻辑
public boolean onTouchEvent(MotionEvent event) {
int y = (int) event.getY();
int x = (int) event.getX();
scaleGestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
int downDX = Math.abs(x - downX);
int downDY = Math.abs(y - downY);
if (downDX & 10 || downDY & 10) {
int dx = x - lastX;
int dy = y - lastY;
matrix.postTranslate(dx, dy);
invalidate();
case MotionEvent.ACTION_UP:
return true;
onDraw的时候
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(seat, matrix, paint);
3、座位图的自动回弹、自动缩放效果的实现
为什么要自动回弹呢,因为你操作的时候有可能把座位图移到屏幕外,缩放的时候把图缩放的比较小,或者比较大,这个时候程序通过计算给你自动的移动到一个比较合适的位置,比较合适的缩放大小。这样就有着不错的使用体验。
自动回弹实现的思路:
当我们手指屏幕上移动然后抬起的时候会触发MotionEvent.ACTION_UP事件,这个时候我们可以通过matrix对象来获取当前的移动的位置,如果当前移动的值不符合我们的规则,我们就将座位图按照规则移动到指定位置。
移动规则如下(参考的淘票票客户端的移动逻辑)
座位图整个大小不超过控件大小的时候:
往左边滑动,自动回弹到行号右边
往右边滑动,自动回弹到右边
往上,下滑动,自动回弹到顶部
座位图整个大小超过控件大小的时候:
往左侧滑动,回弹到最右边,往右侧滑回弹到最左边
往上滑动,回弹到底部,往下滑动回弹到顶部
以上的移动规则的实现大家可以查看具体源码中的autoScroll()方法的实现,这里就不贴出来了。
移动和缩放涉及到一个弹性移动和缩放的问题,所谓弹性移动就是有动画效果的移动。因为如果你当前在100,100 这个位置,你需要移动到800,100这个位置,如果你直接移动到800这个位置,而不是通过,先移动到110,在移动到120。。。一直到800这样一段一段的移动。那么移动效果将是非常僵硬的,刷的闪过去的感觉,效果非常不好。
弹性移动的实现思路就是:
比如要从100,100 移动到800,100这个位置,很明显 x轴要移动700个像素。那么把这700个像素的移动我们分成10次移动来实现,每次移动700/10=70个像素,两次移动之间间隔50毫秒,就跟帧动画似的,这样就会有一个弹性的动画效果。
通过handler来实现代码如下:
int FRAME_COUNT = 10;
int time = 15;
Handler handler = new Handler(new Handler.Callback() {
public boolean handleMessage(Message msg) {
if (count & FRAME_COUNT) {
MoveInfo moveInfo = (MoveInfo) msg.
float moveXLength = moveInfo.moveXL
float moveYLength = moveInfo.moveYL
float xValue = moveXLength / FRAME_COUNT;
float yValue = moveYLength / FRAME_COUNT;
matrix.postTranslate(xValue, yValue);
invalidate();
Message message = Message.obtain();
message.obj = msg.
handler.sendMessageDelayed(message, time);
count = 0;
return true;
弹性缩放的原理跟弹性移动的原理一致
4、缩略图部分的绘制实现
缩略图是座位图的缩小版,缩略图的宽高和座位图的宽高有一定比例,比如五分之一。当然这是可以根据效果来调整的。之所以必须是座位图的一定比例,是因为缩略图上有一个动态的红色方框表示当前可见的座位区域,这个红色方框是需要根据座位图的移动而移动的。比例确定后,就这可以根据座位图的移动来移动红色方框。举个例子来说-如果当前座位图向上移动了100个像素,那么缩略图中对应的红色方框部分向下移动 100/4=250个像素即可。
绘制概览图代码:
Bitmap drawOverview() {
float rectSize = seatBitmap.getHeight() / overviewS
rectW = column * rectWidth + (column - 1) * overviewSpacing + overviewSpacing * 2;
rectH = row * rectSize + (row - 1) * overviewVerSpacing + overviewVerSpacing * 2;
Canvas canvas = new Canvas(overviewBitmap);
canvas.drawRect(0, 0, rectW, rectH, paint);
paint.setColor(Color.WHITE);
for (int i = 0; i & i++) {
float top = i * rectSize + i * overviewVerSpacing + overviewVerS
for (int j = 0; j & j++) {
int seatType = getSeatType(i, j);
switch (seatType) {
case SEAT_TYPE_AVAILABLE:
paint.setColor(Color.WHITE);
case SEAT_TYPE_NOT_AVAILABLE:
case SEAT_TYPE_SELECTED:
paint.setColor(overview_checked);
case SEAT_TYPE_SOLD:
paint.setColor(overview_sold);
left = j * rectWidth + j * overviewSpacing + overviewS
canvas.drawRect(left, top, left + rectWidth, top + rectSize, paint);
return overviewB
绘制概览图上的红色方框
* 绘制概览图
void drawOverviewBorder(Canvas canvas) {
int left = (int) -getTranslateX();
if (left & 0) {
left /= overviewS
left /= getMatrixScaleX();
int currentWidth = (int) (getTranslateX() + (column * seatBitmap.getWidth() + spacing * (column - 1)) * getMatrixScaleX());
if (currentWidth & getWidth()) {
currentWidth = currentWidth - getWidth();
currentWidth = 0;
int right = (int) (rectW - currentWidth / overviewScale / getMatrixScaleX());
float top = -getTranslateY()+headH
if (top & 0) {
top /= overviewS
top /= getMatrixScaleY();
if (top & 0) {
top += overviewVerS
int currentHeight = (int) (getTranslateY() + (row * seatBitmap.getHeight() + verSpacing * (row - 1)) * getMatrixScaleY());
if (currentHeight & getHeight()) {
currentHeight = currentHeight - getHeight();
currentHeight = 0;
int bottom = (int) (rectH - currentHeight / overviewScale / getMatrixScaleY());
canvas.drawRect(left, top, right, bottom, redBorderPaint);
控件性能优化
千辛万苦终于把控件做出来了,结果一运行卡的不要不要的。特别是行数列数一多,卡顿的懵逼了。这个时候呢我们要对性能进行优化,总结下来主要从以下几个方面:
1、避免在onDraw中创建对象,分配内存,把paint对象的创建放在初始化函数里面。这一步其实非常重要因为我们使用canvas绘图的时候需要paint对象,往往不同的地方需要不同paint,这样一来,创建的paint对象就比较多了,在加上onDraw方法可能会执行多次。频繁的创建对象会造成gc,导致卡顿。当然了不止是paint对象,其他的对象创建也要能少则少。
2、避免不必要的绘制逻辑,在需要的时候才绘制。这个需要我们根据控件的绘制逻辑来进行调整,同样也是非常重要。
3、总的原则就是想尽一切办法把onDraw方法的执行控制在16ms以内,就不会卡了。
最后看看我们实现的效果
源码地址:
如果有bug或者问题欢迎指出。
一开始的时候为了方便,整个座位图是在一个Bitmap上绘制的,这会导致一个问题,当行数列数一多,就会创建出一个尺寸巨大的Bitmap,直接导致卡顿或者oom
不用bitmap,采用实时绘制,只绘制座位图在屏幕上能看见的部分。
弹性移动,缩放是自己用handler实现的‘(&﹏&)′ 不要自己用handler实现 ,用属性动画来做,也就是ValueAnimator来做。
写代码,的时候还是要考虑代码的运行效率的。。。对onDraw方法来说“差之毫厘失之千里”
教你敲代码实现在线电影票选座功能
网上购票如此的方便,那么我们能用HTML5+JavaScript实现一款在线电影票的选票功能吗?
答案是肯定的,今天我们就来借助jQuery的jQuery-Seat-Charts插件来实现在线电影...
HTML5与JQuery混合应用:选座功能逻辑简单实现
功能目标:
假设为了实现一个选座功能,用HTML5和JQuery来实现:
首先要将座位分布画出来,但往往是大量的座位,因此要借助JQuery语句通过循环来实现;
然后用户点击其中一个座位后,要得到该座...
https://github.com/richzertuche/ZSeatSelector
http://blog.csdn.net/qifengdeqingchen/article/details/
http://blog.csdn.net/qifengdeqin...
这是一个简单的电影院选座效果,实现该效果大致分为三步:自定义view进行绘制;手势缩放效果的实现;手势触摸被选和未被选效果的实现;先来看第一步,效果的绘制;public class MoveSeatV...
&em&电影&/em&做&em&选座功能&/em&有情侣坐,也可以用在演唱会等等。综合评分:1 收藏评论(1)举报 所需: 3积分/C币 开通VIP 立即下载 评论共有1条 goodsoft-29 10...
js html 实现在线&em&选座功能&/em& 立即下载
上传者: 哎一入江湖岁月催 时间:
综合评分: 0 积分/C币:5
jQuery+css+js+html5实现订座功能(仿&em&电影&/em&票...
没有更多推荐了,为何我的微信电影票选座位的时候不显示颜色,我重装了好几次都不行?
按时间排序
重装系统就可以解决了,系统U盘制作及重装系统的操作步骤为:1.制作启动U盘:到实体店买个4-8G的U盘(可以要求老板帮忙制作成系统U盘即可省略以下步骤),上网搜索下载装机员U盘启动PE制作工具,将U盘插入电脑运行此软件制作成启动U盘。2.复制系统文件:上网到装机员论坛下载WINXP或WIN7等操作系统的GHO文件,复制到U盘或启动工具指定的U盘文件夹下。3.设置U盘为第一启动磁盘:开机按DEL键(笔记本一般为F2或其它)进入BIOS设置界面,进入BOOT选项卡设置USB磁盘为第一启动项(注:部分电脑需要在此时插入U盘进行识别才能设置)。4.U盘启动并重装系统:插入U盘启动电脑,进入U盘启动界面按提示利用下载来的GHO文件进行克隆安装。5.如果有系统光盘(没有也可以去电脑商店购买),则将系统光盘插入光驱,开机后按DEL键(笔记本一般为F2或根据屏幕底行提示字符)进入CMOS,并在BOOT选项卡中设置光驱(CD-ROM或DVD-ROM)为第一启动项。重启进入光盘启动菜单,选择将系统安装到C区,再按提示操作即可。
空间更新了说说后,好友空间动态没有收到提醒,可能会有以下几种情况影响:一、您 空间设置访问权限为“回答问题”、或者“指定好友可见”,好友不在指定的权限之内,这两种情况在您更新内容后,好友空间动态里不会收到提醒;二、您 空间设置“自己的动态更新不通知到所有好友”的情况,好友空间动态则无法显示。建议您修改动态隐私设置三、好友的个人中心动态设置了忽略您的 空间更新,建议联系好友,让对方设置关注您的 空间更新;四、好友的个人中心动态设置了忽略说说更新,建议联系好友,让对方设置关注好友的说说更新。
位置已经被人订过了
感谢您为社区的和谐贡献力量请选择举报类型
经过核实后将会做出处理感谢您为社区和谐做出贡献
确定要取消此次报名,退出该活动?
请输入私信内容:有一对情侣买了两张后角落的电影票,于是我和朋友四个决定一探究竟
这些回帖亮了
为什么不去看前面那仨人3p?
就这上座率人家换到其他座你们还有脸跟着?找骂的节奏,不作不死
sangxinbguang,
卧槽 你们实在是太坏了!大快人心!
说不定是俩基佬呢!
然后他们卿卿我我的时候,你们四个做啥
昨天就看到了。这只是选座而已并没有买下吧。买下了其实也没什么卵。因为假如电影院那么空是可以随便坐的
影院私欲.avi
到了之后发现是一个大妈和一个大爷,分分钟教你们四个做人
去你妹的,老子买最后一排的时候最烦你们这种人了,电影不好好看就知道偷瞄小情侣
后来我进了场都不按座位坐了,就迟到5分钟进去,看哪块没人就坐哪块
6个基佬一起玩
4个搞基的贱人!我好不容易约了志玲姐姐看场电影,容易吗?
到时候发现人家只是单纯的想坐在后排看电影。。。。
那2个人的心情很难想像啊
笑死我了,假如整场就你们九个人那该出现什么情景
你们撒币吗,都坐在人家周围了,人家是有多脑残才会搞事给你们看
就这上座率人家换到其他座你们还有脸跟着?找骂的节奏,不作不死
为什么不去看前面那仨人3p?
如果后面坐满了还好,就你们几个人就笑死了。
??,电影院一般不会爆满,碰见你们算我倒霉。来,@,我们坐前面去。
您需要登录后才可以回复,请或者
427人参加团购259.00元&469.00元
1073人参加团购299.00元&890.00元
1379人参加团购659.00元&1399.00元
1506人参加团购175.00元&395.00元
99人参加团购35.90元&75.00元
141人参加团购189.00元&539.00元
242人参加团购199.00元&829.00元
36人参加团购145.00元&228.00元
163人参加团购39.00元&89.00元
34人参加团购89.00元&299.00元
138人参加团购99.00元&319.00元
21人参加团购109.00元&239.00元【图文】关于消费者对在网上购买电影票并直接选定座位的看法_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&100W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
关于消费者对在网上购买电影票并直接选定座位的看法
阅读已结束,下载本文到电脑
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 买电影票怎么选座位 的文章

 

随机推荐