今天在项目里面添加来一个需求就是退出的时候,实现双击退出,由于我之前已经实现过,所以我把之前的代码拷贝过去,但是死活没有起作用,我就很郁闷,因为之前是好用的,但是期间被人修改过代码,将我之前的实现功能换成了使用ViewPager里面添加Activity的形式来实现,所有我那一个分享界面有3个Activity存在,1.最外层的Activity---ShareActivity,包含PhotoActivity和VideoActivity,默认显示的是PhotoActivity,所以我就想可能是按键事件被里面的两个捕获了,所以我重写了OnKeyDown,调试一下确实是被里面的捕获了,而且分不同的情况。总结来说就是第一个处于焦点的Activity具有捕获按键的功能,其他的都无法捕获,如果你没有去切换Activity,那么可以捕获的就是默认的Activity。
(不作直译,只是按照官方文档的结构做重点解释,不对的地方欢迎指正)
关于 Sprite KitSpritKit框架用来做图像的渲染,并且可以将一系列的纹理图像或者一些sptite(精灵)做成动画。它采用传统逐帧渲染的方式来进行渲染工作,并且期间会经历一个渲染过程(如图)。它通过图像硬件来渲染每一帧图像,SpritKit做了充分的优化,这样就可以使被渲染的对象能够在每一帧中反复的修改位置。除此之外,SptitKit框架为游戏开发提供了其他的基本功能,如背景音乐、模拟物理环境。Xcode5里集成了这个框架和相关工具,使用起来就更加方便。
(官方图)
动画和渲染工作是由SKView对象负责执行。你可以将SKView放置在window视图中,然后做渲染工作。由于SKView也是一个视图,所以按照视图层级关系,你可以将其他视图对象放置于其中,作为其子视图。
显示于场景中的节点树SKScene类是SKNode类的子类。当使用SpritKit框架的时候,一个个节点为所有内容构成一个节点树,场景对象(SKScene类的实例或者其子类的实例)就是这些节点对象树的根节点。由它来决定哪些内容要被渲染出来、如何被渲染出来。
每一个节点的坐标是根据其父类节点的系统坐标定义的。每一个节点为它其中子节点及其内容提供一些属性,例如,一个节点旋转,它里面包含的子节点及其内容也要跟着旋转。你可以使用节点树创建一个复杂的图像,整个图像会根据最外层节点属性的变化而发生变化。
SKNode类不能绘制任何东西,但是它可以将自己的属性传递给它的子节点。绘制图像的工作由SpriteKit框架中的其他子类负责。其他的子节点也不能为自己绘制内容,但它们可以为其中的内容传递一些行为。例如,你可以使用SKEffectNode对象为场景中的整个子节点树提供一个图像滤镜。恰当地对节点树结构的控制,你可以决定哪些节点可以被渲染。
所有的节点对象都是responder对象,都继承自UIResponder或NSResponder,所以你的任何节点的子类都可以响应用户输入。
Textures控制可重复使用的图像数据
渲染sprites的时候,Textures被用来分享图片。当你需要将同一张图片应用于多个sptite的时候可以使用Textures。Textures包含了从你的app目录中加载进来的图片文件。然而,Textures也可以在你的程序运行时创建并加载图片文件,这些图片文件包括你通过core graphics框架绘制的图,甚至可以将渲染的节点树放置到Textures中。如果你的游戏需要使用大量的图片,你可以控制每部分图片加载的进程来提高性能。
一个texture atlas包含一组相关的Textures,例如,游戏中为一个角色动画提供一系列textures,所以就可以将这些textures存储于texture atlas 中。Textures atlas可以提高渲染性能。
一个场景中内容的动画是通过使用动作(actions)来实现的。动作(actions)是SKAction的实例。你可以让节点去执行一些动作。这些动作在场景动画执行过程中被执行。有些动作在单帧中完成,有些可能贯穿好多帧,直到动画结束。例如你可以创建一系列的动作去改变一个节点的位置、大小、旋转、透明度等。
动作是非常实用的,你可以将动作整合在一起创建一个复杂的效果。你可以创建一组动作,让它们同时执行或者按一定队列顺序执行。也可以让他们重复的执行这些动作。
在你的场景中添加物理刚体和模拟物理环境
你可以为你的场景添加物理刚体(SKPhysicsBody),每一个物理刚体都可以定义它的形状、大小、质量和一些其他物理属性。
当将这些物理刚体添加到拥有模拟物理环境的场景中时,像摩擦力、重力将自动被执行。拥有速度和加速度的刚体之间也会存在作用力,例如碰撞产生的作用力。
通过使用SKPhysicsWorld对象为你的场景添加模拟物理环境。它可以为整个环境定义一个重力加速度,你可以使用SKPhysicsJoint对象将存在与模拟物理环境中的刚体联系在一起。
选择时间对话框,在点击对话框外面的时候对话框不会自动关闭
public void showTimeDialog() { View view = View.inflate(this, R.layout.dialog_datepicker, null); final TimePicker timePicker = (TimePicker) view.findViewById(R.id.timepicker_appoint_detail_activity); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(System.currentTimeMillis()); timePicker.setIs24HourView(true);//设置为24小时制 timePicker.setCurrentMinute(Calendar.MINUTE); AlertDialog dialog = new AlertDialog.Builder(AppointDetailActivity.this).setTitle("请选择预约时间").setView(view).setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { StringBuffer sb = new StringBuffer(); if (timePicker.getCurrentHour() < 10) { sb.append("0").append(timePicker.getCurrentHour()); if (timePicker.getCurrentMinute() < 10) { sb.append(":").append("0").append(timePicker.getCurrentMinute()); } else { sb.append(":").append(timePicker.getCurrentMinute()); } } else if (timePicker.getCurrentMinute() < 10) { sb.append(timePicker.getCurrentHour()).append(":").append("0").append(timePicker.getCurrentMinute()); } else { sb.append(timePicker.getCurrentHour()).append(":").append(timePicker.getCurrentMinute()); } appointTimeBu.setText(sb.toString()); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int arg1) { dialog.cancel(); } }).create(); dialog.setCanceledOnTouchOutside(false);//设置此行的目的是在点击本对话框以外的内容时,该对话框不会自动关闭 dialog.show(); }R.layout.dialog_datepicker//布局文件,用来展示对话框页面 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TimePicker android:id="@+id/timepicker_appoint_detail_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </LinearLayout>