中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

Android偏移動畫(hua)-轉(zhuan)圈的Button

以前做項目(mu)碰到(dao)過一個(ge)(ge)需求,就(jiu)是有(you)5個(ge)(ge)button,這(zhe)5個(ge)(ge)button要圍繞一個(ge)(ge)點不(bu)停的轉動(dong),而且點擊不(bu)同(tong)的button會進行相應(ying)的邏輯,比如activity的跳轉等.

就類(lei)似于gallery,但是又有(you)所不同

QQ截圖20120422211515

有人(ren)會首先想到用偏(pian)(pian)移(yi)動畫(hua),但(dan)(dan)是(shi)(shi)(shi)android的偏(pian)(pian)移(yi)動畫(hua)只是(shi)(shi)(shi)動畫(hua),也(ye)就是(shi)(shi)(shi)說你從(cong)A點移(yi)動B點,看上(shang)去是(shi)(shi)(shi)移(yi)動過去了(le),但(dan)(dan)是(shi)(shi)(shi)點擊的事件觸發(fa)卻還是(shi)(shi)(shi)在A點,實際上(shang)沒有真正(zheng)的

偏移過去,只是欺(qi)騙(pian)眼睛罷了,但是在android2.2以后api提(ti)供了這樣的(de)一(yi)(yi)個方(fang)(fang)法setPosition(),這個方(fang)(fang)法的(de)好處是你(ni)可以監聽動(dong)畫,假如一(yi)(yi)段動(dong)畫完成了你(ni)可以動(dong)態(tai)的(de)

得到(dao)現(xian)在button的(de)(de)(de)位置,然(ran)后set進(jin)去(qu),這樣也(ye)可(ke)以完成操作,但是簡單的(de)(de)(de)運動還(huan)行,如果是向我上門說的(de)(de)(de)5個button不(bu)停的(de)(de)(de)轉(zhuan)動,然(ran)后每個button的(de)(de)(de)動畫不(bu)斷的(de)(de)(de)監(jian)聽然(ran)后set

會很費事,而且2.2以下的pad或者手機就沒有辦(ban)法安裝(zhuang)了

 

其實(shi)如果是(shi)在ios上(shang)這樣(yang)是(shi)非常容易的,ios的偏移動畫很像我們(men)做(zuo)flash一(yi)樣(yang),定制起始點,再定制一(yi)個終點,然后創建補間動畫即(ji)可,幾行代碼就可以搞定,但是(shi)android上(shang)就不行

 

所以(yi)(yi)基于以(yi)(yi)上,我就(jiu)只能是(shi)這個思路(lu),我就(jiu)實(shi)現真(zhen)正的偏(pian)移好了,對,就(jiu)是(shi)用開發游戲(xi)的思路(lu)實(shi)現真(zhen)正的偏(pian)移

 

下(xia)面我直接(jie)上代碼了,以下(xia)是舞臺的代碼

我(wo)的button就相當于演員(yuan),演員(yuan)要表演只能去(qu)舞(wu)臺(tai)

package com.yp.rotatebutton;

import android.app.Activity;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;

public class RotateStage extends SurfaceView implements SurfaceHolder.Callback,Runnable {
	
	public static final String 	TAG	= "RotateStage";
	
	private Context context ;
	private SurfaceHolder holder ;
	private Thread mThread ;
	private Canvas mCanvas;
	
	private boolean isMovie = false;
	
	private RotateImageView mOneImageView ,mTwoImageView, mThreeImageView,mFourthImageView,mFiveImageView;
	
	public static double POINTX = DisplayMetrics.DENSITY_LOW ;
	public static double POINTY = DisplayMetrics.DENSITY_HIGH ;
	public static final  double RADIUS = 100;
	
