導航:首頁 > 操作系統 > 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