您的位置:首页 > 移动开发

实现图片自旋转的同时自由移动~~

2015-10-26 20:17 246 查看
           本文介绍了如何使用SurfaceView然后实现图片的自旋转同时移动的问题。

           我采用的方法是一种比较笨的方法,主要是实在在网上找不到好的方法,所以如果有人有更好的方法,还望不吝赐教。

           我首先将一张图片旋转了三次,然后得到了4个原图片(当然弄个24张或许更好效果),然后再每次设定的时候就换一张图片你懂得我想。然后就移动图像,然后再不断的循环,最后就达到了我想要的基本效果。代码,有点乱是我根据网上一个SurfaceView改的也没有理就放上来了,还望各位海涵。好了,废话不多说了直接上代码:

        public class BallSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
MainActivity myMainActivity;// 调用该SurfaceView的上下文引用
private Ball ball;// 小球
SurfaceHolder holder;
private int count = 0;
private float runX=100;// 球的位置
private float runY=100;// 球的位置
private float maxHeight=100;// 当前运动最高的高度
private float maxWidth=100;

/**
* 18. * 球的高 19.
*/
public static final int HEIGHT = 93;
/**
* 22. * 球的宽 23.
*/
public static final int WIDTH = 93;

private boolean upDirection = false;// if true,up direction,or is down
// direction
private boolean rightDirection=false;
private static final int STEPLENGTH = 5;// 每次运动的间距

public void init(Context context) {
this.myMainActivity = (MainActivity) context;
newBall();
holder = this.getHolder();
holder.addCallback(this);
}

public BallSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
//System.out
// .println("BallSurfaceView(Context context, AttributeSet attrs)");
this.myMainActivity = (MainActivity) context;
newBall();
holder = this.getHolder();
holder.addCallback(this);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

if (canvas == null)
canvas = holder.lockCanvas();// 锁定画布

Paint p = new Paint();
int c = p.getColor();
p.setColor(Color.GRAY);// 设置背景白色
if (canvas != null) {
canvas.drawRect(0, 0, myMainActivity.screenWidth,
myMainActivity.screenHeight, p);
}
p.setColor(c);
newBall();
ball.onDraw(canvas);
holder.unlockCanvasAndPost(canvas);// 释放锁
move();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Canvas canvas = null;
if (canvas == null)
canvas = holder.lockCanvas();// 锁定画布
Paint p = new Paint();
int c = p.getColor();
p.setColor(Color.GRAY);// 设置背景白色
if (canvas != null)
canvas.drawRect(0, 0, myMainActivity.screenWidth,
myMainActivity.screenHeight, p);
p.setColor(c);
newBall();
ball.onDraw(canvas);
holder.unlockCanvasAndPost(canvas);// 释放锁
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}

public void newBall() {
ball = new Ball(this, count);
if (count != 3) {
count++;
} else {
count = 0;
}
}

