android x轴翻转动画如何使摄像头xy轴移动

3DMAX怎么使用坐标轴,X,Y,Z可以直接拖着轴移动的_百度知道
3DMAX怎么使用坐标轴,X,Y,Z可以直接拖着轴移动的
我有更好的答案
基本操作,试一试就知道了,光标停在红箭头上就只在X轴移动,停在绿箭头就只在Y轴移动,停在黄色方框上就是XY轴同时都能移动
采纳率:81%
来自团队:
对啊!那你的问题到底是什么呢?
为您推荐:
其他类似问题
坐标轴的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。android中用重力传感器怎么判断Y轴的移动距离_百度知道
android中用重力传感器怎么判断Y轴的移动距离
我有更好的答案
sensor类一般不需要new而是通过SensorManager的方法获得
二 介绍SensorManager类
SDK解释:“SensorManager lets you access the device's sensors. Get an instance of this class by calling Context.getSystemService() with the argument SENSOR_SERVICE.
Always make sure to disable sensors you don&#39.
///距离传感器
int
TYPE_ROTATION_VECTOR
A constant describing a rotatio三轴加速度感应器 返回三个坐标轴的加速度
单位m&#47一 介绍Sensor类
SDK只有一句介绍“Class representing a sensor。通过传入参数SENSOR_SERVICE参数调用Context. Use getSensorList(int) to get the list of available Sensors.”,表示一个感应器的类,可以使用getSensorList方法(此方法属于接下来要讲的SensorManager)获得所有可用的感应器,该方法返回的是一个List&方向感应器 已过时 可以使用方法获得
int
TYPE_PRESSURE
A constant describing a pressure sensor type
/&#47.getSystemService方法可以获得一个sensor的实例;/翻转传感器
int
TYPE_TEMPERATURE
A constant describing a temperature sensor type
&#47,要关闭感应器。忽略这一点肯能导致几个小时就耗尽电池. Failing to do so can drain the battery
下面的列表显示了,Sensor所提供的所有服务
----------------------------------------------------------------------------------------------------------------------------------------------------------
Constants
int
TYPE_ACCELEROMETER
A constant describing an accelerometer sensor type. ///陀螺仪 可判断方向 返回三个坐标轴上的角度
int
TYPE_LIGHT
A constant describing an light sensor type.
//用于列出所有感应器
int
TYPE_GRAVITY
A constant describing a gravity sensor type.
/t need, especially when you/温度传感器 单位 摄氏度
----------------------------------------------------------------------------------------------------------------------------------------------------------
此类中包含的方法都是get型的 用来获取所选sensor的一些属性.
&#47,注意当屏幕关闭时,系统不会自动关闭感应器。
三 常用的感应器
(1) 加速度感应器
可以通过这个感应器获得三个浮点型
y-axis
z-axis
可参阅《android 高级编程2》中的一个插图分析次数据
X Y Z分别对应values[0]到[2]
X表示左右移动的加速度
Y表示前后移动的加速度
Z表示垂直方向的加速度
下面先看一个基本的获取加速的/重力感应器
int
TYPE_GYROSCOPE
A constant describing a gyroscope sensor type
&#47.getOrientation() instead. //磁场感应 返回三个坐标轴的数值
微特斯拉
int
TYPE_ORIENTATION
This constant is deprecated. use SensorM线性加速度
int
TYPE_MAGNETIC_FIELD
A constant describing a magnetic field sensor type.
//光线感应器 单位 lux 勒克斯
int
TYPE_LINEAR_ACCELERATION
A constant describing a linear acce压力感应器
单位 千帕斯卡
int
TYPE_PROXIMITY
A constant describing an proximity sensor type.
/Sensor&gt。永远记得确保当你不需要的时候,特别是Activity暂定的时候. Note that the system will not disable sensors automatically when the screen turns off. ”
SensorManager 允许你访问设备的感应器;s2
int
A constant describing all sensor types.
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。分享几个Android摄像头采集的YUV数据旋转与镜像翻转的方法 - 简书
分享几个Android摄像头采集的YUV数据旋转与镜像翻转的方法
最近在做直播推流方面的工作,因为需要添加美白,滤镜,AR贴图等效果。所以不能简单的使用SufaceView加Camera的方式进行数据的采集,而是需要对Camera采集到的YUV数据进行相关的处理之后然后再进行推流的操作,YUV数据的返回接口。
public void onPreviewFrame(byte[] data, Camera camera) {
当然,美白,滤镜,AR贴图等效果采用的是第三方的SDK了。除此之外,因为Android摄像头采集的数据都是有一定的旋转的。一般前置摄像头有270度的旋转,后置摄像头有90的旋转。所以要对YUV数据进行一定旋转操作,同时对于前置摄像头的数据还要进行镜像翻转的操作。网上一般比较多的算法是关于旋转的
private byte[] rotateYUVDegree90(byte[] data, int imageWidth, int imageHeight) {
byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
// Rotate the Y luma
int i = 0;
for (int x = 0; x & imageW x++) {
for (int y = imageHeight - 1; y &= 0; y--) {
yuv[i] = data[y * imageWidth + x];
// Rotate the U and V color components
i = imageWidth * imageHeight * 3 / 2 - 1;
for (int x = imageWidth - 1; x & 0; x = x - 2) {
for (int y = 0; y & imageHeight / 2; y++) {
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
private byte[] rotateYUVDegree270(byte[] data, int imageWidth, int imageHeight) {
byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
// Rotate the Y luma
int i = 0;
for (int x = imageWidth - 1; x &= 0; x--) {
for (int y = 0; y & imageH y++) {
yuv[i] = data[y * imageWidth + x];
}// Rotate the U and V color components
i = imageWidth * imageH
for (int x = imageWidth - 1; x & 0; x = x - 2) {
for (int y = 0; y & imageHeight / 2; y++) {
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
上述两个算法分别用于90度旋转(后置摄像头)和270度旋转(前置摄像头),但是对于前置摄像头的YUV数据是需要镜像的,参照上面的算法,实现了前置摄像头的镜像算法。
private byte[] rotateYUVDegree270AndMirror(byte[] data, int imageWidth, int imageHeight) {
byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
// Rotate and mirror the Y luma
int i = 0;
int maxY = 0;
for (int x = imageWidth - 1; x &= 0; x--) {
maxY = imageWidth * (imageHeight - 1) + x * 2;
for (int y = 0; y & imageH y++) {
yuv[i] = data[maxY - (y * imageWidth + x)];
// Rotate and mirror the U and V color components
int uvSize = imageWidth * imageH
int maxUV = 0;
for (int x = imageWidth - 1; x & 0; x = x - 2) {
maxUV = imageWidth * (imageHeight / 2 - 1) + x * 2 + uvS
for (int y = 0; y & imageHeight / 2; y++) {
yuv[i] = data[maxUV - 2 - (y * imageWidth + x - 1)];
yuv[i] = data[maxUV - (y * imageWidth + x)];
至于更多关于YUV和推流的知识,目前我还不是很了解。这篇文章也主要是分享这三个算法。
存在问题 移动端录像在yuv数据上存在如下问题: 无论android还是ios都不能直接从摄像头取出颜色空间为i420的数据,所以在编码前需要进行格式转换。 而且由于所取图像得分辨率必须是摄像头所提供分辨率中得一组,所以有可能需要裁剪。 另外由于(1)想让无论用户哪个方向拿...
1、前言 Android端的视频相关的开发,大概一直是整个Android生态,以及Android API中,最为分裂以及兼容性问题最为突出的一部分。摄像头,以及视频编码相关的API,Google一直对这方面的控制力非常差,导致不同厂商对这两个API的实现有不少差异,而且从A...
一、文章说明 上周开始写直播相关的文章,写了一篇手机直播总览的文章,没想到得到大家很多赞和关注,在此感谢大家支持。这篇文章将会讲述Android摄像头相关的知识,希望能对大家有所帮助。文章开始会简单介绍一下摄像头的成像原理,然后会讲述摄像头采集相关的一些图片格式,之后会讲述...
在Android做过自定义Camera的朋友应该都知道,我们可以通过public void onPreviewFrame(byte[] data, Camera camera)回调中获取摄像头采集到的每一帧的数据,但是这个byte[] data的数据格式YUV...
//我所经历的大数据平台发展史(三):互联网时代 o 上篇http://www.infoq.com/cn/articles/the-development-history-of-big-data-platform-paet02 编者按:本文是松子(李博源)的大数据平台发展史...
JY把”墨语花开时“公众号的文章发到了朋友圈! 她说,你说的,花开了,你来了,真好!为什么,我们来了,你不愿意呢? 花开了吗? 我有点茫然,更不知所措…… 她说,春天了,在江南,繁花开遍,看花的人那么快乐,多好…… 为什么花开了,你还要捂着? 我不知道! 我也爱满眼繁花,我...
用手账记录生活,今天参考了网上朋友的作品,然后做成了这样。
纯文字版的,没有图,后来贴了几个胶带图案,但好像也是多余。我想每天尝试一个新的版图。手账就是要好玩。
今天这个方格的感觉就是字一定要漂亮。我这个字。。。。。。汗
一直觉得没话写,今天认真总结一下,发现有...
很多失意的人 都知道这座森林 想遁入森林 他也来到森林边缘 却发现一块牌子 不得入森 森林有异样的香气 树叶有奇特的纹路 看久了就会眩晕 他萎地而坐 闭眼的时候 森林里一棵藤蔓 对他说 你若让我穿透你的心 我便让你进入 他的念头松动 我本不是寻死 若真的死了 倒也真是清净 ...
《复归于婴儿》1 健康是生命的自在无病状态。生理的疾病大多是由于心理的疾病引起的。潜意识会制造神经症,这是现代医学知道的事情,潜意识制造各种疾病是需要被验证的事情。今年6月到现在我闺蜜正在经历这样的过程,由于信佛曾经想有出家的想法,这两年头发越来越白,她自己也不清楚原因,感...
妖狐在岩石背后等待时机之时,她想起五百年前耶律道长对自己的点化,每日认真修习不敢懈怠,只等有缘人的出现。 话说五百年前,耶律道长途经此地遇一妖狐,本该收妖替天行道,但道长看出小妖狐本性纯良,聪明乖巧,又具有极高造化,便心生喜悦,决定传她心法,引她修归正道,同时赐名为“雨诺”...在上一篇最后提出了一个注意点:当自定义的MatrixImageView如ViewPager、ListView等带有滑动效果的ViewGroup中时,ImageView自定义的拖动事件会和ViewGroup的滑动事件冲突,并且指出了冲突原因是由于ViewGroup拦截了Move事件的缘故。如果对于Touch事件的分发机制不甚了解的话,可以参考下这篇。
这篇文章将会在MatrixImageView的基础上,以ViewPager作为测试容器做进一步优化。
当进行缩放操作时,手势不会同时触发ViewPager的滑动切换Item事件。
当进行拖动操作时,除非图片已经到达左右边界,否则不触发ViewPager的滑动切换Item事件。
当进行拖动操作时,若图片左边缘到达左边界,则可以向左滑动触发ViewPager切换至前一个I当图片右边缘到达右边界,则可以向右滑动触发ViewPager的切换至后一个Item。
每个down-up(cancel)事件周期内只执行一种类型的事务操作(缩放、拖动或者ViewPager切换Item),防止多重事务互相干扰。
将事务处理封装到MatrixImageView类内,提供状态接口给ViewPager使用,方便适配多种ViewGroup。
当ViewPager内嵌MatrixImageView时,由于MatrixImgaeView在Down事件中返回了true,表明ViewPager将捕获本次完整的Touch事件(Move-Ponit_Down-UP等等),其中最重要的一个事件便是Move事件,因为ViewPager自身需要捕获Move事件在onTouch中进行切换Item操作,MatrixImageView的捕获意味着它将无法响应。不过,ViewPager本身控制着Touch事件的下发操作,每个Touch事件的下发都遵从从上至下层层递归,在MatrixImageView真正获得Move事件前,Move事件必须经过ViewPager的onInterceptTouchEvent和dispatchTouchEvent事件,前者执行拦截操作后者执行下发操作。ViewPager便是在onInterceptTouchEvent中对Move事件进行了过滤,当移动距离超过一定值时,它会拦截掉Move事件,阻止MatrixImageView继续处理Touch事件的权利,转而让自身的onTouch事件处理。于是,我们要做的便是重写onInterceptTouchEvent事件,通过判断MatrixImageView的状态决定是否拦截。
由于容器ViewPager在满足条件的时候会拦截掉子View的touch事件,因此需要自定义个ViewPager修改拦截逻辑。当MatriImageView进行缩放和拖动时,我们不希望ViewPager拦截。具体代码如下:
public class AlbumViewPager extends ViewPager implements OnChildMovingListener {
当前子控件是否处理拖动状态
private boolean mChildIsBeingDragged=false;
public boolean onInterceptTouchEvent(MotionEvent arg0) {
if(mChildIsBeingDragged)
return false;
return super.onInterceptTouchEvent(arg0);
public void startDrag() {
// TODO Auto-generated method stub
mChildIsBeingDragged=true;
public void stopDrag() {
// TODO Auto-generated method stub
mChildIsBeingDragged=false;
public interface OnChildMovingListener{
public void
startDrag();
public void
stopDrag();
&通过判断变量mChildIsBeingDragged的值决定是否拦截,而mChildIsBeingDragged的值通过OnChildMovingListener接口由MatriImageView进行设置。别忘了在PagerAdapter的instantiateItem中给MatriImageView设置监听接口
MatrixImageView imageView = (MatrixImageView) imageLayout.findViewById(R.id.image);
imageView.setOnMovingListener(AlbumViewPager.this);
ViewPager的改造便完成了,只需要新增一个变量和实现一个接口,之后对于事件的拦截操作都转到了MatrixImageView中。
接下去看下改造后的MatrixImageView的onTouch方法。
/** 和ViewPager交互相关,判断当前是否可以左移、右移
boolean mLeftD
boolean mRightD
是否第一次移动 */
boolean mFirstMove=false;
private PointF mStartPoint = new PointF();
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
//设置拖动模式
mMode=MODE_DRAG;
mStartPoint.set(event.getX(), event.getY());
isMatrixEnable();
startMove();
checkDragable();
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
reSetMatrix();
stopMove();
case MotionEvent.ACTION_MOVE:
if (mMode == MODE_ZOOM) {
setZoomMatrix(event);
}else if (mMode==MODE_DRAG) {
setDragMatrix(event);
stopMove();
case MotionEvent.ACTION_POINTER_DOWN:
if(mMode==MODE_UNABLE) return true;
mMode=MODE_ZOOM;
mStartDis = distance(event);
case MotionEvent.ACTION_POINTER_UP:
return mGestureDetector.onTouchEvent(event);
其中加红部分的代码都是修改后的代码,逐一分析。
子控件开始进入移动状态,令ViewPager无法拦截对子控件的Touch事件
private void startDrag(){
if(moveListener!=null) moveListener.startDrag();
子控件开始停止移动状态,ViewPager将拦截对子控件的Touch事件
private void stopDrag(){
if(moveListener!=null) moveListener.stopDrag();
startDrag和stopDrag方法很简单,就是调用ViewPager传递进来的OnChildMovingListener接口进行mChildIsBeingDragged的设置。当监听到down事件时,表示开始拖动,当接收到up和cancel事件时,表示结束拖动,以这个逻辑来说,ViewGroup将永远无法拦截touch事件,所以我们还需要在其他地方设置stopDrag事件,后面说明。
接下去是在down事件中执行checkDragable方法:
根据当前图片左右边缘设置可拖拽状态
private void checkDragable() {
mLeftDragable=true;
mRightDragable=true;
mFirstMove=true;
float[] values=new float[9];
getImageMatrix().getValues(values);
//图片左边缘离开左边界,表示不可右移
if(values[Matrix.MTRANS_X]&=0)
mRightDragable=false;
//图片右边缘离开右边界,表示不可左移
if((mImageWidth)*values[Matrix.MSCALE_X]+values[Matrix.MTRANS_X]&=getWidth()){
mLeftDragable=false;
该方法将会重置mLeftDragable、mRightDragable、mFirstMove三个参数的状态。mLeftDragable表示当前状态下的Matrix可以向左拖动,mRightDragable表示当前状态下的Matrix可以向右拖动,mFirstMove为每次完整touch事件(从down到up或cancel)中的第一次拖动操作标志。其中mLeftDragable和mRightDragable都是根据Matrix矩阵的数值计算出来的。
由于前面功能需求的时候说过"每个down-up(cancel)事件周期内只执行一种类型的事务操作(缩放、拖动或者ViewPager切换Item)",因此当进行缩放操作时,就不会再执行切换Item操作了,可以等缩放结束后执行up操作时stopDrag。而Move操作重点就是要识别是切换item还是拖动图片了。查看修改后的setDragMatrix代码
设置拖拽状态下的Matrix
@param event
public void setDragMatrix(MotionEvent event) {
if(isZoomChanged()){
float dx = event.getX() - mStartPoint.x; // 得到x轴的移动距离
float dy = event.getY() - mStartPoint.y; // 得到x轴的移动距离
//避免和双击冲突,大于10f才算是拖动
if(Math.sqrt(dx*dx+dy*dy)&10f){
mStartPoint.set(event.getX(), event.getY());
//在当前基础上移动
mCurrentMatrix.set(getImageMatrix());
float[] values=new float[9];
mCurrentMatrix.getValues(values);
dy=checkDyBound(values,dy);
dx=checkDxBound(values,dx,dy);
mCurrentMatrix.postTranslate(dx, dy);
setImageMatrix(mCurrentMatrix);
stopDrag();
和当前矩阵对比,检验dx,使图像移动后不会超出ImageView边界
@param values
private float checkDxBound(float[] values,float dx,float dy) {
float width=getWidth();
if(!mLeftDragable&&dx&0){
//加入和y轴的对比,表示在监听到垂直方向的手势时不切换Item
if(Math.abs(dx)*0.4f&Math.abs(dy)&&mFirstMove){
stopDrag();
if(!mRightDragable&&dx&0){
//加入和y轴的对比,表示在监听到垂直方向的手势时不切换Item
if(Math.abs(dx)*0.4f&Math.abs(dy)&&mFirstMove){
stopDrag();
mLeftDragable=true;
mRightDragable=true;
if(mFirstMove) mFirstMove=false;
if(mImageWidth*values[Matrix.MSCALE_X]&width){
if(values[Matrix.MTRANS_X]+dx&0){
dx=-values[Matrix.MTRANS_X];
else if(values[Matrix.MTRANS_X]+dx&-(mImageWidth*values[Matrix.MSCALE_X]-width)){
dx=-(mImageWidth*values[Matrix.MSCALE_X]-width)-values[Matrix.MTRANS_X];
处理逻辑是这样的:
1.判断当前缩放级别是否是原始缩放级别(isZoomChanged()),如果未缩放过那将可以直接切换Item,在这直接stopDrag。
2.若进行了缩放,那判断是否累移动了10f,当移动了10f之后计算出x轴和y轴的移动量,并且通过checkDyBound方法计算出y轴的真实移动量
3.进入checkDxBound方法,首先判断当前是否能够左移,如果不能左移而实际的x轴偏移量是向左的,那就返回x的偏移量为0,防止左移。同时,如果当前是第一次移动,那就表示本次不是左移操作,而是向前切换item,于是执行stopDrag方法,令ViewPager拦截掉对MatrixImageView的事件分发。另外在这里加入和Y轴偏移量的对比,是为了防止执行的是垂直方向的滑动而导致stopDrag,ViewPager自身对于X轴偏移量/2小于Y轴偏移量的情况是不当成切换Item意图的,这里设置为*0.4可以保证不冲突。
4.右移同理。
5.当第一次左移和右移判断结果都不是切换Item后,将mLeftDragable和mRightDragable都设置为true,表示可以正常移动了。之后就和单个MatrixImageView的拖动处理一样了。
到此便完成了内嵌到ViewGroup内的MatriImageView的改造。下面还有两点显示优化。
首先在reSetMatrix中加入了新的功能:当缩放后的图片高度未达到ImageView高度时,在up和cancel之后会将其Y轴居中,防止&放大图片-Y轴移动图片-缩小图片&导致图片位置不对称。异常图效果如下:
重置Matrix
private void reSetMatrix() {
if(checkRest()){
mCurrentMatrix.set(mMatrix);
setImageMatrix(mCurrentMatrix);
//判断Y轴是否需要更正
float[] values=new float[9];
getImageMatrix().getValues(values);
float height=mImageHeight*values[Matrix.MSCALE_Y];
if(height&getHeight()){
//在图片真实高度小于容器高度时,Y轴居中,Y轴理想偏移量为两者高度差/2,
float topMargin=(getHeight()-height)/2;
if(topMargin!=values[Matrix.MTRANS_Y]){
mCurrentMatrix.set(getImageMatrix());
mCurrentMatrix.postTranslate(0, topMargin-values[Matrix.MTRANS_Y]);
setImageMatrix(mCurrentMatrix);
优化了缩放操作的缩放x轴对称轴选择问题。在"图片放大-移动X轴-缩小图片"时,若直接以ImageView中心点为缩放原点,可能会导致缩放后的图片边缘离开ImageView边界。
出错图效果如下:
设置缩放Matrix
@param event
private void setZoomMatrix(MotionEvent event) {
//只有同时触屏两个点的时候才执行
if(event.getPointerCount()&2) return;
float endDis = distance(event);// 结束距离
if (endDis & 10f) { // 两个手指并拢在一起的时候像素大于10
float scale = endDis / mStartD// 得到缩放倍数
mStartDis=endD//重置距离
mCurrentMatrix.set(getImageMatrix());//初始化Matrix
float[] values=new float[9];
mCurrentMatrix.getValues(values);
scale = checkMaxScale(scale, values);
PointF centerF=getCenter(scale,values);
mCurrentMatrix.postScale(scale, scale,centerF.x,centerF.y);
setImageMatrix(mCurrentMatrix);
获取缩放的中心点。
@param scale
@param values
private PointF getCenter(float scale,float[] values) {
//缩放级别小于原始缩放级别时或者为放大状态时,返回ImageView中心点作为缩放中心点
if(scale*values[Matrix.MSCALE_X]&mScale||scale&=1){
return new PointF(getWidth()/2,getHeight()/2);
float cx=getWidth()/2;
float cy=getHeight()/2;
//以ImageView中心点为缩放中心,判断缩放后的图片左边缘是否会离开ImageView左边缘,是的话以左边缘为X轴中心
if((getWidth()/2-values[Matrix.MTRANS_X])*scale&getWidth()/2)
//判断缩放后的右边缘是否会离开ImageView右边缘,是的话以右边缘为X轴中心
if((mImageWidth*values[Matrix.MSCALE_X]+values[Matrix.MTRANS_X])*scale&getWidth())
cx=getWidth();
return new PointF(cx,cy);
通过判断图片宽度,决定是以ImageView中点为X轴缩放原点,还是以左右边缘为缩放原点。
目前为止MatrixImageView的功能基本完善了,具体代码还是放在我的Github上的。该View如果有问题的可以在这篇文章下留言或私信我。
阅读(...) 评论()> 博客详情
package&me.
import&android.animation.AnimatorS
import&android.animation.ObjectA
import&android.app.A
import&android.os.B
import&android.view.MotionE
import&android.view.V
import&android.widget.ImageV
import&android.widget.RelativeL
public&class&MoveImgActivity&extends&Activity&{
&&&&ImageView&
&&&&private&int&containerW
&&&&private&int&containerH
&&&&float&lastX,&lastY;
&&&&RelativeLayout&
&&&&@Override
&&&&protected&void&onCreate(Bundle&savedInstanceState)&{
&&&&&&&&super.onCreate(savedInstanceState);
&&&&&&&&setContentView(R.layout.activity_move_img);
&&&&&&&&rl&=&(RelativeLayout)&findViewById(R.id.rl);
&&&&&&&&iv&=&(ImageView)&findViewById(R.id.iv);
&&&&&&&&iv.setOnTouchListener(new&View.OnTouchListener()&{
&&&&&&&&&&&&@Override
&&&&&&&&&&&&public&boolean&onTouch(View&v,&MotionEvent&event)&{
&&&&&&&&&&&&&&&&switch&(event.getActionMasked())&{
&&&&&&&&&&&&&&&&&&&&case&MotionEvent.ACTION_DOWN:
&&&&&&&&&&&&&&&&&&&&&&&&lastX&=&event.getRawX();
&&&&&&&&&&&&&&&&&&&&&&&&lastY&=&event.getRawY();
&&&&&&&&&&&&&&&&&&&&&&&&return&
&&&&&&&&&&&&&&&&&&&&case&MotionEvent.ACTION_MOVE:
&&&&&&&&&&&&&&&&&&&&&&&&//&&不要直接用getX和getY,这两个获取的数据已经是经过处理的,容易出现图片抖动的情况
&&&&&&&&&&&&&&&&&&&&&&&&float&distanceX&=&lastX&-&event.getRawX();
&&&&&&&&&&&&&&&&&&&&&&&&float&distanceY&=&lastY&-&event.getRawY();
&&&&&&&&&&&&&&&&&&&&&&&&float&nextY&=&iv.getY()&-&distanceY;
&&&&&&&&&&&&&&&&&&&&&&&&float&nextX&=&iv.getX()&-&distanceX;
&&&&&&&&&&&&&&&&&&&&&&&&//&不能移出屏幕
&&&&&&&&&&&&&&&&&&&&&&&&if&(nextY&&&0)&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&nextY&=&0;
&&&&&&&&&&&&&&&&&&&&&&&&}&else&if&(nextY&&&containerHeight&-&iv.getHeight())&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&nextY&=&containerHeight&-&iv.getHeight();
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&if&(nextX&&&0)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&nextX&=&0;
&&&&&&&&&&&&&&&&&&&&&&&&else&if&(nextX&&&containerWidth&-&iv.getWidth())
&&&&&&&&&&&&&&&&&&&&&&&&&&&&nextX&=&containerWidth&-&iv.getWidth();
&&&&&&&&&&&&&&&&&&&&&&&&//&属性动画移动
&&&&&&&&&&&&&&&&&&&&&&&&ObjectAnimator&y&=&ObjectAnimator.ofFloat(iv,&"y",&iv.getY(),&nextY);
&&&&&&&&&&&&&&&&&&&&&&&&ObjectAnimator&x&=&ObjectAnimator.ofFloat(iv,&"x",&iv.getX(),&nextX);
&&&&&&&&&&&&&&&&&&&&&&&&AnimatorSet&animatorSet&=&new&AnimatorSet();
&&&&&&&&&&&&&&&&&&&&&&&&animatorSet.playTogether(x,&y);
&&&&&&&&&&&&&&&&&&&&&&&&animatorSet.setDuration(0);
&&&&&&&&&&&&&&&&&&&&&&&&animatorSet.start();
&&&&&&&&&&&&&&&&&&&&&&&&lastX&=&event.getRawX();
&&&&&&&&&&&&&&&&&&&&&&&&lastY&=&event.getRawY();
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&return&
&&&&&&&&&&&&}
&&&&&&&&});
&&&&@Override
&&&&public&void&onWindowFocusChanged(boolean&hasFocus)&{
&&&&&&&&super.onWindowFocusChanged(hasFocus);
&&&&&&&&//&这里来获取容器的宽和高
&&&&&&&&if&(hasFocus)&{
&&&&&&&&&&&&containerHeight&=&rl.getHeight();
&&&&&&&&&&&&containerWidth&=&rl.getWidth();
activity_move_img.xml
&?xml&version="1.0"&encoding="utf-8"?&
&RelativeLayout&xmlns:android="http://schemas.android.com/apk/res/android"
&&&&xmlns:tools="http://schemas.android.com/tools"
&&&&android:id="@+id/rl"
&&&&android:layout_width="match_parent"
&&&&android:layout_height="match_parent"
&&&&tools:context="com.example.android.interactivechart.MoveImgActivity"&
&&&&&ImageView
&&&&&&&&android:id="@+id/iv"
&&&&&&&&android:src="@drawable/b1"
&&&&&&&&android:layout_width="wrap_content"
&&&&&&&&android:layout_height="wrap_content"&/&
&/RelativeLayout&
http://developer.android.com/reference/android/animation/AnimatorSet.html#playTogether(android.animation.Animator...)

我要回帖

更多关于 android y轴翻转动画 的文章

 

随机推荐