	public RotateStage(Context context) {
		super(context);
		
		this.context = context;
		this.holder = this.getHolder();
		this.holder.addCallback(this);
		
		DisplayMetrics dm = new DisplayMetrics();
		((Activity) this.context).getWindowManager().getDefaultDisplay().getMetrics(dm);
		POINTX = dm.widthPixels / 2 -  BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher).getWidth() / 2;
		POINTY = dm.heightPixels / 2 - BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher).getHeight() / 2 ;
		
		Init();
	}
	
	private void Init(){
		mOneImageView = new RotateImageView(this.context,
				R.drawable.ic_launcher, POINTX
						+ Math.cos(0 * RotateImageView.ANGLENUM) * RADIUS,
				POINTY + Math.sin(0 * RotateImageView.ANGLENUM) * RADIUS, 0);

		mTwoImageView = new RotateImageView(this.context,
				R.drawable.ic_launcher, POINTX
						+ Math.cos(72 * RotateImageView.ANGLENUM) * RADIUS,
				POINTY + Math.sin(72 * RotateImageView.ANGLENUM) * RADIUS, 72);

		mThreeImageView = new RotateImageView(this.context,
				R.drawable.ic_launcher, POINTX
						+ Math.cos(144 * RotateImageView.ANGLENUM) * RADIUS,
				POINTY + Math.sin(144 * RotateImageView.ANGLENUM) * RADIUS, 144);

		mFourthImageView = new RotateImageView(this.context,
				R.drawable.ic_launcher, POINTX
						+ Math.cos(216 * RotateImageView.ANGLENUM) * RADIUS,
				POINTY + Math.sin(216 * RotateImageView.ANGLENUM) * RADIUS, 216);

		mFiveImageView = new RotateImageView(this.context,
				R.drawable.ic_launcher, POINTX
						+ Math.cos(288 * RotateImageView.ANGLENUM) * RADIUS,
				POINTY + Math.sin(288 * RotateImageView.ANGLENUM) * RADIUS, 288);
		
	}
	
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		mThread = new Thread(this);
		mThread.start();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		
		isMovie = true ;
		
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		isMovie = false;
	}

	@Override
	public void run() {
		
		while (isMovie) {
			
			long start = System.currentTimeMillis();
			draw();
			logic();
			long end = System.currentTimeMillis();
			if (end - start < 5) {
				try {
					Thread.sleep (5 - (end - start)) ;
//					Thread.sleep(5);
				} catch (InterruptedException e) {
					Log.v(TAG, "run thread sleep error : " + e.toString());
				}
			}
		}
		
	}
	
	
	public void draw(){
		try{
			mCanvas = holder.lockCanvas() ;
			mCanvas.drawColor(Color.RED);
			
			mCanvas.drawBitmap(mOneImageView.getmBgBitmap(), (float)mOneImageView.getxPix(), (float)mOneImageView.getyPix(), null);
			mCanvas.drawBitmap(mTwoImageView.getmBgBitmap(), (float)mTwoImageView.getxPix(), (float)mTwoImageView.getyPix(), null);
			mCanvas.drawBitmap(mThreeImageView.getmBgBitmap(), (float)mThreeImageView.getxPix(), (float)mThreeImageView.getyPix(), null);
			mCanvas.drawBitmap(mFourthImageView.getmBgBitmap(), (float)mFourthImageView.getxPix(), (float)mFourthImageView.getyPix(), null);
			mCanvas.drawBitmap(mFiveImageView.getmBgBitmap(), (float)mFiveImageView.getxPix(), (float)mFiveImageView.getyPix(), null);
			
		}catch (Exception e) {
			
			Log.v(TAG	, "draw error: " + e.toString());
			
		}finally{
			if (mCanvas != null) holder.unlockCanvasAndPost(mCanvas) ;
		}
	}
	
	private void logic() {
		mOneImageView.moveImageButton();
		mTwoImageView.moveImageButton();
		mThreeImageView.moveImageButton();
		mFourthImageView.moveImageButton();
		mFiveImageView.moveImageButton();
	}
	
}

 

舞臺中的演(yan)員:RotateImageView  這個也是我(wo)自己定義的一(yi)個類,就(jiu)相當于button,你(ni)要(yao)在舞臺上添加幾個演(yan)員你(ni)就(jiu)new幾個好了(le),我(wo)沒有好的圖片,所以(yi)就(jiu)拿默認的icon了(le),講究(jiu)看吧

 

