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

[android view]仿安全卫士的加速小球

2015-06-01 17:06 435 查看
首先,考虑到比较简单,触发事件也只有一个点击事件,所以想继承view实现这个控件。

大体可以把他看成一个矩形和一个圆形相交取圆形的剩余部分矩形的相交部分,考虑使用paint的Xfermode,来进行绘制(这里需要注意 需要新建一个bitmap然后利用的canvas进行这个操作,直接使用onDraw(canvas)中的canvas没有效果具体原因我想Xfermode设计就是针对bitmap吧 不太清楚详细见源码);用一个线程不断改变矩形的高。

其次有的球在加速完会有一个波浪的效果,这里我参考了http://blog.csdn.net/vrix/article/details/39206975,我理解就是把点定好不断移动点,我这里采用和他文章一样的方法没改效果还可以,也可以手动指定几个点,这里我采用等他绘制完矩形到达目标出,然后在进行一段波浪绘制移动。

源代码如下

color.xml

<?xml version="1.0" encoding="UTF-8"?>
<resources>
<color name="gray">#404040</color>
<color name="green">#00cc00</color>
<color name="white">#ffffff</color>
<color name="red">#cc0000</color>
</resources>
ball360.xml

<?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" >

<com.example.tools.BallView
android:id="@+id/ballview"
android:layout_width="200dp"
android:layout_height="200dp"
>
</com.example.tools.BallView>

</LinearLayout>
Ballactivity.java
import com.example.tools.BallView;

import android.app.Activity;
import android.graphics.Canvas;
import android.os.Bundle;
import android.widget.ImageView;

public class BallActivity extends Activity{
BallView ballView;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.ball360);
ballView=(BallView)findViewById(R.id.ballview);
ballView.setStartHeight(40);
ballView.setStopHeight(65);
}

}
BallView.java

package com.example.tools;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;

import com.example.model.Point;
import com.example.visualization.R;

import android.R.integer;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

public class BallView extends View implements Runnable{
int startHeight=40;
int radius=50;
int centX=100;
int centY=100;
int stopHeight=70;
int count=0;
//Thread thread=new Thread(this);
Paint paint=new Paint();
Paint qPaint=new Paint();
Path path=new Path();
boolean isWave=false;
boolean start=false;
ArrayList<Point> mPointsList=new ArrayList<Point>();

private int mViewWidth;
private int mViewHeight;

/**
* 水位线
*/
private float mLevelLine;

/**
* 波浪起伏幅度
*/
private float mWaveHeight = 80;
/**
* 波长
*/
private float mWaveWidth = 200;
/**
* 被隐藏的最左边的波形
*/
private float mLeftSide;

private float mMoveLen;
/**
* 水波平移速度
*/
public static final float SPEED = 2f;
public BallView(Context context) {
super(context);
// TODO Auto-generated constructor stub

/* 构建对象 */

/* 开启线程 */
new Thread(this).start();

}

public BallView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub

/* 构建对象 */

/* 开启线程 */
new Thread(this).start();

}

public BallView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub

/* 构建对象 */

/* 开启线程 */
new Thread(this).start();

}
/*
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub

paint.setColor( getResources().getColor(R.color.gray));
canvas.drawCircle(centX, centY, radius, paint);
canvas.save();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
paint.setColor(getResources().getColor(R.color.green));
canvas.drawRect(centX-radius, centY+radius-startHeight, centX+radius, centY+radius, paint);

canvas.save();
super.onDraw(canvas);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return super.onTouchEvent(event);
}*/