public class Ball {

private static final float REDUCEPERCENTAGE = 0.35F;// 递减系数
private int stepReduce;// 每次反向运动的缩短的距离

private Paint paint;
Bitmap ballBitmap;// 球的图片
MainActivity sa;

public Ball( BallSurfaceView bsv,int count) {
//System.out.println("count:" + count);
ballBitmap = BitmapFactory.decodeResource(bsv.getResources(),
MyUtils.BALLRESOURCE[count]);// 加载图片
paint = new Paint();
sa = bsv.myMainActivity;
}

public void onDraw(Canvas canvas) {
int c = paint.getColor();// 保存颜色,之后还原为之前颜色
boundaryTest();
if (canvas != null)
canvas.drawBitmap(ballBitmap, runX, runY, paint);
paint.setColor(c);

}

/**
* 70. * 边界检测,使球不会飞出边界 71.
*/
private void boundaryTest() {

if (runY > sa.screenHeight - HEIGHT) {// 向下运动到头
upDirection = !upDirection;// 方向置反
runY = sa.screenHeight - HEIGHT;
stepReduce = (int) (maxHeight * REDUCEPERCENTAGE);
maxHeight = maxHeight + stepReduce;// 最大高度递减

}
if (runY < maxHeight) {// 向上运动到头
upDirection = !upDirection;// 方向置反
if (maxHeight >= (sa.screenHeight - HEIGHT))
return;
runY = maxHeight;

}
if (runX > sa.screenWidth - WIDTH) {// 向右运动到头
rightDirection = !rightDirection;// 方向置反
runX = sa.screenWidth - WIDTH;
stepReduce = (int) (maxWidth * REDUCEPERCENTAGE);
maxWidth = maxWidth + stepReduce;// 最大高度递减

}
if (runX < maxWidth) {// 向右运动到头
rightDirection = !rightDirection;// 方向置反
if (maxWidth >= (sa.screenWidth - WIDTH))
return;
runX = maxWidth;
}
}
}
/**
* 56. * 运动 57.
*/
private void move() {
if (maxHeight >= (myMainActivity.screenHeight - HEIGHT)) {

}else {
if (upDirection) {// 向上
runY = runY + STEPLENGTH;
} else {
runY = runY - STEPLENGTH;
}
}
if(maxWidth>=(myMainActivity.screenWidth-WIDTH)){

}else{
if(rightDirection){
runX+=STEPLENGTH;
}else{
runX-=STEPLENGTH;
}
}
}
}这是最核心的一个类,其中写出了如何实现这个SurfaceView从而实现移动和旋转的。
然后是MainActivity:public class MainActivity extends Activity {

<span style="white-space:pre"> </span>public int screenWidth;
<span style="white-space:pre"> </span>public int availableMoveHeight;
<span style="white-space:pre"> </span>private int screenHeight;
<span style="white-space:pre"> </span>BallSurfaceView bsv;
<span style="white-space:pre"> </span>private Handler mHandler = new Handler();

<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void onCreate(Bundle savedInstanceState) {
<span style="white-space:pre"> </span>super.onCreate(savedInstanceState);
<span style="white-space:pre"> </span>setContentView(R.layout.activity_main);
<span style="white-space:pre"> </span>bsv = (BallSurfaceView) findViewById(R.id.myBall);
<span style="white-space:pre"> </span>bsv.init(MainActivity.this);
<span style="white-space:pre"> </span>// 获得屏幕尺寸
<span style="white-space:pre"> </span>DisplayMetrics dm = new DisplayMetrics();
<span style="white-space:pre"> </span>dm = this.getApplicationContext().getResources().getDisplayMetrics();
<span style="white-space:pre"> </span>System.out.println("all height:" + dm.heightPixels);
<span style="white-space:pre"> </span>screenWidth = dm.widthPixels;
<span style="white-space:pre"> </span>screenHeight = dm.heightPixels;
<span style="white-space:pre"> </span>Runnable r = new Runnable() {
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void run() {
<span style="white-space:pre"> </span>availableMoveHeight = getHeightExceptTitleStatusBar(screenHeight);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>};
<span style="white-space:pre"> </span>mHandler.postDelayed(r, 200);
<span style="white-space:pre"> </span>System.out.println("screenHeight:" + availableMoveHeight);
<span style="white-space:pre"> </span>// 下两句为设置全屏

<span style="white-space:pre"> </span>/*
<span style="white-space:pre"> </span> * requestWindowFeature(Window.FEATURE_NO_TITLE);
<span style="white-space:pre"> </span> * getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
<span style="white-space:pre"> </span> * WindowManager.LayoutParams.FLAG_FULLSCREEN);
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>new RefreshThread().start();
<span style="white-space:pre"> </span>}

<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>protected void onPause() {
<span style="white-space:pre"> </span>// TODO Auto-generated method stub
<span style="white-space:pre"> </span>super.onPause();
<span style="white-space:pre"> </span>}

<span style="white-space:pre"> </span>public int getHeightExceptTitleStatusBar(int height) {
<span style="white-space:pre"> </span>Class<?> c = null;
<span style="white-space:pre"> </span>Object obj = null;
<span style="white-space:pre"> </span>Field field = null;
<span style="white-space:pre"> </span>int x = 0, statusBarHeight = 0;
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>c = Class.forName("com.android.internal.R$dimen");
<span style="white-space:pre"> </span>obj = c.newInstance();
<span style="white-space:pre"> </span>field = c.getField("status_bar_height");
<span style="white-space:pre"> </span>x = Integer.parseInt(field.get(obj).toString());
<span style="white-space:pre"> </span>statusBarHeight = getResources().getDimensionPixelSize(x);
<span style="white-space:pre"> </span>} catch (Exception e1) {
<span style="white-space:pre"> </span>e1.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT)
<span style="white-space:pre"> </span>.getTop();
<span style="white-space:pre"> </span>// statusBarHeight是上面所求的状态栏的高度
<span style="white-space:pre"> </span>int titleBarHeight = contentTop - statusBarHeight;
<span style="white-space:pre"> </span>System.out.println("title:" + titleBarHeight + "contentTop:"
<span style="white-space:pre"> </span>+ contentTop + "stat:" + statusBarHeight);
<span style="white-space:pre"> </span>return height - statusBarHeight - titleBarHeight;
<span style="white-space:pre"> </span>}

<span style="white-space:pre"> </span>private class RefreshThread extends Thread {

<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void run() {

<span style="white-space:pre"> </span>while (true) {
<span style="white-space:pre"> </span>Canvas canvas = null;
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>bsv.onDraw(canvas);
<span style="white-space:pre"> </span>} catch (Exception e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>Thread.sleep(20);
<span style="white-space:pre"> </span>} catch (InterruptedException e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}

<span style="white-space:pre"> </span>}
}
然后是我的Utils:

public class MyUtils {

public static final int[] BALLRESOURCE = { R.drawable.ic_launcher,
R.drawable.ic_launcher90, R.drawable.ic_launcher180,
R.drawable.ic_launcher270 };

}

最后是我的activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<com.example.ball.BallSurfaceView
android:id="@+id/myBall"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

最后,这个代码有很多问题,不过就功能来说是实现了。各位看着改吧,最好自己重写吧,会好一点···
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息