Chapter 12
Download
1 / 52

Android - PowerPoint PPT Presentation


  • 207 Views
  • Uploaded on

Chapter 12. Android 動畫程式設計. 前言. Android 在動畫程式設計上有非常多成熟的工具可以使用 。 例如說: Canvas 畫布、 ViewFlipper 動畫等,另外也可以使用 OpenGL 去設計 2D/3D 圖形或動畫,使手機多媒體或是操作介面有更多爆炸性的發展。. 畫布 / 畫筆. Canvas.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Android' - Lucy


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Chapter 12

Chapter 12

Android動畫程式設計


前言

Android在動畫程式設計上有非常多成熟的工具可以使用。

例如說:Canvas畫布、ViewFlipper動畫等,另外也可以使用OpenGL去設計2D/3D圖形或動畫,使手機多媒體或是操作介面有更多爆炸性的發展。


畫布/畫筆


Canvas
Canvas

  • Canvas物件在Java應用程式上已經非常成熟,用於Android上也是開發動畫或UI的一個好工具。Canvas就像手機中的畫布,可以在Canvas上繪製圖形或者圖片,一般我們可以使用以下四個組成部分,在Android上繪製圖形:

    • 點陣圖(包含像素)

    • Canvas畫布(包含繪畫內容,寫入點陣圖 )

    • 初始圖形(例如Rect、Bitmap、text…等等 )

    • Paint(用來描述上面初始圖形的顏色和類型…等等)


Canvas1
Canvas

  • View類別的onDraw方法會傳入一個Canvas物件,用來繪製元件界面的畫布。在實作onDraw方法時,經常會看到呼叫到save和restore方法,下面就解釋這兩個方法的作用:

    • save:保存Canvas的狀態。save之後,可以呼叫Canvas中的位移、縮放、旋轉、裁切…等等操作。

    • restore:回復Canvas之前保存的狀態。防止save後對Canvas執行的操作對後續繪製有所影響。


Canvas2
Canvas

save和restore要同時使用,如果restore呼叫次數比save多,會引發Error。

下面將有一簡易範例解說Canvas中較重要的部分,如圖所示。


Canvas3
Canvas

程式碼(CanvasEX.java):

package ncu.bnlab.CanvasExample;

import android.app.Activity;

import android.os.Bundle;

public class CanvasEX extends Activity

{

DrawAction drawAction;

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

drawAction = new DrawAction(this);

setContentView(drawAction);

/* requestFocus方法用於設置新焦點 */

drawAction.requestFocus();

}

}


Canvas4
Canvas

程式碼(DrawAction.java):

由於程式碼過多,完整程式碼請參考光碟中CanvasEX.java、DrawAction.java

public void onDraw(Canvas canvas)

{

/* 取得寬度 */

int px = getMeasuredWidth();

int py = getMeasuredWidth();

/* 設定線畫筆顏色 */

linePaint.setColor(Color.WHITE);

/* 設置為true可消除邊緣效果 */

linePaint.setAntiAlias(true);

/* 設定背景畫筆顏色 */

backgroundPaint.setColor(Color.BLUE);

backgroundPaint.setAntiAlias(true);

/* 設定方塊畫筆顏色 */

rectPaint.setColor(Color.RED);

rectPaint.setAntiAlias(true);

/* 於畫布繪製圖形 */

canvas.drawRect(0, 0, px, py, backgroundPaint);

/* 呼叫save方法儲存目前狀態 */

canvas.save();

........

/* 呼叫restore方法 */

canvas.restore();

/* 於畫布繪製方塊 */

canvas.drawRect(px, py, 300, 300, rectPaint);


Canvas5
Canvas

從範例可看出,其中紅色的方塊位置有明顯差異。

造成這樣的原因是因為將Canvas中save與restore方法註解,所有的圖都是在旋轉90°後的畫布上繪製。當執行完onDraw方法,系統自動將畫布恢復回來。


Paint
Paint

Paint類別擁有樣式與顏色資訊,主要是有關於如何繪製幾何圖形、文字及點陣圖的方法,範例如圖所示。


Paint1
Paint

布局文件(res/layout/main.xml):

<?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"

>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="horizontal"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

>

<Button

android:id="@+id/btnPrevious"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Previous"

/>

<Button

android:id="@+id/btnNext"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Next"

/>

</LinearLayout>

<ViewFlipper

android:id="@+id/viewFlipper"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:gravity="center"

/>

</LinearLayout>


Paint2
Paint

程式碼(PaintEX.java):

package ncu.bnlab.PaintExample;

import android.app.Activity;

import android.os.Bundle;

import android.view.Window;

import android.view.WindowManager;

@SuppressWarnings("unused")

public class PaintEX extends Activity

{

DrawAction drawAction;

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

/* getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); */

/* requestWindowFeature(Window.FEATURE_NO_TITLE); */

drawAction = new DrawAction(this);

setContentView(drawAction);

/* requestFocus方法用於設置新焦點 */

drawAction.requestFocus();

}

}


