[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
大体可以把他看成一个矩形和一个圆形相交取圆形的剩余部分矩形的相交部分,考虑使用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; } }
相关文章推荐
- Android-基本XML
- android imageview图片居中技巧应用
- Android-Intent
- android悬浮窗口的实现
- Android中Google Drive显示黑屏问题分析
- Android最新支持包Design简介
- java4Android(4)各种基本数据类型及赋值
- android 通知
- Android Studio快捷键
- Android中Device Provisioned引起的问题分析
- Android 换行
- Android修改系统自带Spinner字体大小和颜色示例代码
- Android给ListView设置分割线Divider样式
- 启动android默认浏览器
- android SrollView的内容发生变化时自动滚动的处理
- Android开发中模拟Home键操作和关闭手机软键盘
- Android 系统中WiFi的部署
- 防止android控件点击事件重复提交
- Android开发之:自定义GridView
- Android 如何有效修改包名