Android碰撞的小球,密集恐惧症者谨慎
2015-11-07 22:46
429 查看
今天又温习了一遍Java的进程。正好用Android写了一个小Demo,具体就是在手机屏幕上显示多个运动的小球,小球碰到手机屏幕边缘会自动弹回。大概就是下面图中显示的:
![](http://img.blog.csdn.net/20151107224838162?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
该本主要的结束的是自定义View封装,View视图绘制,通过xml文件自定义View属性并设置属性,多线程Thread,小球碰撞弹回简单算法。
下面是制作这个Demo的简单步骤:
step1:自定义一个View抽象类,它封装了View类的基本方法,以及多线程的创建和操作方法。具体代码如下:
下面我对View的两个构造方法View(Context context)和View(Context context,AttributeSet attrs)解释一下。第一个View(Context context)只有一个上下文context的参数,一般在代码(.javawenjian)中创建View进行调用,比如View view = new View(this)。第二个构造方法View(Context
context,AttributeSet attrs)有两个参数,其中attrs是View的属性集合。一般在布局创建View对象时进行调用(.xml文件)。
step2:然后重写一个MyCustomeView类,继承刚才定义的抽象类BaseCustomeView。并实现抽象方法initView()、logicalDo()、drawSub()方法。具体代码如下:
1.首先在自定义类中声明你要在xml文件设置的属性,比如我在MyCustomeView中声明了ballNumber和ballRadius属性。
2.在values文件夹中创建一个attrs.xml文件,在里面声明你要在xml文件中使用的属性,如下:
3.在主视图布局文件中(我这里是默认的activity_main.xml文件),设置属性的值,代码我已经贴在上面。
在主布局中添加xmlns:yourname="http://schemas.android.com/apk/res/com.example.constumeview";
其中xmlns:yourname中xmlns是固定的,yourname可以自定义,不过设置属性的时候要保持一致。后面的工具前面的http://schemas.android.com/apk/res/是不变的,后面的是你的工作空间包名。接下来就是设置属性了。例如:yourname:ballNumber="500" yourname:ballRadius="10.0".详细看上面的代码部分哦。
4.最后贴上我入口程序MainActivity.java中的代码,其实什么都没有,只是为了保持项目的完整性,读者好参考。
该本主要的结束的是自定义View封装,View视图绘制,通过xml文件自定义View属性并设置属性,多线程Thread,小球碰撞弹回简单算法。
下面是制作这个Demo的简单步骤:
step1:自定义一个View抽象类,它封装了View类的基本方法,以及多线程的创建和操作方法。具体代码如下:
<span style="font-size:12px;">package com.example.constumeview; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.View; public abstract class BaseCustomeView extends View { private MyThread myThread = null; private class MyThread extends Thread{ @Override public void run() { while(true){ logicalDo(); postInvalidate(); //通知更新界面,会重新调用onDraw()函数 try{ sleep(80); }catch(Exception e){ e.printStackTrace(); } } } } public abstract void logicDo(); //逻辑处理方法 public abstract void drawSub(Canvas canvas); //绘画内容代码 public abstract void initView(); @Override protected void onDraw(Canvas canvas) { if(myThread == null){ //第一次调用onDraw()方法的时候会创建一个线程,用来实现小球的碰撞弹回 initView();<span style="white-space:pre"> </span>//初始化View方法 myThread = new MyThread(); myThread.start(); //启动线程 }else{ drawSub(canvas); //如果线程以创建,则调用绘制方法 } } public BaseCustomeView(Context context) { super(context); } public BaseCustomeView(Context context, AttributeSet attrs) { super(context, attrs); } } </span>
下面我对View的两个构造方法View(Context context)和View(Context context,AttributeSet attrs)解释一下。第一个View(Context context)只有一个上下文context的参数,一般在代码(.javawenjian)中创建View进行调用,比如View view = new View(this)。第二个构造方法View(Context
context,AttributeSet attrs)有两个参数,其中attrs是View的属性集合。一般在布局创建View对象时进行调用(.xml文件)。
step2:然后重写一个MyCustomeView类,继承刚才定义的抽象类BaseCustomeView。并实现抽象方法initView()、logicalDo()、drawSub()方法。具体代码如下:
<span style="font-size:12px;">package com.example.constumeview; import java.util.Random; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.PointF; import android.util.AttributeSet; public class MyCustomeView extends BaseCustomeView { private Paint paint = new Paint(); private int ballNumber = 1; //定义小球个数,默认为1个,通过xml自定义属性进行设置,详细看后面 private PointF[] ballCenter = null; //存储各个小球的圆心坐标 private float ballRadius = 4.0f; //定义小球半径,通过xml自定义设置,看后面解释 private int viewWidth = 0; //手机屏幕宽度 private int viewHeight = 0; //手机屏幕高度 private float[] xspace; //存储各个小球横向运动速度,每个小球在横向和纵向运动的速度是不同 private float[] yspace;//存储各个小球纵向的运动速度 public MyCustomeView(Context context) {//代码中解析 super(context); } public MyCustomeView(Context context, AttributeSet attrs) {//布局中解析属性 super(context, attrs); TypedArray typeArray = context.obtainStyledAttributes(attrs,R.styleable.NumberText); ballNumber = typeArray.getInt(R.styleable.NumberText_ballNumber, 1);//获得小球个数 ballRadius = typeArray.getFloat(R.styleable.NumberText_ballRadius, 4.0f);//获得小球半径 typeArray.recycle();//回收TypeArray资源 productBallCenter(); //产生各个小球的圆心位置 setBackgroundColor(Color.WHITE);//设置View背景色为白色 } @Override public void logicDo() {//小球碰撞弹回简单算法 for(int i=0;i<ballNumber;i++){ if((ballCenter[i].x-ballRadius)<0){ //如果小球到达屏幕左边缘,设置<span style="font-family: Arial, Helvetica, sans-serif;">ballCenter[i].x = ballRadius;</span> xspace[i] = 0-xspace[i]; ballCenter[i].x = ballRadius; }else if((ballCenter[i].x+ballRadius)>viewWidth){//如果小球到达屏幕右边缘 xspace[i] = 0-xspace[i]; ballCenter[i].x = viewWidth-ballRadius; } else if((ballCenter[i].y-ballRadius)<0){//如果小球达到屏幕上边缘 yspace[i] = 0-yspace[i]; ballCenter[i].y = ballRadius; }else if((ballCenter[i].y+ballRadius)>viewHeight){//如果小球到达屏幕下边缘 yspace[i] = 0-yspace[i]; ballCenter[i].y = viewHeight-ballRadius; } else{<span style="white-space:pre"> </span>//默认正常情况下 ballCenter[i].x = ballCenter[i].x+xspace[i]; ballCenter[i].y = ballCenter[i].y+yspace[i]; } } } @Override public void drawSub(Canvas canvas) {//以圆心坐标绘制每个小球在屏幕中的位置 for(int i=0;i<ballNumber;i++){ /*Random random = new Random(); int r = random.nextInt(256); int g = random.nextInt(256); int b = random.nextInt(256); paint.setARGB(255,r, g, b);*/<span style="white-space:pre"> </span>//随机产生小球的颜色,这里我注释了,用的是全黑 canvas.drawCircle(ballCenter[i].x, ballCenter[i].y, ballRadius, paint); } } public void productBallCenter(){ //随机初始化小球的圆心和小球运动速度,只在initView中调用一次 ballCenter = new PointF[ballNumber]; xspace = new float[ballNumber]; yspace = new float[ballNumber]; Random random = new Random(); float xpoint = 0; float ypoint = 0; for(int i=0;i<ballNumber;i++){ xpoint = random.nextFloat()*viewWidth+ballRadius; ypoint = random.nextFloat()*viewHeight+ballRadius; ballCenter[i] = new PointF(xpoint,ypoint); xspace[i] = random.nextFloat()*ballRadius+1; yspace[i] = random.nextFloat()*ballRadius+1; } } @Override public void initView() { //初始化View方法,准备工作 viewWidth = getWidth(); viewHeight = getHeight(); productBallCenter(); } } </span>程序的运行过程我在注释中写得很详细了,现在我主要介绍一下怎么在xml中自定义View的属性。比如在上面程序中ballNumber和ballRadius属性是同xml文件设置的,以及我们自定义的MyCustomeView对象也是通过xml进行初始化的。下面是我的xml文件中代码,只有几行:
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" xmlns:yourname="http://schemas.android.com/apk/res/com.example.constumeview" xmlns:android="http://schemas.android.com/apk/res/android"> <com.example.constumeview.MyCustomeView android:layout_width="match_parent" android:layout_height="match_parent" yourname:ballNumber="500" yourname:ballRadius="10.0"/> </LinearLayout>下面是具体步骤:
1.首先在自定义类中声明你要在xml文件设置的属性,比如我在MyCustomeView中声明了ballNumber和ballRadius属性。
2.在values文件夹中创建一个attrs.xml文件,在里面声明你要在xml文件中使用的属性,如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="NumberText"> <attr name="ballNumber" format="integer"/> <attr name="ballRadius" format="float"/> </declare-styleable> </resources>name为属性名,format为属性的数据类型。
3.在主视图布局文件中(我这里是默认的activity_main.xml文件),设置属性的值,代码我已经贴在上面。
在主布局中添加xmlns:yourname="http://schemas.android.com/apk/res/com.example.constumeview";
其中xmlns:yourname中xmlns是固定的,yourname可以自定义,不过设置属性的时候要保持一致。后面的工具前面的http://schemas.android.com/apk/res/是不变的,后面的是你的工作空间包名。接下来就是设置属性了。例如:yourname:ballNumber="500" yourname:ballRadius="10.0".详细看上面的代码部分哦。
4.最后贴上我入口程序MainActivity.java中的代码,其实什么都没有,只是为了保持项目的完整性,读者好参考。
package com.example.constumeview; import android.app.Activity; import android.app.ActionBar; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.os.Build; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }到此一个满屏幕都是碰撞小球的Demo就制作好了,密集恐惧症的人请将小球个数调少点哦。23333333
相关文章推荐
- Android中自定义控件获取text的宽高方式
- Android--Listview学习
- 关于Android Studio如何导入library project
- 调用Android相机拍照的问题
- aidl(android 接口定义语言)
- 怎么样将android studio或者xamarin studio默认界面的标题栏去掉,便于html5打包apk,为了美观
- Android TouchEvent事件传递机制
- robotium 中获取相同类型的自控觉得获取方法(使用Android的ViewGroup控件的getChildAt(index)获取)
- Android NDK开发之《HelloJni》
- Android 自定义seekbar 代码实现
- Android存储-SQLite
- android 5.0新特性CardView教程
- SEAndroid与SEpolicy Language简介
- Android button 点击变色,圆角
- Android背景选择器selector
- Android 百度地图SDK v_3_4_0学习笔记(一)环境搭建
- ionic 解决android 中tabs 在上面的问题。
- android 的oermission权限
- Android系统中的Activity简介
- Android开书籍推荐