Paint3
Paint

程式碼-1(DrawAction.java):

程式碼-2(DrawAction.java):

@Override

public void onDraw(Canvas canvas)

{

for (Point point : points)

{

/*於畫布上繪製圖形*/

canvas.drawCircle(point.x, point.y, 5, paint);

}

}

public boolean onTouch(View view, MotionEvent event)

{

Point point = new Point();

/* 取得目前觸碰螢幕之x,y值 */

point.x = event.getX();

point.y = event.getY();

/* 新增點至Point物件 */

points.add(point);

/* 用於更新View */

invalidate();

return true;

}

List<Point> points = new ArrayList<Point>();

Paint paint = new Paint();

public DrawAction(Context context)

{

super(context);

/* 設定可取得焦點 */

setFocusable(true);

/* 設定在觸控模式可取得焦點 */

setFocusableInTouchMode(true);

/* 設定監聽器 */

this.setOnTouchListener(this);

/* 設定畫筆顏色 */

paint.setColor(Color.WHITE);

paint.setAntiAlias(true);

}


Paint4
Paint

了解上述Canvas與Paint結合的範例後,接著解說關於在Android中如何顯示字體,因為字體在所有應用中是最常被使用到的。字體一般擁有的屬性有大小、顏色、對齊方式、粗體、斜體、下劃線等。


Paint5
Paint

在Android中使用Typeface類別來定義字體。

Typeface可以指定字體和字體風格,並可用Paint繪製字型,Typeface就類似Paint中的其它屬性textSize,textSkewX,textScaleX...等等。下表為字體常數的定義:


Paint6
Paint

這些字體常數,在應用程式中是可以直接使用的,例如說:Typeface. SERIF。

另外Typeface也包含了一些用來處理字體的方法,例如:建立字體Create(),取得字體屬性getStyle()、isBold()、isItalic()…等等。

Typeface類別不僅定義了字體,還包括粗體(Bold)、斜體(Italic)。


Paint7
Paint

其它對顯示String有影響的因素,都可以在Paint類別中找到它們的方法,如下頁表所示:


Paint8
Paint

至此讀者應對Paint有基本的瞭解,實際上在Paint中還有其他一些功能,例如用Alpha來處理透明度、用Dither來處理混色...等等,詳細內容可參考Android SDK。


Paint9
Paint

接著就以一個簡單的範例來演練Typeface與Paint結合的做法,程式如圖所示。


Paint10
Paint

首先需將ttf字型檔加入專案中的fonts資料夾(於asset下新建),如圖所示。


Paint11
Paint

程式碼(TypefaceEX.java):

private static class FontView extends View

{

/* Paint.ANTI_ALIAS_FLAG為消除鋸齒 */

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

private Typeface typeFace;

public FontView(Context context)

{

super(context);

/* 自定義字體 */

typeFace = Typeface.createFromAsset(getContext().getAssets(), "fonts/verdanaz.ttf");

// typeFace = Typeface.createFromFile("/sdcard/verdanaz.ttf");

/* 設定字體大小 */

paint.setTextSize(32);

}

@Override

protected void onDraw(Canvas canvas)

{

canvas.drawColor(Color.WHITE);

/* 繪製預設字體 */

paint.setTypeface(null);

canvas.drawText("Default Font", 10, 100, paint);

/* 繪製自定義字體 */

paint.setTypeface(typeFace);

canvas.drawText("Custom Font", 10, 200, paint);

}

}



Viewflipper
ViewFlipper

ViewFlipper可以包含多個View) 且View之間的切換有動畫效果,例如說漸變效果。它也可以根據時間週期切換顯示項目,像是一個幻燈片播放的效果,範例如圖所示。


Viewflipper1
ViewFlipper

  • ViewAnimator的作用是為FrameLayout裡面的View切換提供動畫效果。

  • ViewAnimator類別有幾個和動畫相關的方法:

    • setInAnimation:設定View進入螢幕時候使用的動畫。

    • setOutAnimation: 設定View退出螢幕時候使用的動畫。

    • showNext:呼叫此方法顯示Layout裡面的下一個View。

    • showPrevious:呼叫此方法顯示Layout裡面的上一個View。