package com.yp.rotatebutton;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
/**
 * 
 * @author peng_yu
 *
 */
public class RotateImageView {
	
	public static final String TAG = "RotateImageView";
	
	public static final double ANGLENUM = Math.PI/180;
	
	private Bitmap mBgBitmap;
	private double angle ;
	private double xPix;
	private double yPix;
	
	public RotateImageView() {
		super();
	}
	
	public RotateImageView(Context content,int bgId,double XPix,double Ypix,double angle) {
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inJustDecodeBounds = true;
		mBgBitmap = BitmapFactory.decodeResource(content.getResources(),bgId);
		this.xPix = XPix;
		this.yPix = Ypix;
		this.angle = angle;
		
	}
	
	public double getAngle() {
		return angle;
	}

	public void setAngle(double angle) {
		this.angle = angle;
	}
	
	public int getHeight() {
		return mBgBitmap.getHeight();
	}


	public int getWidth() {
		return mBgBitmap.getWidth();
	}

	public double getxPix() {
		return xPix;
	}

	public void setxPix(double xPix) {
		this.xPix = xPix;
	}

	public double getyPix() {
		return yPix;
	}

	public void setyPix(double yPix) {
		this.yPix = yPix;
	}
	
	public Bitmap getmBgBitmap() {
		return mBgBitmap;
	}

	public void setmBgBitmap(Bitmap mBgBitmap) {
		this.mBgBitmap = mBgBitmap;
	}
	
	public void moveImageButton(){
		if(angle > 360){
			angle = 0;
		}
		xPix = RotateStage.POINTX + Math.cos(angle*ANGLENUM)*RotateStage.RADIUS;
		yPix = RotateStage.POINTY + Math.sin(angle*ANGLENUM)*RotateStage.RADIUS;
		angle += 1;
		
	}

}

 

這個(ge)是我的演員(button)代碼

其(qi)實細心(xin)的(de)朋(peng)友就已經發現(xian)了我是(shi)不斷重(zhong)繪每一個(ge)view的(de)坐標,實現(xian)這種(zhong)轉圈(quan)的(de)效果,所以這個(ge)demo最關(guan)鍵(jian)的(de)就是(shi)怎(zen)么(me)來(lai)算(suan)出每個(ge)button下一幀的(de)位(wei)置

如(ru)果你是(shi)想讓一個button轉圈(quan),這個非常好實現,但是(shi)如(ru)果想讓5個button沿著同(tong)一軌跡來運(yun)動畫(hua)圈(quan)不那么容易,至少我是(shi)費了很(hen)多時(shi)間的(de)

因為(wei)表演的(de)演員的(de)職責(ze),所(suo)以(yi)這樣(yang)的(de)邏輯(ji)就在它(ta)自身了

xPix = RotateStage.POINTX + Math.cos(angle*ANGLENUM)*RotateStage.RADIUS;

yPix = RotateStage.POINTY + Math.sin(angle*ANGLENUM)*RotateStage.RADIUS;

angle += 1;

這里面的(de)(de)RotateStage.POINTX 是我計算的(de)(de)屏(ping)幕(mu)中心(xin)點的(de)(de)位置,RotateStage.RADIUS是所(suo)繞圈的(de)(de)半徑大小

ANGLENUM也可(ke)以看到,實(shi)際上就(jiu)是Math.PI/180

每次運動(dong)繪制angle會(hui)+1,就會(hui)相應的(de)計算(suan)出新(xin)的(de)坐標,然(ran)后舞臺調用它們各自的(de)moveImageButton方(fang)法(fa)即可

 

還有值得(de)注意的(de)是舞臺中的(de)代碼:

也就是我自定(ding)義(yi)的演(yan)員(yuan)的構造方法

mOneImageView = new RotateImageView(this.context,
                R.drawable.ic_launcher, POINTX
                        + Math.cos(0 * RotateImageView.ANGLENUM) * RADIUS,
                POINTY + Math.sin(0 * RotateImageView.ANGLENUM) * RADIUS, 0);

