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
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; // w w w . jav a 2 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); } } }