Viewflipper2
ViewFlipper

  • 一般不直接使用ViewAnimator而是使用它的兩個子類別ViewFlipper和ViewSwitcher。

  • ViewFlipper可以用來指定Layout內多個View之間的切換效果,可以一次指定也可以每次切換的時候都指定單獨的效果。此類別額外提供了如下幾個方法:

    • isFlipping:用來判斷View切換是否正在進行。

    • setFilpInterval:設定View之間切換的時間間隔。

    • startFlipping:使用上面設定的時間間隔來切換所有View,會以幻燈片方式進行。

    • stopFlipping: 停止View切換。


Viewflipper3
ViewFlipper

布局文件(res/layout/main.xml):

<?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"

>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="horizontal"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

>

<Button

android:id="@+id/btnPrevious"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Previous"

/>

<Button

android:id="@+id/btnNext"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Next"

/>

</LinearLayout>

<ViewFlipper

android:id="@+id/viewFlipper"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:gravity="center"

/>

</LinearLayout>


Viewflipper4
ViewFlipper

程式碼-1(ViewFlipperEX.java):

public class ViewFlipperEX extends Activity

{

public final static int VIEW_TEXT = 0;

public final static int VIEW_IMAGE = 1;

private Button btnPrevious;

private Button btnNext;

private ViewFlipper viewFlipper;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

initView();

/* 新增圖檔及文字於viewFlipper此View中 */

viewFlipper.addView( addTextByText("Android 1.6") );

viewFlipper.addView( addImageById(R.drawable.play) );

viewFlipper.addView( addTextByText("Android 2.0") );

viewFlipper.addView( addImageById(R.drawable.normal) );

viewFlipper.addView( addTextByText("HTC Hero") );

}


Viewflipper5
ViewFlipper

程式碼-2(ViewFlipperEX.java):

程式碼-3(ViewFlipperEX.java):

public View addTextByText(String text)

{

/* 設定TextView屬性並回傳 */

TextView textView = new TextView(this);

textView.setText(text);

textView.setGravity(1);

return textView;

}

public View addImageById(int id)

{

/* 設定ImageView屬性並回傳 */

ImageView imageView = new ImageView(this);

imageView.setImageResource(id);

return imageView;

}

完整程式碼請參考光碟中ViewFlipperEX.java

private OnClickListener listener = new OnClickListener()

{

public void onClick(View v)

{

/* 判斷點擊到哪個按鈕 */

switch(v.getId())

{

/* 點擊到上一張按鈕就呼叫showPrevious方法 */

case R.id.btnPrevious:

viewFlipper.showPrevious();

break;

/* 點擊到下一張按鈕就呼叫showNext方法 */

case R.id.btnNext:

viewFlipper.showNext();

break;

}

}

};


Viewswitcher
ViewSwitcher

ViewSwitcher簡單來說就是Switcher在兩個View之間切換,可以透過ViewSwitcher指定一個ViewSwitcher.ViewFactory 來建立兩個View。

此類別具有兩個子類別ImageSwitcher、TextSwitcher分別用於圖片和文字切換,範例如下頁圖所示。


Viewswitcher1
ViewSwitcher

程式範例圖:


Viewswitcher2
ViewSwitcher

一開始要在res資料夾底下新增兩個XML檔案,接著將一開始新增的兩個XML檔,作為兩個View,並使用ViewSwitcher的方法去做兩個View之間的切換。

當按下讀取更多的按鈕時,ViewSwitcher就會切換到另外一個View,當背景作業處理完成後,才會切換回原本的View。


Viewswitcher3
ViewSwitcher

布局文件(res/layout/button.xml):

<?xml version="1.0" encoding="utf-8"?>

<!--使用 ViewSwitcher 切換的第一個View-->

<Button xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/btn_loadmorecontacts"

android:text="Load More Items"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:textAppearance="?android:attr/textAppearanceLarge"

android:minHeight="?android:attr/listPreferredItemHeight"

android:textColor="#FFFFFF"

android:background="@android:drawable/list_selector_background"

android:clickable="true"

android:onClick="onClick"

/>


Viewswitcher4
ViewSwitcher

布局文件(res/layout/progress.xml):

<?xml version="1.0" encoding="utf-8"?>

<!--使用 ViewSwitcher 切換的第二個View-->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:gravity="center_horizontal"

android:minHeight="?android:attr/listPreferredItemHeight">

