A. 求助,怎么用android实现控件的3D立体旋转效果
实现水平滑动,所以可在手势抬起的时候进行判断并处理,是滑动显得流畅,代码如下:
java">packagecom.example.rotation3dview;
importandroid.content.Context;
importandroid.graphics.Camera;
importandroid.graphics.Canvas;
importandroid.graphics.Matrix;
importandroid.util.AttributeSet;
importandroid.view.MotionEvent;
importandroid.view.VelocityTracker;
importandroid.view.View;
importandroid.view.ViewDebug.HierarchyTraceType;
importandroid.view.ViewGroup;
importandroid.widget.ImageView;
importandroid.widget.Scroller;
{
privateintmCurScreen=1;
//滑动的速度
privatestaticfinalintSNAP_VELOCITY=500;
;
privateintmWidth;
privateScrollermScroller;
privateCameramCamera;
privateMatrixmMatrix;
//旋转的角度,可以进行修改来观察效果
privatefloatangle=90;
publicRote3DView(Contextcontext,AttributeSetattrs){
super(context,attrs);
mScroller=newScroller(context);
mCamera=newCamera();
mMatrix=newMatrix();
initScreens();
}
publicvoidinitScreens(){
ViewGroup.LayoutParamsp=newViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
for(inti=0;i<3;i++){
this.addView(newImageView(this.getContext()),i,p);
}
((ImageView)this.getChildAt(0)).setImageResource(R.drawable.page1);
((ImageView)this.getChildAt(1)).setImageResource(R.drawable.page2);
((ImageView)this.getChildAt(2)).setImageResource(R.drawable.page3);
}
@Override
protectedvoidonLayout(booleanchanged,intl,intt,intr,intb){
intchildLeft=0;
finalintchildCount=getChildCount();
for(inti=0;i<childCount;i++){
finalViewchildView=getChildAt(i);
if(childView.getVisibility()!=View.GONE){
finalintchildWidth=childView.getMeasuredWidth();
childView.layout(childLeft,0,childLeft+childWidth,childView.getMeasuredHeight());
childLeft+=childWidth;
}
}
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
finalintwidth=MeasureSpec.getSize(widthMeasureSpec);
finalintwidthMode=MeasureSpec.getMode(widthMeasureSpec);
if(widthMode!=MeasureSpec.EXACTLY){
thrownewIllegalStateException("仅支持精确尺寸");
}
finalintheightMode=MeasureSpec.getMode(heightMeasureSpec);
if(heightMode!=MeasureSpec.EXACTLY){
thrownewIllegalStateException("仅支持精确尺寸");
}
finalintcount=getChildCount();
for(inti=0;i<count;i++){
getChildAt(i).measure(widthMeasureSpec,heightMeasureSpec);
}
scrollTo(mCurScreen*width,0);
}
privatefloatmDownX;
@Override
publicbooleanonTouchEvent(MotionEventevent){
if(mVelocityTracker==null){
mVelocityTracker=VelocityTracker.obtain();
}
//将当前的触摸事件传递给VelocityTracker对象
mVelocityTracker.addMovement(event);
floatx=event.getX();
switch(event.getAction()){
caseMotionEvent.ACTION_DOWN:
if(!mScroller.isFinished()){
mScroller.abortAnimation();
}
mDownX=x;
break;
caseMotionEvent.ACTION_MOVE:
intdisX=(int)(mDownX-x);
mDownX=x;
scrollBy(disX,0);
break;
caseMotionEvent.ACTION_UP:
=mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
intvelocityX=(int)velocityTracker.getXVelocity();
if(velocityX>SNAP_VELOCITY&&mCurScreen>0){
snapToScreen(mCurScreen-1);
}elseif(velocityX<-SNAP_VELOCITY&&mCurScreen<getChildCount()-1){
snapToScreen(mCurScreen+1);
}else{
snapToDestination();
}
if(mVelocityTracker!=null){
mVelocityTracker.recycle();
mVelocityTracker=null;
}
break;
}
returntrue;
}
@Override
publicvoidcomputeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
publicvoidsnapToDestination(){
setMWidth();
finalintdestScreen=(getScrollX()+mWidth/2)/mWidth;
snapToScreen(destScreen);
}
publicvoidsnapToScreen(intwhichScreen){
whichScreen=Math.max(0,Math.min(whichScreen,getChildCount()-1));
setMWidth();
intscrollX=getScrollX();
intstartWidth=whichScreen*mWidth;
if(scrollX!=startWidth){
intdelta=0;
intstartX=0;
if(whichScreen>mCurScreen){
setPre();
delta=startWidth-scrollX;
startX=mWidth-startWidth+scrollX;
}elseif(whichScreen<mCurScreen){
setNext();
delta=-scrollX;
startX=scrollX+mWidth;
}else{
startX=scrollX;
delta=startWidth-scrollX;
}
mScroller.startScroll(startX,0,delta,0,Math.abs(delta)*2);
invalidate();
}
}
privatevoidsetNext(){
intcount=this.getChildCount();
Viewview=getChildAt(count-1);
removeViewAt(count-1);
addView(view,0);
}
privatevoidsetPre(){
intcount=this.getChildCount();
Viewview=getChildAt(0);
removeViewAt(0);
addView(view,count-1);
}
privatevoidsetMWidth(){
if(mWidth==0){
mWidth=getWidth();
}
}
}
实现立体效果,添加如下代码:
/*
*当进行View滑动时,会导致当前的View无效,该函数的作用是对View进行重新绘制调用drawScreen函数
*/
@Override
protectedvoiddispatchDraw(Canvascanvas){
finallongdrawingTime=getDrawingTime();
finalintcount=getChildCount();
for(inti=0;i<count;i++){
drawScreen(canvas,i,drawingTime);
}
}
publicvoiddrawScreen(Canvascanvas,intscreen,longdrawingTime){
//得到当前子View的宽度
finalintwidth=getWidth();
finalintscrollWidth=screen*width;
finalintscrollX=this.getScrollX();
//偏移量不足的时
if(scrollWidth>scrollX+width||scrollWidth+width<scrollX){
return;
}
finalViewchild=getChildAt(screen);
finalintfaceIndex=screen;
finalfloatcurrentDegree=getScrollX()*(angle/getMeasuredWidth());
finalfloatfaceDegree=currentDegree-faceIndex*angle;
if(faceDegree>90||faceDegree<-90){
return;
}
finalfloatcenterX=(scrollWidth<scrollX)?scrollWidth+width
:scrollWidth;
finalfloatcenterY=getHeight()/2;
finalCameracamera=mCamera;
finalMatrixmatrix=mMatrix;
canvas.save();
camera.save();
camera.rotateY(-faceDegree);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX,-centerY);
matrix.postTranslate(centerX,centerY);
canvas.concat(matrix);
drawChild(canvas,child,drawingTime);
canvas.restore();
}
B. 在Android里怎么让一张png图片循环旋转,就像雷达里面那个,不停地旋转,可以有按钮控制开关的
使用android中的旋转动画,让imageview以自身为中心旋转,在写个Button控制动画的开始结束
可参考:http://blog.csdn.net/feng88724/article/details/6318430
C. android 图片旋转
Android UI之ImageView旋转的几种方式
Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.ic_launcher)).getBitmap();
Matrix matrix = new Matrix();
matrix.setRotate(90);
Bitmap new = Bitmap.create(bitmap,0,bitmap.getWidth(),0,bitmap.getHeight(),matrix);
image.setBitmapResource(bitmap);
如果程序不断获取新的bitmap重新设置给ImageView的话,那么bitmap在不断旋转,又不回收内存,浪费大大哒,不推荐使用。
可以通过在xml中设置ImageView的属性来实现,如
android:rotation="90" //写死固定方向没问题
,这样。
动态调用如下:
iv.setPivotX(image.getWidth()/2);
iv.setPivotY(image.getHeight()/2);//支点在图片中心
iv.setRotation(90);
可以使用ImageView配合属性动画实现,如
iv.animate().rotation(90); //会好看一下,只有第一次加载时是这样的
或者普通动画
Animation rotateAnimation = new RotateAnimation(lastAngle, progress, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1);
rotateAnimation.setFillAfter(true);
rotateAnimation.setDuration(50);
rotateAnimation.setRepeatCount(0);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateImage.startAnimation(rotateAnimation);
Matrix matrix=new Matrix();
rotateImage.setScaleType(ScaleType.MATRIX); //required
matrix.postRotate((float) progress, pivotX, pivotY);
iv.setImageMatrix(matrix);
D. android 怎么让图片实现朝Z轴的方向旋转RotateAnimation是x y方向的,我想要包含z方向的
RotateAnimation是不可以绕Z轴旋转的,如果LZ想要实现Z轴旋转效果,可以看下matrix这个类(实际还是opengl),可以给LZ例举下:
rotateX(float degree) 绕着x轴旋转degree个度数
rotateY(float degree) 绕着y轴旋转degree个度数
rotateZ(float degree) 绕着z轴旋转degree个度数
E. Android属性动画之旋转动画
CSDN同步发布
旋转动画有三种
角度增加是逆时针方向旋转。注意,如果旋转角度是90度的话,最终View会不可见。
当要旋转的View尺寸很小的时候,效果很好,但是当View很大的时候,就出问题了。如下所示:
当时很奇怪为啥会这样呢?最后是在这篇文章 实现翻转卡片的动画效果 看到了一个叫cameraDistance的东西,然后感觉可能这个有用,试了试果然可以。
View的 getCameraDistance 方法。
View的 setCameraDistance 方法,看注释。
注意:注释中的这段这个相机距离用“深度像素”来表示。默认的距离依赖屏幕的密度。例如,在一个中等密度的屏幕上,默认的距离是1280。在高密度的屏幕上,默认距离是1920。我认为这个单位是dp。1280dp,1920dp。我的测试机density是2.75,通过getCameraDistance方法,获取到的值是3520.0,3520.0除以2.75就是1280。
注意:关于设置cameraDistance,建议始终使用大于此视图高度(绕X轴旋转)或宽度(Y轴旋转)的相机距离。而且这个距离得比较大才行,我测试下来得10000以上才可以。如下所示:
同样需要设置 cameraDistance
平时这个用的比较多应该,也比较简单。也不涉及 cameraDistance 的东西。
参考链接
F. Android中怎么使一张图片绕Y轴自动旋转
动画animation能实现围绕自身某个点旋转和围绕外部屏幕上某个点旋转.
G. android制作一个可以旋转textview怎么实现
android制作一个可以旋转textview需要用到补间动画,然后用textview调用该补间动画。在andorid studio中实现步骤如下。
1、首先在一个layout布局中创建一个textView控件,并定义id。代码如下:
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
2、然后创建anim文件,在然后文件中创建一个xml文件,文件中为tv_rotate。文件内容如下。
运行之后textView就可以旋转了。
H. Android自定义控件之可平移、缩放、旋转图片控件
先上效果图
单点拖动图片对图片进行平移操作。双手缩放图片大小和旋转图片到一定的角度。图片缩放的时候 不能大于最大的缩放因子和小于最小的缩放因子。大于最大缩放因子或者小于最小缩放因子需要对图像进行回弹。图片旋转的角度只能为90度的倍数,不满足90度要进行回弹。图片回弹要一个渐变的效果。
大体思路: 首先,Android中提供了Matrix类可以对图像进行处理。其次,要显示一张图片最容易想到的就是ImageView。回弹要求渐变的过程,可以通过属性动画进行设置。所以大体的思路是:继承ImageView,重写onTouchEvent()方法,判断事件类型,在对应的事件使用Matrix对图像进行变换。
Matrix是一个已经封装好的矩阵,最重要的作用就是对坐标点进行变换。
举个栗子:
1.某个点(x0,y0,1)通过单位矩阵E映射得到的点还是(x0,y0,1)。
3.点(x0,y0,1)通过矩阵T映射得到的点就会做如下的变换
可以看到点(x0,y0,1)经过T矩阵在x轴方向上平移了dx,在y轴方向上平移了dy。
通过以上的变换可以得到具体的思路: 我们维护一个图像对应的矩阵mCurrentMatrix,该矩阵主要是对ImageView中的图像的各个点进行映射。ImageView在容器位置摆放完成之后,置mCurrentMatrix矩阵为单位矩阵。当onTouchEvent()方法中触发单点触控并且手指进行平移的时候,调用矩阵mCurrentMatrix的postTranslate(dx,dy),对mCurrentMatrix进行变换。当手指抬起,利用变换结束后的矩阵对图像的各个点进行映射,从而得到平移变换后的图像。同理可得,在两只手指进行缩放旋转的时候,我们对矩阵mCurrentMatrix进行各种变换,当缩放旋转的事件结束再利用变换完的矩阵去映射图像的各个点,从而得到缩放、旋转后的图像。
安卓自定义View进阶 - Matrix原理
安卓自定义View进阶 - Matrix详解
首先理清事件的逻辑:
初始化图像大小和位置
缩放图像大小和控件大小自适应,平移图像中心和控件中心重合
onTouchEvent()函数
平移操作
将图像对应的矩阵进行变换。
缩放操作
mBoundRectF为记录图像边界的矩形。缩放的时候选取图像的中心进行缩放。
旋转操作
旋转的时候旋转的旋转中心也是图像的中心
图像中各个点的映射
调用ImageView的setImageMatrix(Matrix matrix)会让ImageView根据设置的matrix去重新绘制图像。
更新图像的矩形边界
获得图像的矩形,并根据矩阵映射矩形各个点的坐标。
缩放回弹
旋转回弹
一些计算方法
要求图像的变换是一个渐变的过程,很容易想到的就是属性动画。因为属性动画本身就是对值进行不断set的过程。而我们维护的矩阵也是一个值,所以很自然可以想到,如果得到回弹之前的矩阵的值以及回弹之后矩阵的值,就可以根据动画监听器中动画当前的系数值去改变矩阵的值。
对animator对象设置完监听器之后,就可以在手指抬起的时候调用属性动画的start()方法开启动画。
自定义可平移、缩放、旋转的控件主要点有两个方面:一是onTouchEvent()中判断平移、旋转、缩放的触发条件,平移位移量、缩放比例因子、旋转角度的计算。二是Matrix矩阵的应用。
I. Android 图片旋转
旋转图片通常的方法:
但是找到另一种方法,根据网上的方法改的,网络上的只支持90度旋转,其他角度有问题。但是改造后只支持90、270、360以及其负值的角度旋转:
第二种方法效率比第一种快40%左右,第二种不能支持任意角度旋转,但是需要对于需要提高效率的地方,这个方法真管用。