Draw texture with thread
Description
The following code shows how to Draw texture with thread.
Code revised from
Android Recipes:A Problem-Solution Approach
http://www.apress.com/9781430234135
ISBN13: 978-1-4302-3413-5
Example
Main layout xml file
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_transform"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Rotate" />
<TextureView
android:id="@+id/surface"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_gravity="center" />
</FrameLayout>
Main Activity Java code
package com.java2s.myapplication3.app;
/* ww w . ja v a2 s . c o m*/
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
public class MainActivity extends Activity implements View.OnClickListener, View.OnTouchListener, TextureView.SurfaceTextureListener {
private TextureView mSurface;
private DrawingThread mThread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button_transform).setOnClickListener(this);
mSurface = (TextureView) findViewById(R.id.surface);
mSurface.setOnTouchListener(this);
mSurface.setSurfaceTextureListener(this);
}
@Override
public void onClick(View v) {
mSurface.animate()
.rotationBy(180.0f)
.setDuration(750);
}
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mThread.addItem((int) event.getX(), (int) event.getY());
}
return true;
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
int height) {
mThread = new DrawingThread(new Surface(surface),
BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
mThread.updateSize(width, height);
mThread.start();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
int height) {
mThread.updateSize(width, height);
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mThread.quit();
mThread = null;
return true;
}
private static class DrawingThread extends HandlerThread implements Handler.Callback {
private static final int MSG_ADD = 100;
private static final int MSG_MOVE = 101;
private static final int MSG_CLEAR = 102;
private int mDrawingWidth, mDrawingHeight;
private Surface mDrawingSurface;
private Rect mSurfaceRect;
private Paint mPaint;
private Handler mReceiver;
private Bitmap mIcon;
private ArrayList<DrawingItem> mLocations;
private class DrawingItem {
int x, y;
boolean horizontal, vertical;
public DrawingItem(int x, int y, boolean horizontal, boolean vertical) {
this.x = x;
this.y = y;
this.horizontal = horizontal;
this.vertical = vertical;
}
}
public DrawingThread(Surface surface, Bitmap icon) {
super("DrawingThread");
mDrawingSurface = surface;
mSurfaceRect = new Rect();
mLocations = new ArrayList<DrawingItem>();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mIcon = icon;
}
@Override
protected void onLooperPrepared() {
mReceiver = new Handler(getLooper(), this);
mReceiver.sendEmptyMessage(MSG_MOVE);
}
@Override
public boolean quit() {
mReceiver.removeCallbacksAndMessages(null);
return super.quit();
}
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_ADD:
DrawingItem newItem = new DrawingItem(msg.arg1, msg.arg2,
Math.round(Math.random()) == 0,
Math.round(Math.random()) == 0);
mLocations.add(newItem);
break;
case MSG_CLEAR:
mLocations.clear();
break;
case MSG_MOVE:
try {
Canvas c = mDrawingSurface.lockCanvas(mSurfaceRect);
if (c == null) {
break;
}
c.drawColor(Color.BLACK);
for (DrawingItem item : mLocations) {
item.x += (item.horizontal ? 1 : -1);
c.drawBitmap(mIcon, item.x, item.y, mPaint);
}
mDrawingSurface.unlockCanvasAndPost(c);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
mReceiver.sendEmptyMessage(MSG_MOVE);
return true;
}
public void updateSize(int width, int height) {
mDrawingWidth = width;
mDrawingHeight = height;
mSurfaceRect.set(0, 0, mDrawingWidth, mDrawingHeight);
}
public void addItem(int x, int y) {
Message msg = Message.obtain(mReceiver, MSG_ADD, x, y);
mReceiver.sendMessage(msg);
}
public void clearItems() {
mReceiver.sendEmptyMessage(MSG_CLEAR);
}
}
}