<ProgressBar

android:id="@+id/progressBar"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

/>

<TextView

android:text="Loading…"

android:textAppearance="?android:attr/textAppearanceLarge"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:layout_toRightOf="@+id/progressBar"

android:layout_centerVertical="true"

android:gravity="center"

android:padding="10dip"

android:textColor="#FFFFFF"

/>

</RelativeLayout>


Viewswitcher5
ViewSwitcher

程式碼-1(ViewSwitcherEX.java):

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

switcher = new ViewSwitcher(this);

button = (Button)View.inflate(this, R.layout.button, null);

progress = View.inflate(this, R.layout.progress, null);

/* 將button與progressbar加入switcher中 */

switcher.addView(button);

switcher.addView(progress);

/* 取得ListView並將switcher加入 */

getListView().addFooterView(switcher);

/* 設定ListAdapter,其中第二個參數可選擇樣式 */

setListAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, ITEMS));

}


Viewswitcher6
ViewSwitcher

程式碼-2(ViewSwitcherEX.java):

完整程式碼請參考光碟中ViewSwitcherEX.java

private class getMoreItems extends AsyncTask

{

@Override

protected Object doInBackground(Object... params)

{

/* 此處可撰寫新增項目之程式碼 */

try

{

/* 執行緒會呼叫sleep方法 */

Thread.sleep(3000);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

return null;

}

@Override

protected void onPostExecute(Object result)

{

switcher.showPrevious();

}

}



前言

在Android中支援高效能的3D圖形,主要是透過OpenGL/ES API。

所謂的ES API就是OpenGL所規範給嵌入式設備使用的。


Glsurfaceview
GLSurfaceView

GLSurfaceView是一個新API,開始使用是從Android1.5版。

GLSurfaceView可以使得創造一個OpenGL ES應用程式更為容易,通常用於遊戲或快速更新畫面的應用程式上。


Glsurfaceview1
GLSurfaceView

  • GLSurfaceView具有下列優點:

    • 提供了glue code來連接OpenGL ES的視圖系統。

    • 提供了glue code使得OpenGL ES與活動生命週期一起工作。

    • 可以更簡單的選擇適合的Frame buffer像素格式。

    • 建立與管理一個獨立的繪圖執行緒,使得動畫效果更為流暢。

    • 提供簡易的除錯工具。


Glsurfaceview2
GLSurfaceView

下面將以一個簡易的範例使讀者更了解GLSurfaceView的使用方式,範例執行結果如圖所示。


Glsurfaceview3
GLSurfaceView

程式碼-1(GLSurfaceViewEX.java):

程式碼-2(GLSurfaceViewEX.java):

class ClearRenderer implements GLSurfaceView.Renderer

{

private float mRed;

private float mGreen;

private float mBlue;

public void onSurfaceCreated(GL10 gl, EGLConfig config)

{

}

public void onSurfaceChanged(GL10 gl, int w, int h)

{

/* 決定視窗上的繪圖區域 */

gl.glViewport(0, 0, w, h);

}

public void onDrawFrame(GL10 gl)

{

/* 清除顏色buffer */

gl.glClearColor(mRed, mGreen, mBlue, 1.0f);

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

}

public void setColor(float r, float g, float b)

{

mRed = r;

mGreen = g;

mBlue = b;

}

}

class ClearGLSurfaceView extends GLSurfaceView

{

private ClearRenderer mRenderer;

public ClearGLSurfaceView(Context context)

{

super(context);

mRenderer = new ClearRenderer();

setRenderer(mRenderer);

}

public boolean onTouchEvent(final MotionEvent event)

{

/* 啟動執行緒,並傳入座標設定顏色 */

queueEvent(new Runnable()

{

public void run()

{

mRenderer.setColor(event.getX() / getWidth(),

event.getY() / getHeight(), 1.0f);

}});

return true;

}

}

}


Surfaceview
SurfaceView

依照傳統的作法,要快速更新畫面或做遊戲之類的應用,通常會新增執行緒處理工作後,使用handler傳送訊息給View顯示畫面或是在非使用者執行緒呼叫View。


Surfaceview1
SurfaceView

SurfaceView通常用於遊戲中或是需快速更新畫面之應用程式,藉此來加快程式畫面運行速度。SurfaceView也是View的一種,但有獨立buffer,稱為surface。

由於此buffer不需透過 Android framework做畫面更新,可直接對應到畫面上的區塊,提供更好的效能。


Surfaceview2
SurfaceView

