导航:首页 > 操作系统 > androidlockcanvas

androidlockcanvas

发布时间:2022-05-28 02:57:59

android如何在屏幕点击位置画一个小圆

主要运用SurfaceView来实现在屏幕上画一个圆,你可以通过按方向键和触摸屏幕来改变圆的位置

代码:
Activity

package com.view;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// 隐藏状态栏
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

// 把Activity的标题去掉
requestWindowFeature(Window.FEATURE_NO_TITLE);

// 设置布局
this.setContentView(new MySurfaceView(this));
}
}

SurfaceView

package com.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class MySurfaceView extends SurfaceView implements Runnable, Callback {

private SurfaceHolder mHolder; // 用于控制SurfaceView

private Thread t; // 声明一条线程

private boolean flag; // 线程运行的标识,用于控制线程

private Canvas mCanvas; // 声明一张画布

private Paint p; // 声明一支画笔

private int x = 50, y = 50, r = 10; // 圆的坐标和半径

public MySurfaceView(Context context) {
super(context);

mHolder = getHolder(); // 获得SurfaceHolder对象
mHolder.addCallback(this); // 为SurfaceView添加状态监听
p = new Paint(); // 创建一个画笔对象
p.setColor(Color.WHITE); // 设置画笔的颜色为白色
setFocusable(true); // 设置焦点
}

/**
* 自定义一个方法,在画布上画一个圆
*/
public void Draw() {
mCanvas = mHolder.lockCanvas(); // 获得画布对象,开始对画布画画
mCanvas.drawRGB(0, 0, 0); // 把画布填充为黑色
mCanvas.drawCircle(x, y, r, p); // 画一个圆
mHolder.unlockCanvasAndPost(mCanvas); // 完成画画,把画布显示在屏幕上
}

/**
* 当SurfaceView创建的时候,调用此函数
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
t = new Thread(this); // 创建一个线程对象
flag = true; // 把线程运行的标识设置成true
t.start(); // 启动线程
}

/**
* 当SurfaceView的视图发生改变的时候,调用此函数
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}

/**
* 当SurfaceView销毁的时候,调用此函数
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
flag = false; // 把线程运行的标识设置成false
}

/**
* 当屏幕被触摸时调用
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
x = (int) event.getX(); // 获得屏幕被触摸时对应的X轴坐标
y = (int) event.getY(); // 获得屏幕被触摸时对应的Y轴坐标
return true;
}

/**
* 当用户按键时调用
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_DPAD_UP){ //当用户点击↑键时
y--; //设置Y轴坐标减1
}
return super.onKeyDown(keyCode, event);
}

@Override
public void run() {
while (flag) {
Draw(); // 调用自定义画画方法
try {
Thread.sleep(50); // 让线程休息50毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

MySurfaceView首先继承SurfaceView,然后实现Runnable和Callback接口

重写了Runnable的run方法和Callback的surfaceCreated(SurfaceHolder holder),surfaceChanged(SurfaceHolder holder, int format, int width,int height),surfaceDestroyed(SurfaceHolder holder)方法,
还实现了onTouchEvent(MotionEvent event),onKeyDown(int keyCode, KeyEvent event)方法来,详细的在代码里已注释。

❷ android videoview和surfaceview的区别

在Android游戏当中充当主要的除了控制类外就是显示类,在J2ME中我们用Display和Canvas来实现这些,而Google Android中涉及到显示的为view类,Android游戏开发中比较重要和复杂的就是显示和游戏逻辑的处理。
这里说下android.view.View和android.view.SurfaceView。SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView,到底有哪些优势呢? SurfaceView可以控制表面的格式,比如大小,显示在屏幕中的位置,最关键是的提供了SurfaceHolder类,使用getHolder方法获取,相关的有Canvas lockCanvas()
Canvas lockCanvas(Rect dirty) 、void removeCallback(SurfaceHolder.Callback callback)、void unlockCanvasAndPost(Canvas canvas) 控制图形以及绘制,而在SurfaceHolder.Callback 接口回调中可以通过重写下面方法实现。

使用的SurfaceView的时候,一般情况下要对其进行创建,销毁,改变时的情况进行监视,这就要用到 SurfaceHolder.Callback.
class XxxView extends SurfaceView implements SurfaceHolder.Callback {

public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}
//看其名知其义,在surface的大小发生改变时激发
public void surfaceCreated(SurfaceHolder holder){}
//同上,在创建时激发,一般在这里调用画图的线程。
public void surfaceDestroyed(SurfaceHolder holder) {}
//同上,销毁时激发,一般在这里将画图的线程停止、释放。

}

对于Surface相关的,Android底层还提供了GPU加速功能,所以一般实时性很强的应用中主要使用SurfaceView而不是直接从View构建,同时后来做android 3d OpenGL中的GLSurfaceView也是从该类实现。

SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。
那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。
当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。

所以基于以上,根据游戏特点,一般分成两类。

1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。

2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。

3.Android中的SurfaceView类就是双缓冲机制。因此,开发游戏时尽量使用SurfaceView而不要使用View,这样的话效率较高,而且SurfaceView的功能也更加完善。

考虑以上几点,所以我一直都选用 SurfaceView 来进行游戏开发。
那么在以后源码实例中,都会以继承sarfaceView框架来进行演示。

❸ android的surfaceView类不执行surfaceCreated(),lockCanvas返回null

你把你初始化的代码放到onCreate外面去,然后在oncreate里面调用ca1=sfh.lockCanvas(null);
试试。

❹ 对android中的surfaceview的困惑,双缓冲区该怎么理解

  1. 最近开发一款小游戏,需要用到surfaceView,出于效率的考虑,需要使用脏矩形刷新技术。一开始怎么都不成功,到网上搜了很多有关脏矩形的使用的文章,但总是不懂。后来就只能到google上去搜索英文的相关文章,但是也收获甚微。后来,直接看Android
    Developers上面的解释,也是一懂半懂的。

  2. canvas
    = holder.lockCanvas(Rect
    dirty);中定义脏矩形刷新。我的理解是,给定dirty之后,系统会自动把前一个画布中dirty矩形外的部分拷贝过来,然后把dirty矩形内部留给现在的canvas来绘制。但是在项目的运行中,我发现根本不是这样的,系统好像不会自动拷贝dirty之外的部分过来,因为我的背景图片在绘制了一次之后,直接被黑色背景覆盖了。我查了一下AndroidDevelopers上面有关这个脏矩形的讲解,上面这样介绍:Just
    likelockCanvas()but allows
    specification of a dirty rectangle. Every pixel within that
    rectangle must be written; however pixels outside the dirty
    rectangle will be preserved by the next call to
    lockCanvas()。意思就是说:在矩形内的每一个像素必须都要被写入,然后dirty矩形外的像素将在下次调用的时候保留。我在想,这个dirty脏矩形是不是为下次的绘图而准备的?

  3. 后来又仔细想了一会,结合网上的有关surfaceView的双缓冲实现,我觉得可能问题是这样的:第一次画背景是画在前景帧上,缓冲帧没有。而第二次画时,系统把缓冲帧与前景帧调换了,这样由于之前的缓冲帧里面没有画背景,就导致第二次绘画中背景没有画出来。而第二次绘画又是使用的脏矩形绘制,将在下一次绘制的时候保留脏矩形之外的部分,导致第三次绘画时,虽然调出了最开始画了背景的那一帧,但是脏矩形机制填充了脏矩形之外的部分,导致背景再次被覆盖。自此,背景彻底从缓冲的两帧中消失了。

  4. 找到了原因所在,解决就比较好办了。直接在一开始的时候,调用两遍绘制背景的函数,这样保证缓冲的两帧上面都有背景,那么之后再用脏矩形,就没有问题了。

  5. 当然,明白了这些,就不难解释网上那些闪烁的问题的根源了。只需要在一开始把背景绘制两遍即可。

  6. 在解决这个问题的过程中,通过所查的资料,以及我单步跟踪调试,也发现了一个android的隐藏操作:就是在每次定制好脏矩形之后,android系统会自动重置脏矩形的大小尺寸(一般重置为当前整个画布的大小),所以,为了能够在下次循环的时候能够继续调用之前的脏矩形对象,就需要重置一下脏矩形的大小;或者还有一个办法,就是直接写一个函数,这个函数返回一个脏矩形的拷贝给canvas,这样canvas就只能更改这个拷贝,而不能更改脏矩形对象本身了。

❺ Android自定义控件复写onDraw(Canvas canvas),canvas是怎样获取的

ViewRootImpl.java

如果是软件绘制的话,drawSoftWare方法会调用view.draw()方法。

从上图中可以看到canvas来源于mSurface.lockCanvas。这里会调用到native层,简单点说就是去申请了一块buffer。这个时候canvas就可以用了,接下来就会调用view.draw方法。

具体点的过程自己可以去看看。

❻ android里面如何填充矩形呢

方案:

在canvas上画矩形,然后设置画笔为实心就可以了。

代码示例:

paint.setStyle(Style.FILL);//实心矩形框
paint.setColor(Color.RED);//颜色为红色
canvas.drawRect(newRectF(10,10,300,100),paint);//画一个290*90的红色实心矩形

❼ android开发:lockcanvas返回null,附上简单的代码

一般很少这样使用surfaceview的,一般使用surfaceview来做游戏界面,开一个线程不断的对canvas重新绘制,像你实现的这种功能 让你的自定义view集成View类就行了,没必要使用surfaceview

一般来说surfaceview 这样使用

publicvoiddraw(){
Canvascanvas=null;
synchronized(holder){
try{
canvas=holder.lockCanvas();

if(whichView==WhichView.start_view){
if(canvas!=null)
canvas.drawBitmap(bitmap,0,0,paint);
hero.drawSelf(canvas,x,y,direction);
}
}catch(Exceptione){
e.printStackTrace();
}
finally{
if(canvas!=null)
holder.unlockCanvasAndPost(canvas);
}
}
}


然后再一个线程里调用draw()方法不断进行界面绘制
像你的那种情况应该是你调用lockcanvas的时候surfaceView还没有创建,你可以尝试在surfaceCreate()中调用这个方法,刚开始这个canvas确实是获取不到的。我尝试过

❽ android 中 holder.lockCanvas(null)为什么获取为空

在canvas进行画图时,会把原有的图层清空,以盛放新的新的绘图区内容;反正获取画布,代码都这样格式的,另外这个问题国内外都有争议,不知道底层代码怎么搞的

❾ android surfaceview视频播放如何让视频翻转90

《android逆向视频》网络网盘资源免费下载

链接:https://pan..com/s/1W1NAE-AeKbz0bb6E4mdXfA

提取码:5yme
android逆向视频|第一章:Android Java 逆向基础|第五章:Android arm native 逆向|第四章:Android 系统编译|第三章:阶段考核|第七章:Android 应用脱壳|第六章:Android 应用初步编程保护|第二章:Android Hook 插件开发|第八章:Android 应用保护|课时4 Android 加壳保护工具编写3.mp4|课时3 Android 加壳保护工具编写2.mp4|课时2 Android 加壳保护工具编写1.mp4|课时1 Android 加壳原理.mp4|课时3 快速Hook代码搭建之 Xposed.mp4|课时2 快速Hook代码搭建之 Cydia Substrate.mp4

❿ android 怎么在屏幕中间画一个圆

主要运用SurfaceView来实现在屏幕上画一个圆,你可以通过按方向键和触摸屏幕来改变圆的位置 代码: Activity package com.view; import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 隐藏状态栏 this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 把Activity的标题去掉 requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置布局 this.setContentView(new MySurfaceView(this)); } } SurfaceView package com.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; public class MySurfaceView extends SurfaceView implements Runnable, Callback { private SurfaceHolder mHolder; // 用于控制SurfaceView private Thread t; // 声明一条线程 private boolean flag; // 线程运行的标识,用于控制线程 private Canvas mCanvas; // 声明一张画布 private Paint p; // 声明一支画笔 private int x = 50, y = 50, r = 10; // 圆的坐标和半径 public MySurfaceView(Context context) { super(context); mHolder = getHolder(); // 获得SurfaceHolder对象 mHolder.addCallback(this); // 为SurfaceView添加状态监听 p = new Paint(); // 创建一个画笔对象 p.setColor(Color.WHITE); // 设置画笔的颜色为白色 setFocusable(true); // 设置焦点 } /** * 自定义一个方法,在画布上画一个圆 */ public void Draw() { mCanvas = mHolder.lockCanvas(); // 获得画布对象,开始对画布画画 mCanvas.drawRGB(0, 0, 0); // 把画布填充为黑色 mCanvas.drawCircle(x, y, r, p); // 画一个圆 mHolder.unlockCanvasAndPost(mCanvas); // 完成画画,把画布显示在屏幕上 } /** * 当SurfaceView创建的时候,调用此函数 */ @Override public void surfaceCreated(SurfaceHolder holder) { t = new Thread(this); // 创建一个线程对象 flag = true; // 把线程运行的标识设置成true t.start(); // 启动线程 } /** * 当SurfaceView的视图发生改变的时候,调用此函数 */ @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } /** * 当SurfaceView销毁的时候,调用此函数 */ @Override public void surfaceDestroyed(SurfaceHolder holder) { flag = false; // 把线程运行的标识设置成false } /** * 当屏幕被触摸时调用 */ @Override public boolean onTouchEvent(MotionEvent event) { x = (int) event.getX(); // 获得屏幕被触摸时对应的X轴坐标 y = (int) event.getY(); // 获得屏幕被触摸时对应的Y轴坐标 return true; } /** * 当用户按键时调用 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_DPAD_UP){ //当用户点击↑键时 y--; //设置Y轴坐标减1 } return super.onKeyDown(keyCode, event); } @Override public void run() { while (flag) { Draw(); // 调用自定义画画方法 try { Thread.sleep(50); // 让线程休息50毫秒 } catch (InterruptedException e) { e.printStackTrace(); } } } } MySurfaceView首先继承SurfaceView,然后实现Runnable和Callback接口 重写了Runnable的run方法和Callback的surfaceCreated(SurfaceHolder holder),surfaceChanged(SurfaceHolder holder, int format, int width,int height),surfaceDestroyed(SurfaceHolder holder)方法, 还实现了onTouchEvent(MotionEvent event),onKeyDown(int keyCode, KeyEvent event)方法来,详细的在代码里已注释。

阅读全文

与androidlockcanvas相关的资料

热点内容
自己购买云主服务器推荐 浏览:422
个人所得税java 浏览:761
多余的服务器滑道还有什么用 浏览:192
pdf劈开合并 浏览:28
不能修改的pdf 浏览:752
同城公众源码 浏览:489
一个服务器2个端口怎么映射 浏览:298
java字符串ascii码 浏览:79
台湾云服务器怎么租服务器 浏览:475
旅游手机网站源码 浏览:332
android关联表 浏览:946
安卓导航无声音怎么维修 浏览:333
app怎么装视频 浏览:431
安卓系统下的软件怎么移到桌面 浏览:96
windows拷贝到linux 浏览:772
mdr软件解压和别人不一样 浏览:904
单片机串行通信有什么好处 浏览:340
游戏开发程序员书籍 浏览:860
pdf中图片修改 浏览:288
汇编编译后 浏览:491