android中view组件使用详解
View
extends Objectimplements Drawable.Callback KeyEvent.Callback AccessibilityEventSource
java.lang.Object | |
↳ | android.view.View |
Known Direct Subclasses AnalogClock, ImageView, KeyboardView, ProgressBar, SurfaceView, TextView, ViewGroup, ViewStub |
Known Indirect Subclasses AbsListView, AbsSeekBar, AbsSpinner, AbsoluteLayout, AdapterView<Textends Adapter>, AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, AutoCompleteTextView, Button, CalendarView, CheckBox, CheckedTextView, Chronometer, CompoundButton, and 47 others. |
上面的是SDK中对View类的一个定义,可以看到,有很多类是它的直接子类或者间接子类。
每个View类都有个可以进行绘画的画布,这个画布可以进行任一扩展。在游戏当中,可以自定义视图(View),使得这个画布的功能更能满足我们在游戏中的需要。
在Android中,任何一个View类都要重写onDraw()方法来实现画面显示,自定义的视图或者3D实现。
游戏中经常会使用触屏、键盘等事件,在View中同样也要实现它们来满足相应的功能。
onKeyUp,onKeyDown,onKeyMultiple,onKeyPreIme,onTouchEvent,onTrackballEvent等方法,在继承View的时候需要重载这些方法。
其实,游戏的核心就是不断的刷新界面和绘图,绘图可以在onDraw()方法中实现,那么刷新界面呢?Android中提供了
invalidate()方法来实现界面刷新,注意,invalidate不能直接在线程中调用,因为它违背了单线程模型:Android UI操作不是线程安全的,并且这些线程必须在UI线程中执行,因此Android中最常用的方法是利用Handler来实现UI线程的更新。
下面是个例子:
ViewDemo.java
Java代码- packagecom.loulijun.viewdemo;
- importandroid.content.Context;
- importandroid.graphics.Canvas;
- importandroid.graphics.Color;
- importandroid.graphics.Paint;
- importandroid.os.Bundle;
- importandroid.view.View;
- publicclassViewDemoextendsView{
- //用于后面生成不同颜色而定义的变量
- intcount=0;
- //重写ViewDemo的构造方法
- publicViewDemo(Contextcontext)
- {
- super(context);
- }
- //画图方法
- publicvoidonDraw(Canvascanvas)
- {
- if(count<100)
- {
- count++;
- }
- else
- {
- count=0;
- }
- Paintpaint=newPaint();
- switch(count%4)
- {
- case0:paint.setColor(Color.BLUE);break;
- case1:paint.setColor(Color.GREEN);break;
- case2:paint.setColor(Color.RED);break;
- case3:paint.setColor(Color.YELLOW);break;
- default:paint.setColor(Color.WHITE);break;
- }
- //画一个坐标在(100,100),半径为60的圆
- canvas.drawCircle(100,100,60,paint);
- }
- }
package com.loulijun.viewdemo;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Bundle;import android.view.View;public class ViewDemo extends View {//用于后面生成不同颜色而定义的变量 int count = 0; //重写ViewDemo的构造方法 public ViewDemo(Context context) { super(context); } //画图方法 public void onDraw(Canvas canvas) { if(count < 100) { count++; } else { count = 0; } Paint paint = new Paint(); switch(count%4) { case 0:paint.setColor(Color.BLUE);break; case 1:paint.setColor(Color.GREEN);break; case 2:paint.setColor(Color.RED);break; case 3:paint.setColor(Color.YELLOW);break; default:paint.setColor(Color.WHITE);break; } //画一个坐标在(100,100),半径为60的圆 canvas.drawCircle(100,100,60,paint); } }
MainActivity.java
Java代码- packagecom.loulijun.viewdemo;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.view.KeyEvent;
- importandroid.view.MotionEvent;
- publicclassMainActivityextendsActivity{
- //设置一个id
- publicstaticfinalintREFRESH=0X000001;
- //声明ViewDemo
- privateViewDemomv=null;
- publicvoidonCreate(BundlesavedInstanceState)
- {
- super.onCreate(savedInstanceState);
- //实例化ViewDemo对象
- mv=newViewDemo(this);
- //设置显示为我们自定义的View
- setContentView(mv);
- //开启线程
- newThread(newGameThread()).start();
- }
- Handlerhandler=newHandler()
- {
- //接收消息后处理
- publicvoidhandleMessage(Messagemsg)
- {
- switch(msg.what)
- {
- caseMainActivity.REFRESH:mv.invalidate();break;
- }
- super.handleMessage(msg);
- }
- };
- //内部类,需要实现一个Runnable接口
- classGameThreadimplementsRunnable
- {
- @Override
- publicvoidrun(){
- //如果当前线程没有中断
- while(!Thread.currentThread().isInterrupted())
- {
- Messagemessage=newMessage();
- message.what=MainActivity.REFRESH;
- //发送消息
- handler.sendMessage(message);
- try
- {
- Thread.sleep(500);
- }catch(InterruptedExceptione)
- {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
package com.loulijun.viewdemo;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.KeyEvent;import android.view.MotionEvent;public class MainActivity extends Activity {//设置一个idpublic static final int REFRESH = 0X000001;//声明ViewDemoprivate ViewDemo mv = null;public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);//实例化ViewDemo对象mv = new ViewDemo(this);//设置显示为我们自定义的ViewsetContentView(mv);//开启线程new Thread(new GameThread()).start();}Handler handler = new Handler(){//接收消息后处理public void handleMessage(Message msg){switch(msg.what){case MainActivity.REFRESH:mv.invalidate();break;}super.handleMessage(msg);}};//内部类,需要实现一个Runnable接口class GameThread implements Runnable{@Overridepublic void run() {//如果当前线程没有中断while(!Thread.currentThread().isInterrupted()){Message message = new Message();message.what = MainActivity.REFRESH;//发送消息handler.sendMessage(message);try{Thread.sleep(500);}catch(InterruptedException e){Thread.currentThread().interrupt();}}}}
分析:
这里,通过实例化一个Handler对象并重写handleMessage方法来实现一个消息接收器,然后再线程中通过sendMessage()方法发送更新界面的消息,当接收器收到更新界面的时候,便开始执行invalidate()方法更新屏幕信息。
当然,还可以直接在线程中使用postInvalidate()方法在线程中更新界面,而不用再使用Handler来接收消息了
MainActivity.java
Java代码- packagecom.loulijun.viewdemo;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.view.KeyEvent;
- importandroid.view.MotionEvent;
- publicclassMainActivityextendsActivity{
- //设置一个id
- publicstaticfinalintREFRESH=0X000001;
- //声明ViewDemo
- privateViewDemomv=null;
- publicvoidonCreate(BundlesavedInstanceState)
- {
- super.onCreate(savedInstanceState);
- //实例化ViewDemo对象
- mv=newViewDemo(this);
- //设置显示为我们自定义的View
- setContentView(mv);
- //开启线程
- newThread(newGameThread()).start();
- }
- //内部类,需要实现一个Runnable接口
- classGameThreadimplementsRunnable
- {
- @Override
- publicvoidrun(){
- //如果当前线程没有中断
- while(!Thread.currentThread().isInterrupted())
- {
- try
- {
- Thread.sleep(500);
- }catch(InterruptedExceptione)
- {
- Thread.currentThread().interrupt();
- }
- //使用postInvalidate()也可以直接在线程中更新界面,这样就不再需要HandlerMessage来接收消息了
- mv.postInvalidate();
- }
- }
- }
- //触笔事件
- publicbooleanonTouchEvent(MotionEventevent)
- {
- returntrue;
- }
- //按键按下事件
- publicbooleanonKeyDown(intkeyCode,KeyEventevent)
- {
- returntrue;
- }
- //按键弹起事件
- publicbooleanonKeyUp(intkeyCode,KeyEventevent)
- {
- returnfalse;
- }
- publicbooleanonKeyMultiple(intkeyCode,intrepeatCount,KeyEventevent)
- {
- returntrue;
- }
- }
更多相关文章
- Android 获取手机屏幕大小两种方法
- android代码实现按钮自旋转
- android中如何利用线程循环打印
- Android中MAC地址获取代码
- Android Timer 实现方法
- Android 显示/隐藏 软键盘 方法
- Android中的一些方法-----生生不息