但實際上還是間接更新到畫面上,但少了 Android framework 這一層,而且可透過硬體加速(加速的功能視平台而定),範例程式如圖所示。


Surfaceview3
SurfaceView

程式碼-1(SurfaceViewEX.java):

程式碼-2(SurfaceViewEX.java):

SurfaceHolder holder;

public AnimView(Context context)

{

super(context);

/* 取得Holder */

holder = this.getHolder(); //holder

/* 新增Callback */

holder.addCallback(this);

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)

{

/* 啟動執行緒繪圖 */

new Thread(new AnimThread(holder)).start();

}

完整程式碼請參考光碟中SurfaceViewEX.java

public void run()

{

while( running )

{

try

{

/* 鎖定畫布 */

canvas = holder.lockCanvas(null);

/* 移動畫布 */

canvas.translate(dx, dy);

paint = new Paint();

paint.setColor(Color.RED);

/* 繪製畫布 */

canvas.drawColor(Color.BLACK);

/* 於畫布繪製圖形 */

canvas.drawRect(new RectF( pLeft,pTop,pRight,pBottom ), paint);

dx++;

}

catch(Exception ex) {}

finally

{

/* 解鎖畫布 */

holder.unlockCanvasAndPost(canvas);

}

/* 移動邊界限制 */

if(width - 100 <= dx)

running = false;

}

}


Surfaceview4
SurfaceView

在這個範例當中,需覆寫surfaceChanged方法,在此方法中啟動執行緒,使用translate方法,並設定條件,達成方塊移動的動畫效果。

藉此範例可以了解到有關SurfaceView中的標準用法,流程將於後面敘述說明。


Surfaceview5
SurfaceView流程

當程式需要更好的效能時,繼承SurfaceView也是一種方式。透過 SurfaceView,canvas不需透過onDraw()取得。

可以透過呼叫SurfaceView.getHolder()取得surface holder,而SurfaceHolder.lockCanvas()會傳回SkCanvas。

Native code 可以在這個 SkCanvas上作畫,然後呼叫 SurfaceHolder.unlockCanvasAndPost(),將內容更新到畫面上。


Surfaceview6
SurfaceView注意事項

每次更新畫面前,都要透過 SurfaceHolder.lockCanvas() 取得一個新的SkCanvas,在這個canvas上繪圖。

繪圖完成後都需呼叫SurfaceHolder.unlockCanvasAndPost() 進行更新,才能正確的更新畫面。


Matrix
Matrix

Android的2D繪圖功能其實是非常強大的,尤其是matrix。透過matrix,可以非常容易的控制Android繪圖座標的位移、旋轉、縮放…等等功能。範例程式執行結果如下頁圖所示。


Matrix1
Matrix

點選縮小按鈕可將旁邊圖示縮小;選放大按鈕則可將圖示放大,其它還有像setRotate、setSinCos、setScale、setTranslate…等等方法可以應用。


Matrix2
Matrix

布局文件(res/layout/main.xml):

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

android:id="@+id/layout"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

xmlns:android="http://schemas.android.com/apk/res/android">

<Button

android:id="@+id/btnSmall"

android:layout_width="90px"

android:layout_height="60px"

android:text="縮小"

android:textSize="18sp"

/>

<Button

android:id="@+id/btnBig"

android:layout_width="90px"

android:layout_height="60px"

android:text="放大"

android:textSize="18sp"

/>

<ImageView

android:id="@+id/imageView"

android:src="@drawable/icon"

android:layout_width="90px"

android:layout_height="60px"

/>

</LinearLayout>


Matrix3
Matrix

程式碼(MatrixEX.java):

完整程式碼請參考光碟中MatrixEX.java

/* 取得bitmap寬高 */

int bmpWidth = bitmap.getWidth();

int bmpHeight = bitmap.getHeight();

/* 設定縮小比例 */

double scale = 0.7;

scaleWidth = (float)(scaleWidth * scale);

scaleHeight = (float)(scaleHeight * scale);

Matrix matrix = new Matrix();

/* 縮放圖片 */

matrix.postScale(scaleWidth, scaleHeight);

/* 重新縮放Bitmap */

Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, true);

if(id == 0)

{

/* 移除View */

linearLayout.removeView(imageView);

}

else

{

linearLayout.removeView((ImageView)findViewById(id));

}

id++;

ImageView imageView = new ImageView(MatrixEX.this);

imageView.setId(id);

imageView.setImageBitmap(resizeBmp);

linearLayout.addView(imageView);

setContentView(linearLayout);


ad