mTwoImageView = new RotateImageView(this.context,
                R.drawable.ic_launcher, POINTX
                        + Math.cos(72 * RotateImageView.ANGLENUM) * RADIUS,
                POINTY + Math.sin(72 * RotateImageView.ANGLENUM) * RADIUS, 72);

不一樣的也(ye)就是0 , 72 了,這個我沒有進(jin)行封(feng)裝,如果你(ni)們需要自己改改就可以了,為(wei)什么(me)是0和72呢,因為(wei)我是5個button,每一等分(fen)就是72,所(suo)以

也就(jiu)是起(qi)始的角度(du),比如你(ni)是0度(du),你(ni)就(jiu)在最右邊,你(ni)是72度(du),你(ni)就(jiu)在72度(du)角的方向上

 

我這么說你們是不是已經(jing)很明白了(le)?

再來說說怎么樣觸發點(dian)擊事件吧,其實也要借(jie)鑒(jian)游(you)戲里的(de)思路了,就是計算你當前toutch的(de)坐標(biao)是否在button內,在哪一個(ge)button內

這樣做也有很多的算法,比如(ru)Region碰撞(zhuang)檢測還有計算矩形(xing)的碰撞(zhuang)

我用的是后一種

@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		if(event.getX() > mOneImageView.getxPix() && event.getX() < mOneImageView.getxPix() + mOneImageView.getWidth()
				  && event.getY() > mOneImageView.getyPix() && event.getY() < mOneImageView.getyPix() + mOneImageView.getHeight()	
					){
			
			Toast.makeText(this.context,"mOneImageView", 1).show();
			return false;
		}
		if(event.getX() > mTwoImageView.getxPix() && event.getX() < mTwoImageView.getxPix() + mTwoImageView.getWidth()
				&& event.getY() > mTwoImageView.getyPix() && event.getY() < mTwoImageView.getyPix() + mTwoImageView.getHeight()	
		){
			Toast.makeText(this.context,"mTwoImageView", 1).show();
			return false;
		}
		if(event.getX() > mThreeImageView.getxPix() && event.getX() < mThreeImageView.getxPix() + mThreeImageView.getWidth()
				&& event.getY() > mThreeImageView.getyPix() && event.getY() < mThreeImageView.getyPix() + mThreeImageView.getHeight()	
		){
			
			Toast.makeText(this.context,"mThreeImageView", 1).show();
			return false;
		}
		if(event.getX() > mFourthImageView.getxPix() && event.getX() < mFourthImageView.getxPix() + mFourthImageView.getWidth()
				&& event.getY() > mFourthImageView.getyPix() && event.getY() < mFourthImageView.getyPix() + mFourthImageView.getHeight()	
		){
			
			Toast.makeText(this.context,"mFourthImageView", 1).show();
			return false;
		}
		if(event.getX() > mFiveImageView.getxPix() && event.getX() < mFiveImageView.getxPix() + mFiveImageView.getWidth()
				&& event.getY() > mFiveImageView.getyPix() && event.getY() < mFiveImageView.getyPix() + mFiveImageView.getHeight()	
		){
			Toast.makeText(this.context,"mFiveImageView", 1).show();
			return false;
		}
		
		return super.onTouchEvent(event);
	}

 

其實這(zhe)樣做并不好,就是(shi)(shi)每次在點(dian)擊的時候都有點(dian)卡,但是(shi)(shi)要解決這(zhe)個問(wen)題也(ye)很好辦(ban),但是(shi)(shi)剩(sheng)下的我(wo)就不說了,自己去(qu)嘗試(shi)吧

附上(shang)我項目中(zhong)的一張截圖:

 

image

 

另(ling)外如果誰(shui)還有更好的一些辦法請告訴我,一定(ding)感激(ji)不(bu)盡(jin)!

posted on 2012-04-22 22:01  ①塊腹肌  閱讀(5589)  評論(0)    收藏  舉報