編輯:關於Android編程
一、基礎知識:
SurfaceView繼承自View,View負責在主線程中更新動畫,而SurfaceView是在一個新線程中更新動畫。
SurfaceView類的主要方法:
// 在SurfaceView創建時調用
pubilic abstract void surfaceCreated(SurfaceHolder holder)
// 在SurfaceView改變時調用
pubilic abstract void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
// 在SurfaceView銷毀時調用
pubilic abstract void surfaceDestroyed(SurfaceHolder holder)
// 繪制SurfaceView畫面
protected void onDraw(Canvas canvas)
(參數canvas是該SurfaceView的畫筆,每一次SurfaceView中畫面改變都是調用了該方法)
二、實現效果:
首先有一副圖片從屏幕的左下角開始向右上方運動,當圖片上沿與手機屏幕上沿相撞時,圖片的水平速度大小與方向均不變,豎直方向上速度大小不變,
方向相反;當下沿相撞後,同樣效果,直到圖片飛出屏幕。之後,屏幕漸漸地顯示一幅圖片。
三、編程實現:
1. 界面編輯(res\layout\main.xml):
[java]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
2. 代碼編輯:
(\src\wyf\zcl\MyActivity.java)
[java]
package wyf.zcl;
/*
* 該例子演示surfaceView中簡單場景的繪制
* MyActivity.java 為程序的主Activity
* MySurfaceView.java 為程序的SurfaceView類
* Constant.java 常量類,將常量全部寫在該類中
* OnDrawThread.java 該類的作用是時時刷新onDraw,進行畫面的重繪
* PicRunThread.java 該類是控制duke圖片運動的類
* */
import android.app.Activity; //引入相關包
import android.content.pm.ActivityInfo; //引入相關包
import android.os.Bundle; //引入相關包
import android.view.Window; //引入相關包
import android.view.WindowManager; //引入相關包
public class MyActivity extends Activity {
/** Called when the activity is first created. */
private MySurfaceView msv; //得到surfaceView的引用
@Override
public void onCreate(Bundle savedInstanceState) { //Activity的生命周期函數,該函數是在程序創建時調用
super.onCreate(savedInstanceState);
msv=new MySurfaceView(MyActivity.this); //實例化MySurfaceView的對象
requestWindowFeature(Window.FEATURE_NO_TITLE); //設置屏幕顯示沒有title欄
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,
WindowManager.LayoutParams.FLAG_FULLSCREEN); //設置全屏
//設置只允許橫屏
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(msv); //設置Activity顯示的內容為msv
}
}
package wyf.zcl;
/*
* 該例子演示surfaceView中簡單場景的繪制
* MyActivity.java 為程序的主Activity
* MySurfaceView.java 為程序的SurfaceView類
* Constant.java 常量類,將常量全部寫在該類中
* OnDrawThread.java 該類的作用是時時刷新onDraw,進行畫面的重繪
* PicRunThread.java 該類是控制duke圖片運動的類
* */
import android.app.Activity; //引入相關包
import android.content.pm.ActivityInfo; //引入相關包
import android.os.Bundle; //引入相關包
import android.view.Window; //引入相關包
import android.view.WindowManager; //引入相關包
public class MyActivity extends Activity {
/** Called when the activity is first created. */
private MySurfaceView msv; //得到surfaceView的引用
@Override
public void onCreate(Bundle savedInstanceState) { //Activity的生命周期函數,該函數是在程序創建時調用
super.onCreate(savedInstanceState);
msv=new MySurfaceView(MyActivity.this); //實例化MySurfaceView的對象
requestWindowFeature(Window.FEATURE_NO_TITLE); //設置屏幕顯示沒有title欄
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,
WindowManager.LayoutParams.FLAG_FULLSCREEN); //設置全屏
//設置只允許橫屏
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(msv); //設置Activity顯示的內容為msv
}
}
(\src\wyf\zcl\Constant.java)
[java]
package wyf.zcl;
import android.view.Display;
//Constant.java 常量類,將常量全部寫在該類中
public class Constant {
public static int SCREENWIDTH=480; //屏幕寬(本程序為橫屏)
public static int SCREENHEIGHT=320; //屏幕高
public static int PICWIDTH=64; //圖片寬度
public static int PICHEIGHT=64; //圖片高度
public static int ONDRAWSPEED=30; //onDraw線程類的繪制間隔時間
public static float PICXSPEED=1.5f; //圖片水平移動速度
public static float PICYSPEED=2; //圖片垂直移動速度
public static int PICRUNSPEED=30; //圖片的運動線程的刷新速度
public static int PICALPHASPEED=20; //圖片漸暗效果演示刷新速度
}
package wyf.zcl;
import android.view.Display;
//Constant.java 常量類,將常量全部寫在該類中
public class Constant {
public static int SCREENWIDTH=480; //屏幕寬(本程序為橫屏)
public static int SCREENHEIGHT=320; //屏幕高
public static int PICWIDTH=64; //圖片寬度
public static int PICHEIGHT=64; //圖片高度
public static int ONDRAWSPEED=30; //onDraw線程類的繪制間隔時間
public static float PICXSPEED=1.5f; //圖片水平移動速度
public static float PICYSPEED=2; //圖片垂直移動速度
public static int PICRUNSPEED=30; //圖片的運動線程的刷新速度
public static int PICALPHASPEED=20; //圖片漸暗效果演示刷新速度
}
(\src\wyf\zcl\MySurfaceView.java)
[java]
package wyf.zcl;
import android.content.Context; //引入相關包
import android.graphics.Bitmap; //引入相關包
import android.graphics.BitmapFactory; //引入相關包
import android.graphics.Canvas; //引入相關包
import android.graphics.Color; //引入相關包
import android.graphics.Paint; //引入相關包
import android.view.Display; //引入相關包
import android.view.SurfaceHolder; //引入相關包
import android.view.SurfaceView; //引入相關包
public class MySurfaceView extends SurfaceView
implements SurfaceHolder.Callback{
//此處實現SurfaceHolder.Callback接口,為surfaceView添加生命周期回調函數
int dy=Display.DEFAULT_DISPLAY;
MyActivity ma; //得到MyActivity的引用
Paint paint; //畫筆的引用
OnDrawThread odt; //OnDrawThread類引用
PicRunThread prt; //圖片運動的Thread類引用
private float picX=0; //圖片x坐標
private float picY=0; //圖片y坐標
boolean picAlphaFlag=false; //圖片變暗效果的標記,false為不顯示,true為顯示。
int picAlphaNum=0; //圖片變暗效果中畫筆的alpha值
public MySurfaceView(Context context) {
super(context);
this.ma=(MyActivity) context;
//將ma的引用指向調用了該Surfaceview類構造器方法的對象,本例為MyActivity
this.getHolder().addCallback(this); //注冊回調接口
paint=new Paint(); //實例化畫筆
odt=new OnDrawThread(this); //實例化OnDrawThread類
prt=new PicRunThread(this); //實例化PicRunThread類
prt.start();
}
public void setPicX(float picX) { //圖片x坐標的設置器
this.picX = picX;
}
public void setPicY(float picY) { //圖片y坐標的設置器
this.picY = picY;
}
public void setPicAlphaNum(int picAlphaNum) {//圖片變暗效果alpha參數設置器
this.picAlphaNum = picAlphaNum;
}
@Override
protected void onDraw(Canvas canvas) { //onDraw方法,此方法用於繪制圖像,圖形等
super.onDraw(canvas);
paint.setColor(Color.WHITE); //設置畫筆為白色
canvas.drawRect(0, 0, Constant.SCREENWIDTH, Constant.SCREENHEIGHT, paint);
//此處畫了一個白色的全屏幕的矩形,目的是設置背景為白色,同時每次重繪時清除背景
//進行平面貼圖
Bitmap bitmapDuke=BitmapFactory.decodeResource(ma.getResources(), R.drawable.duke);
canvas.drawBitmap(bitmapDuke, picX, picY, paint);
//圖片漸暗效果
if(picAlphaFlag){
Bitmap bitmapBG=BitmapFactory.decodeResource(ma.getResources(), R.drawable.jpg1);
paint.setAlpha(picAlphaNum);
canvas.drawBitmap(bitmapBG, 0,0, paint);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) { //此方法為當surfaceView改變時調用,如屏幕大小改變。
}
@Override
public void surfaceCreated(SurfaceHolder holder) {//此方法為在surfaceView創建時調用
odt.start(); //啟動onDraw的繪制線程
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {//此方法為在surfaceView銷毀前調用
}
}
package wyf.zcl;
import android.content.Context; //引入相關包
import android.graphics.Bitmap; //引入相關包
import android.graphics.BitmapFactory; //引入相關包
import android.graphics.Canvas; //引入相關包
import android.graphics.Color; //引入相關包
import android.graphics.Paint; //引入相關包
import android.view.Display; //引入相關包
import android.view.SurfaceHolder; //引入相關包
import android.view.SurfaceView; //引入相關包
public class MySurfaceView extends SurfaceView
implements SurfaceHolder.Callback{
//此處實現SurfaceHolder.Callback接口,為surfaceView添加生命周期回調函數
int dy=Display.DEFAULT_DISPLAY;
MyActivity ma; //得到MyActivity的引用
Paint paint; //畫筆的引用
OnDrawThread odt; //OnDrawThread類引用
PicRunThread prt; //圖片運動的Thread類引用
private float picX=0; //圖片x坐標
private float picY=0; //圖片y坐標
boolean picAlphaFlag=false; //圖片變暗效果的標記,false為不顯示,true為顯示。
int picAlphaNum=0; //圖片變暗效果中畫筆的alpha值
public MySurfaceView(Context context) {
super(context);
this.ma=(MyActivity) context;
//將ma的引用指向調用了該Surfaceview類構造器方法的對象,本例為MyActivity
this.getHolder().addCallback(this); //注冊回調接口
paint=new Paint(); //實例化畫筆
odt=new OnDrawThread(this); //實例化OnDrawThread類
prt=new PicRunThread(this); //實例化PicRunThread類
prt.start();
}
public void setPicX(float picX) { //圖片x坐標的設置器
this.picX = picX;
}
public void setPicY(float picY) { //圖片y坐標的設置器
this.picY = picY;
}
public void setPicAlphaNum(int picAlphaNum) {//圖片變暗效果alpha參數設置器
this.picAlphaNum = picAlphaNum;
}
@Override
protected void onDraw(Canvas canvas) { //onDraw方法,此方法用於繪制圖像,圖形等
super.onDraw(canvas);
paint.setColor(Color.WHITE); //設置畫筆為白色
canvas.drawRect(0, 0, Constant.SCREENWIDTH, Constant.SCREENHEIGHT, paint);
//此處畫了一個白色的全屏幕的矩形,目的是設置背景為白色,同時每次重繪時清除背景
//進行平面貼圖
Bitmap bitmapDuke=BitmapFactory.decodeResource(ma.getResources(), R.drawable.duke);
canvas.drawBitmap(bitmapDuke, picX, picY, paint);
//圖片漸暗效果
if(picAlphaFlag){
Bitmap bitmapBG=BitmapFactory.decodeResource(ma.getResources(), R.drawable.jpg1);
paint.setAlpha(picAlphaNum);
canvas.drawBitmap(bitmapBG, 0,0, paint);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) { //此方法為當surfaceView改變時調用,如屏幕大小改變。
}
@Override
public void surfaceCreated(SurfaceHolder holder) {//此方法為在surfaceView創建時調用
odt.start(); //啟動onDraw的繪制線程
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {//此方法為在surfaceView銷毀前調用
}
}
(\src\wyf\zcl\OnDrawThread.java)
[java]
package wyf.zcl;
import android.graphics.Canvas; //引入相關包
import android.view.SurfaceHolder; //引入相關包
//該類的作用是時時刷新onDraw,進行畫面的重繪
public class OnDrawThread extends Thread{
MySurfaceView msv; //得到MySurfaceView的引用
SurfaceHolder sh; //SurfaceHolder引用
public OnDrawThread(MySurfaceView msv) {
super();
this.msv = msv; //構造方法中,將msv引用指向調用了該類的MySurfaceView的對象
sh=msv.getHolder();
}
@Override
public void run() {
super.run();
Canvas canvas = null; //Canvas的引用
while(true){
try{
canvas=sh.lockCanvas(null); //將canvas的引用指向surfaceView的canvas的對象
synchronized(this.sh){ //繪制過程,可能帶來同步方面的問題,加鎖
if(canvas!=null){
msv.onDraw(canvas);
}
}
}finally{
try{
if(sh!=null){
sh.unlockCanvasAndPost(canvas); //繪制完後解鎖
}
}catch(Exception e){e.printStackTrace();}
}
try{
Thread.sleep(Constant.ONDRAWSPEED); //休息1秒鐘
}catch(Exception e){e.printStackTrace();}
}
}
}
package wyf.zcl;
import android.graphics.Canvas; //引入相關包
import android.view.SurfaceHolder; //引入相關包
//該類的作用是時時刷新onDraw,進行畫面的重繪
public class OnDrawThread extends Thread{
MySurfaceView msv; //得到MySurfaceView的引用
SurfaceHolder sh; //SurfaceHolder引用
public OnDrawThread(MySurfaceView msv) {
super();
this.msv = msv; //構造方法中,將msv引用指向調用了該類的MySurfaceView的對象
sh=msv.getHolder();
}
@Override
public void run() {
super.run();
Canvas canvas = null; //Canvas的引用
while(true){
try{
canvas=sh.lockCanvas(null); //將canvas的引用指向surfaceView的canvas的對象
synchronized(this.sh){ //繪制過程,可能帶來同步方面的問題,加鎖
if(canvas!=null){
msv.onDraw(canvas);
}
}
}finally{
try{
if(sh!=null){
sh.unlockCanvasAndPost(canvas); //繪制完後解鎖
}
}catch(Exception e){e.printStackTrace();}
}
try{
Thread.sleep(Constant.ONDRAWSPEED); //休息1秒鐘
}catch(Exception e){e.printStackTrace();}
}
}
}
(\src\wyf\zcl\PicRunThread.java)
[java]
package wyf.zcl;
//該類是控制duke圖片運動的類
public class PicRunThread extends Thread{
MySurfaceView msv; //MySurfaceView的引用
private float picX=0; //圖片x坐標
private float picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT; //圖片y坐標
boolean yRunFlag=false; //y方向上的運動標記,false時y=y+speed,true時y=y-speed
int picAlphaNum=0; //圖片變暗效果中畫筆的alpha值
public PicRunThread(MySurfaceView msv) {
super();
this.msv = msv; //將該線程類的引用指向調用其的MySurfaceView的對象
}
@Override
public void run() {
super.run();
while(true){
//控制duke圖片的運動
while(this.picX<Constant.SCREENWIDTH){ //當圖片的左邊完全超過屏幕的右邊時,循環結束
msv.setPicX(picX);
msv.setPicY(picY);
picX=picX+Constant.PICXSPEED;
if(yRunFlag){//應該向上運動,自減
picY=picY-Constant.PICYSPEED;
}else{//應該向下運動,自加
picY=picY+Constant.PICYSPEED;
}
if(picY<=0){ //到達屏幕上沿
yRunFlag=false;
}else if(picY>Constant.SCREENHEIGHT-Constant.PICHEIGHT){ //到達屏幕下沿
yRunFlag=true;
}
try{
Thread.sleep(Constant.PICRUNSPEED);
}catch(Exception e){e.printStackTrace();}
}
//圖片變暗效果演示
msv.picAlphaFlag=true; //開啟圖片變暗效果
for(picAlphaNum=0;picAlphaNum<=255;picAlphaNum++){
if(picAlphaNum==255){
msv.picAlphaFlag=false; //當圖片變暗效果結束,標記重置
picX=0; //圖片x坐標
picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT; //圖片y坐標
System.out.println(msv.picAlphaFlag+"picX:"+picX+"picY:"+picY);
}
msv.setPicAlphaNum(picAlphaNum);
try{
Thread.sleep(Constant.PICALPHASPEED);
}catch(Exception e){e.printStackTrace();}
}
}
}
}
package wyf.zcl;
//該類是控制duke圖片運動的類
public class PicRunThread extends Thread{
MySurfaceView msv; //MySurfaceView的引用
private float picX=0; //圖片x坐標
private float picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT; //圖片y坐標
boolean yRunFlag=false; //y方向上的運動標記,false時y=y+speed,true時y=y-speed
int picAlphaNum=0; //圖片變暗效果中畫筆的alpha值
public PicRunThread(MySurfaceView msv) {
super();
this.msv = msv; //將該線程類的引用指向調用其的MySurfaceView的對象
}
@Override
public void run() {
super.run();
while(true){
//控制duke圖片的運動
while(this.picX<Constant.SCREENWIDTH){ //當圖片的左邊完全超過屏幕的右邊時,循環結束
msv.setPicX(picX);
msv.setPicY(picY);
picX=picX+Constant.PICXSPEED;
if(yRunFlag){//應該向上運動,自減
picY=picY-Constant.PICYSPEED;
}else{//應該向下運動,自加
picY=picY+Constant.PICYSPEED;
}
if(picY<=0){ //到達屏幕上沿
yRunFlag=false;
}else if(picY>Constant.SCREENHEIGHT-Constant.PICHEIGHT){ //到達屏幕下沿
yRunFlag=true;
}
try{
Thread.sleep(Constant.PICRUNSPEED);
}catch(Exception e){e.printStackTrace();}
}
//圖片變暗效果演示
msv.picAlphaFlag=true; //開啟圖片變暗效果
for(picAlphaNum=0;picAlphaNum<=255;picAlphaNum++){
if(picAlphaNum==255){
msv.picAlphaFlag=false; //當圖片變暗效果結束,標記重置
picX=0; //圖片x坐標
picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT; //圖片y坐標
System.out.println(msv.picAlphaFlag+"picX:"+picX+"picY:"+picY);
}
msv.setPicAlphaNum(picAlphaNum);
try{
Thread.sleep(Constant.PICALPHASPEED);
}catch(Exception e){e.printStackTrace();}
}
}
}
}
這部分代碼對於我這個初學java的人來說比較吃力,但是硬著頭皮看了兩天,還是基本弄清了這個框架。
代碼中涉及一些java的基礎知識,我做了一點筆記,如下:
[ extends ]:
一個類使用關鍵字extends繼承其他類,關鍵字extends出現在類聲明時的類名後,
extends後面跟著的是要繼承的類的名稱,extends實現了繼承。在Java中的類只能繼承一個類。
[ super ]:
B 繼承 A ,B想調用A的方法,那麼就可以 用super.A的方法。如果用中文解釋:super就是父類的一個別名。
[ implements ]:
implements是一個類實現一個接口用的關鍵字,
他是用來實現接口中定義的抽象方法
。比如:people是一個接口,他裡面有say這個方法。
public interface people()
{
public say();
}
但是接口沒有方法體。
只能通過一個具體的類去實現其中的方法體。
比如chinese這個類,就實現了people這個接口。
public class chinese implements peopel{
public say()
{System.out.println("你好!");}
}
[ extends和implements區別]:
[plain]
extends是繼承父類,只要那個類不是聲明為final或者那個類定義為abstract的就能繼承,
JAVA中不支持多重繼承,但是可以用接口來實現,這樣就要用到implements,繼承只能繼承一個類,
但implements可以實現多個接口,用逗號分開就行了
比如
class A extends B implements C,D,E
extends是繼承父類,只要那個類不是聲明為final或者那個類定義為abstract的就能繼承,
JAVA中不支持多重繼承,但是可以用接口來實現,這樣就要用到implements,繼承只能繼承一個類,
但implements可以實現多個接口,用逗號分開就行了
比如
class A extends B implements C,D,E
前言:之前使用NPOI插件編寫的導表工具,其實就是直接將數據進行序列化,解析時還需要進行反序列化,步驟比較繁復,最近看到Google的一個開源的項目protobuf,不僅
最近在做Android下的流量分析的一個功能,查閱了眾多資料,在手機不用Root的情況下,可以設置代理,對流量分析。也可以使用Android系統提供的VpnService
實現功能:實現網絡音樂搜索功能實現網絡音樂下載功能下載好的音樂目前不在播放器內,可以通過文件浏覽器查看。後續將博文,將實現歌詞和下載音樂掃描功能。經過將近4天,才發布這一
效果圖如下所示:先給大家說下實現android 跳轉到通訊錄的實現思路:1.點擊跳轉到通訊錄界面2.獲取通訊錄姓名和手機號碼3.回調顯示姓名和手機號碼1首先是跳轉到通訊錄
Android的Notification是android系統中很重要的一