Last active
December 13, 2023 09:42
-
-
Save slightfoot/bcf352dcd243a84d3219 to your computer and use it in GitHub Desktop.
Playing around with SurfaceView/TextureView. See edit history.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.graphics.SurfaceTexture; | |
import android.os.Build; | |
import android.text.TextPaint; | |
import android.util.AttributeSet; | |
import android.util.Log; | |
import android.view.Surface; | |
import android.view.TextureView; | |
/** | |
* Moving Background | |
*/ | |
public class MovingBgTextureView extends TextureView implements TextureView.SurfaceTextureListener, Runnable | |
{ | |
private static final String TAG = MovingBgTextureView.class.getSimpleName(); | |
private final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); | |
private Thread mThread; | |
private volatile boolean mRunning = false; | |
private Surface mSurface; | |
private Bitmap mBackground; | |
public MovingBgTextureView(Context context) | |
{ | |
this(context, null, 0); | |
} | |
public MovingBgTextureView(Context context, AttributeSet attrs) | |
{ | |
this(context, attrs, 0); | |
} | |
public MovingBgTextureView(Context context, AttributeSet attrs, int defStyleAttr) | |
{ | |
super(context, attrs, defStyleAttr); | |
mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density); | |
mTextPaint.setColor(Color.WHITE); | |
mTextPaint.setLinearText(true); | |
mBackground = BitmapFactory.decodeResource(getResources(), R.drawable.test_image); | |
mThread = new Thread(this, TAG); | |
setSurfaceTextureListener(this); | |
} | |
@Override | |
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) | |
{ | |
Log.w(TAG, "onSurfaceTextureAvailable " + width + 'x' + height); | |
mSurface = new Surface(surface); | |
mRunning = true; | |
mThread.start(); | |
} | |
@Override | |
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) | |
{ | |
Log.w(TAG, "onSurfaceTextureSizeChanged " + width + 'x' + height); | |
} | |
@Override | |
public void onSurfaceTextureUpdated(SurfaceTexture surface) | |
{ | |
} | |
@Override | |
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) | |
{ | |
Log.w(TAG, "onSurfaceTextureDestroyed"); | |
mRunning = false; | |
try{ | |
mThread.join(); | |
} | |
catch(InterruptedException e){ | |
Log.e(TAG, "onSurfaceTextureDestroyed", e); | |
} | |
mSurface.release(); | |
mSurface = null; | |
return true; | |
} | |
private int mBGFarMoveX = 0; | |
private int mBGNearMoveX = 0; | |
@Override | |
public void run() | |
{ | |
Log.w(TAG, "thread running"); | |
long last = System.currentTimeMillis(); | |
int counter = 0; | |
String log = null; | |
while(mRunning){ | |
// decrement the far background | |
mBGFarMoveX = mBGFarMoveX - 1; | |
// decrement the near background | |
mBGNearMoveX = mBGNearMoveX - 4; | |
// calculate the wrap factor for matching image draw | |
int newFarX = mBackground.getWidth() - (-mBGFarMoveX); | |
Canvas canvas; | |
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ | |
canvas = mSurface.lockHardwareCanvas(); | |
}else{ | |
canvas = mSurface.lockCanvas(null); | |
} | |
if(canvas == null){ | |
mRunning = false; | |
break; | |
} | |
// if we have scrolled all the way, reset to start | |
if(newFarX <= 0){ | |
mBGFarMoveX = 0; | |
// only need one draw | |
canvas.drawBitmap(mBackground, mBGFarMoveX, 0, null); | |
} | |
else{ | |
// need to draw original and wrap | |
canvas.drawBitmap(mBackground, mBGFarMoveX, 0, null); | |
canvas.drawBitmap(mBackground, newFarX, 0, null); | |
} | |
if(log != null){ | |
canvas.drawText(log, 0, mTextPaint.getTextSize(), mTextPaint); | |
} | |
mSurface.unlockCanvasAndPost(canvas); | |
counter++; | |
long now = System.currentTimeMillis(); | |
if((now - last) >= 1000){ | |
log = Integer.toString(counter); | |
counter = 0; | |
last = now; | |
} | |
} | |
Log.w(TAG, "thread stopped"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
can you please provide the use of this class, I have streaming data coming very frequently with milliseconds and I need to display on the texture view. Will this class would be helpful?