public void onDraw(Canvas canvas) {
super.onDraw(canvas);

Bitmap bitmap1 = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
//  Bitmap bitmap2 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888);
Canvas canvas1 = new Canvas(bitmap1);
//    Canvas canvas2 = new Canvas(bitmap2);

paint.setAntiAlias(true);

paint.setColor(getResources().getColor(R.color.gray));
paint.setAlpha(200);
canvas1.drawCircle(centX, centY, radius, paint);
//canvas.drawBitmap(bitmap1, 0, 0, null);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));

paint.setColor(getResources().getColor(R.color.green));
if(startHeight>70){
paint.setColor(getResources().getColor(R.color.red));
}
paint.setAlpha(255);
canvas1.drawRect(centX-radius, centY+radius-startHeight, centX+radius, centY+radius, paint);
path.reset();

// 设置贝赛尔曲线的操作点以及终止点
if(isWave){
int i=0;
paint.setStyle(Style.FILL);

path.moveTo(centX-radius,centY+radius-startHeight);
for (; i < mPointsList.size() - 2; i = i + 2)
{
path.quadTo(mPointsList.get(i + 1).getX(),
mPointsList.get(i + 1).getY(), mPointsList.get(i + 2)
.getX(), mPointsList.get(i + 2).getY());
}

canvas1.drawPath(path, paint);
path.close();
// 绘制贝赛尔曲线(Path)

}
paint = new Paint();
canvas.drawBitmap(bitmap1, 0, 0, paint);
paint.setColor(getResources().getColor(R.color.white));
paint.setTextSize(20);
canvas.drawText(""+(startHeight)+" %", centX-20, centY, paint);

}

// 触笔事件
public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:

Log.e("dianji========", "=========");
isWave=false;
startHeight=0;
start=true;

break;

default:
break;
}

return false;
}

private void resetPoints()
{
mLeftSide = -mWaveWidth;
for (int i = 0; i < mPointsList.size(); i++)
{
mPointsList.get(i).setX(i * mWaveWidth / 4 - mWaveWidth);
}
}

public synchronized void run() {
while (!Thread.currentThread().isInterrupted()) {

// 使用postInvalidate可以直接在线程中更新界面
if(start){
Log.e("start", "rect====");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
startHeight+=5;
if(startHeight>stopHeight){
start=false;
isWave=true;
startHeight=stopHeight;
intiListPoint();

}else{
postInvalidate();

}}else  if(isWave){

try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 记录平移总位移
mMoveLen += SPEED;

if (mLevelLine < 0)
mLevelLine = 0;
mLeftSide += SPEED;
// 波形平移
for (int i = 0; i < mPointsList.size(); i++)
{
mPointsList.get(i).setX(mPointsList.get(i).getX() + SPEED);
switch (i % 4)
{
case 0:
case 2:
mPointsList.get(i).setY(mLevelLine);
break;
case 1:
mPointsList.get(i).setY(mLevelLine + mWaveHeight);
break;
case 3:
mPointsList.get(i).setY(mLevelLine - mWaveHeight);
break;
}
}
if (mMoveLen >= mWaveWidth)
{
// 波形平移超过一个完整波形后复位
mMoveLen = 0;
resetPoints();
isWave=false;

}  else{
postInvalidate();
}
}

}
}

public void intiListPoint(){
mViewHeight = centY+radius-startHeight;
mViewWidth =(int) Math.sqrt(radius*radius-(radius-startHeight)*(radius-startHeight));
// 水位线从最底下开始上升
mLevelLine = mViewHeight;
// 根据View宽度计算波形峰值
mWaveHeight = 12 / 4f;
// 波长等于四倍View宽度也就是View中只能看到四分之一个波形,这样可以使起伏更明显
mWaveWidth = mViewWidth * 4;
// 左边隐藏的距离预留一个波形
mLeftSide = -mWaveWidth;
// 这里计算在可见的View宽度中能容纳几个波形,注意n上取整
int n = (int) Math.round(mViewWidth / mWaveWidth + 0.5);
// n个波形需要4n+1个点,但是我们要预留一个波形在左边隐藏区域,所以需要4n+5个点
for (int i = 0; i < (4 * n + 5); i++)
{
// 从P0开始初始化到P4n+4,总共4n+5个点
float x = i * mWaveWidth / 4 - mWaveWidth;
float y = 0;
switch (i % 4)
{
case 0:
case 2:
// 零点位于水位线上
y = mLevelLine;
break;
case 1:
// 往下波动的控制点
y = mLevelLine + mWaveHeight;
break;
case 3:
// 往上波动的控制点
y = mLevelLine - mWaveHeight;
break;
}
mPointsList.add(new Point(x, y));
}
}

public void setStartHeight(int start){
startHeight=start;
}
public void setStopHeight(int stop){
stopHeight=stop;
}
public void setPosition(int centX,int centY){
this.centX=centX;
this.centY=centY;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: