Android开发——自定义View之实现跟随手指移动的小球
案例:
实现的功能:
手指在屏幕上滑动,红色的小球始终跟随手指移动。
实现的思路:
1)自定义View,在onDraw中画圆作为小球;
2)重写自定义View的onTouchEvent方法,记录触屏坐标,用新的坐标重新绘制小球;
3)在布局中引用自定义View布局,运行程序,实现跟随手指移动效果。
关键技术点:
自定义View应用、触摸事件处理、canvas绘图、Paint应用。
我们先用简单的方式实现以下效果:
MainActivity.java中不需要写代码
DrawViewDemo.java:
package com.bawei.com.myapplication; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * Created by Wangrx on 2017/11/2. */ public class DrawViewDemo extends View{ public float currentX = 70; public float currentY = 70; //定义。创建画笔 Paint p = new Paint(); public DrawViewDemo(Context context) { super(context); } public DrawViewDemo(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public DrawViewDemo(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); //设置画笔的颜色 p.setColor(Color.RED); //绘制一个小球 //参数分别是:圆心坐标,半径 ,所使用的画笔 canvas.drawCircle(currentX, currentY, 30, p); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub //修改当前的坐标 this.currentX = event.getX(); this.currentY = event.getY(); //重绘小球 this.invalidate(); return true; } }activity_main.xml中引入view
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.bawei.com.myapplication.MainActivity"> <com.bawei.com.myapplication.DrawViewDemo android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout>
以上代码可以简单的实现跟随手指移动的小球
下面我们进行一些复杂的操作,用另一种方式实现跟随手指移动的小球
BallActivity.java
package com.bawei.com.ballviewdemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; import java.util.Random; public class BallActivity extends AppCompatActivity { private int screenW; //屏幕宽度 private int screenH; //屏幕高度 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Display dis = this.getWindowManager().getDefaultDisplay(); // 设置全屏 requestWindowFeature(Window.FEATURE_NO_TITLE); this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 获取屏幕宽度 screenW = dis.getWidth(); // 获取屏幕高度 screenH = dis.getHeight(); setContentView(new BallView(this)); } //自定义绘图类 class BallView extends View { private Paint paint; //定义画笔 private float cx = 50; //圆点默认X坐标 private float cy = 50; //圆点默认Y坐标 private int radius = 20; //定义颜色数组 private int colorArray[] = {Color.BLACK,Color.BLACK,Color.GREEN,Color.YELLOW, Color.RED}; private int paintColor = colorArray[0]; //定义画笔默认颜色 public BallView(Context context) { super(context); //初始化画笔 initPaint(); } private void initPaint(){ paint = new Paint(); //设置消除锯齿 paint.setAntiAlias(true); //设置画笔颜色 paint.setColor(paintColor); } //重写onDraw方法实现绘图操作 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //将屏幕设置为白色 canvas.drawColor(Color.WHITE); //修正圆点坐标 revise(); //随机设置画笔颜色 setPaintRandomColor(); //绘制小圆作为小球 canvas.drawCircle(cx, cy, radius, paint); } //为画笔设置随机颜色 private void setPaintRandomColor(){ Random rand = new Random(); int randomIndex = rand.nextInt(colorArray.length); paint.setColor(colorArray[randomIndex]); } //修正圆点坐标 private void revise(){ if(cx <= radius){ cx = radius; }else if(cx >= (screenW-radius)){ cx = screenW-radius; } if(cy <= radius){ cy = radius; }else if(cy >= (screenH-radius)){ cy = screenH-radius; } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 按下 cx = (int) event.getX(); cy = (int) event.getY(); // 通知重绘 postInvalidate(); //该方法会调用onDraw方法,重新绘图 break; case MotionEvent.ACTION_MOVE: // 移动 cx = (int) event.getX(); cy = (int) event.getY(); // 通知重绘 postInvalidate(); break; case MotionEvent.ACTION_UP: // 抬起 cx = (int) event.getX(); cy = (int) event.getY(); // 通知重绘 postInvalidate(); break; } /* * 备注1:此处一定要将return super.onTouchEvent(event)修改为return true,原因是: * 1)父类的onTouchEvent(event)方法可能没有做任何处理,但是返回了false。 * 2)一旦返回false,在该方法中再也不会收到MotionEvent.ACTION_MOVE及MotionEvent.ACTION_UP事件。 */ //return super.onTouchEvent(event); return true; } } }main.xml与AndroidManifest.xml没有做任何修改
以上就是实现跟随手指移动的小球的两种方式 喜欢哪个用哪个, 第二种方式相对复杂一点,不过效果挺好看的。