What I wanted to achieve is this:
I wanted to have a specific portion of the screen to be my SurfaceView. I will use this SurfaceView for some animations. But I wanted to include some Views like TextView and RadioButtonGroup beside my SurfaceView.
So my question is, is this possible? I looking for sample android source code about 'animating sprites', but I couldn't find any activity that incorporates both TextViews and SurfaceView. All are extending SurfaceView. If this is possible, how do I do it? Do you have sample source codes that I can try?
try this i am not extending surfaceview.
public class Preview_can_work extends Activity {
private SurfaceView surface_view;
SurfaceHolder.Callback sh_ob = null;
SurfaceHolder surface_holder = null;
SurfaceHolder.Callback sh_callback = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
surface_view = new SurfaceView(getApplicationContext());
addContentView(surface_view, new LayoutParams(50, 50));
if (surface_holder == null) {
surface_holder = surface_view.getHolder();
}
sh_callback = my_callback(); // CREATING CALLBACK FOR YOUR SURFACE.
surface_holder.addCallback(sh_callback);
}
// THIS FUNCTION RETURNS CALLBACK OBJECT FOR SURFACEVIEW.
SurfaceHolder.Callback my_callback() {
SurfaceHolder.Callback ob1 = new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
};
return ob1;
}
}
now you can simply add any textview or button on your layout it should work.
Note:- I am creating surface dynamically. In your case what you can do is you can create everything in xml file. Instead of creating surfaceview create video view.
SurfaceView surface_view = (SurfaceView) findViewById(R.id.video_view_id);
if you are fetch view by id from your layout then you have to remove some line from code. which are:
surface_view = new SurfaceView(getApplicationContext());
addContentView(surface_view, new LayoutParams(50, 50));
Hope it will help you...
It is definitely possible but you might need to present a little more information. If you want some simple animation to run next to the textview then you don't even need a surfaceview. Just create an imageview and run an animation on it (here is a tutorial I created for the very topic)
TextView and its kin DO NOT derive from Surfaceview they derive from the View class. Once again if you want to perform simple animations I don't think you will need a surfaceview. If you want to do more dynamic complex things then there is also a tutorial on my development blog on how to utilize a SurfaceView for a game. If that is more your flavor then you can create a custom surface view and then just tie it into your layout with the size dimensions you want.
Related
I'm creating a camera app and need to detect Touch on surfaceView which is camera preview. I want to set focus of camera where user touch. But Right i just only need to detect touch place.
Here is my preview class code.
public class Preview extends SurfaceView implements SurfaceHolder.Callback {
public Preview(Context ctx, SurfaceView surfaceView) {
super(ctx);
init(surfaceView);
}
private void init(SurfaceView surfaceView){
mSurfaceView = surfaceView;
final SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
surfaceHolder.addCallback(this);
}
public void setCamera(){
mCamera = Camera.open()
mCamera.setPreviewDisplay(mSurfaceView.getHolder());
mCamera.startPreview();
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i(TAG, "onInterceptTouchEvent");
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.i(TAG, "onTouchEvent");
return super.onTouchEvent(event);
}
// Other code.... like override methods etc
MainActivity
// inside onCreate() method
preview = new Preview(this, surfaceView);
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
mainLayout.addView(preview);
preview.setCamera();
// Other codes .....
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout">
<SurfaceView
android:id="#+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
I added onTouchEvent and onInterceptTouchEvent But both are not working. Whenever I touched on sufaceView nothing show in Log I think I'm missing some thing, can you please let me know ?
preview = new Preview(this, surfaceView);
preview.setCamera();
There is just two line code in MainActivity initilizing the Preview and setCamera() nothing else.
Why you do not see onTouchEvent and onInterceptTouchEvent logs?
I assume, that you haven't added that layout to your view hierarchy.
rootView.addView(preview);
After adding it you should see touch event logs.
But that's not what you actually expect to do, because you have just incorrectly "wrapped" your SurfaceView inside a Java class, which yet doesn't mean that touch events on your SurfaceView would be reflected in your logs.
What you really want is to extend SurfaceView and override those touch events there. Now you would receive correct touch events. Then make sure you are inflating your custom SurfaceView into view hierarchy.
Or, second approach, you can add SurfaceView as a child of your ViewGroup:
yourCustomViewGroup.addView(surfaceView);
There are a few issues with your extended class, in that it does not include all required override methods. However I will assume this is still being developed.
In theory this should work:
preview.setOnClickListener( new OnClickListener(){
#Override
public void onClick() {
//do stuff
}
});
I have not tested it, but as this is extending ViewGroup, this should work.
Note: You probably will need to add this
android:clickable="true"
To your 'Preview' layout, to allow the click to be processed.
Hope that helps.
I'm trying to use the SurfaceView widget. I have a class
public class OurView extends SurfaceView implements Runnable {
public OurView(Context context) {
super(context);
Log.d("OurView", "Yay We started");
}
#Override
public void run() {
}
}
So I have a SurfaceView widget in my Activity's XML. I then try to bind it in the onCreate method
TheView = (OurView) findViewById(R.id.theSurfaceView);
The problem is here I get an error that I can't cast OurView to android.view.SurfaceView.
I know usually I could just do this to the view itself, in the onCreateMethod
TheView = new OurView(this);
setContentView(TheView);
The thing is I don't want to do this, I don't want to draw on my whole activity I just want to draw on the SurfaceView widget that i've put on the layout. How would I do that?
You should put your customized SurfaceView com.xx.OurView in your layout, not SurfaceView.
I've been looking for something about adding images to videos, but i haven't found what I wanted.
I'd like to add a bitmap/image mask in each frame of a video (it can be recorded or from SD), keeping the original sound, and save the video to the SD with the image.
Someone knows how it can be done in Android?
Thnx
create a class that extends SurfaceView
public class PaintSurface extends SurfaceView {
....
In draw() function add code
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawBitmap(bitmap.img, bitmapPosX, bitmapPosY, null);
}
}
In onCreate function create an object of it.
videoView = new PaintSurface(this);
add it to your layout
RelativeLayout layut = (RelativeLayout) findViewById(R.id.lay);
layut.addView(videoView);
get a holder
videoHolder = videoView.getHolder();
set this holder's surface to the MediaRecorder object
recorder.setPreviewDisplay(videoHolder.getSurface());
I am new to Android, so please excuse if it is asked before!
I am playing with some camera code (found online) and I want to show/hide some buttons on screen. When the user touches the screen, I want it to capture the image.
My setup:
1.
Main Activity:
public class CameraDemo extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_inuse);
preview = new Preview(this);
((FrameLayout) findViewById(R.id.preview)).addView(preview);
... ...
// rest of the code that captures the image when a button is pressed.
// the button is defined in main.xml with button id ButtonClicked
}
2.
The preview class looks like this:
class Preview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
public Camera camera;
Preview(Context context) {
super(context);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
My question is,
How can I add touch functionality so that the user can touch the preview (say for a second, or just touch quickly) and something happens ? (Say image is saved)
And a button will appear on the surface say a "Next" button, for example?
#Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
in your preview class , the MotionEvent object will tell you what kind of touch it is (and position etc etc) and let you do whatever you want to do.
I have subclassed the SurfaceView and instantiating it in onCreate of the Activity. The preview is generated but the control never enters onDraw() which is overriden in the subclass of SurfaceView. Why is that?
class ActivityClass extends Activity{
onCreate(){
mPreview = new Preview(this);
setContentView(mPreview);
}
public void startPreview(){
rec = new MediaRecorder();
rec.setVideoSource();.......
rec.setPreviewDisplay(mPreview.getSurfaceHolder.getSurface());
}
}
class Preview extends SurfaceView implements SurfaceHolder.Callback{
SurfaceHolder mHolder;
public Preview(Context context){
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
bringToFront();//this is not
invalidate();//making a difference
}
SurfaceHolder getSurfaceHolder(){
return mHolder;
}
//Surface callback methods implemented here
}
Before drawing the preview on the Surface, shouldn't the control be given to the onDraw callback if it is implemented?
Because onDraw callback says to the Android framework 'you don't draw the view. I will draw it since I have been implemented'. Am I right?
Why then, is the control failing to enter onDraw()? Please help.
You simply have to add
setWillNotDraw(false)
To the constructor.
And its done..:)
public class SelectedRect extends View {
public SelectedRect(Context context) {
super(context);
bringToFront();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawLine(canvas);
invalidate();
this.bringToFront();
}
}
And in activity class :
View rect = new SelectedRect(this);
rect.bringToFront();
this.addView(rect, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
Something fishy is going on. It seems that you're trying to set the SurfaceView as a preview display. In that case, the Activity should implement SurfaceHolder.Callback (not the SurfaceView). This is so that the Activity can know when the SurfaceView has been created and is ready for drawing. Furthermore, it shouldn't even be necessary to extend SurfaceView: you should be able to user SurfaceView itself.
Assuming I misunderstood and you really want to extend surfaceview for some reason...
I don't see where you overrode onDraw in your Preview class. Did you not include this code?
When you say that the onDraw callback tells android 'you don't draw the view. I will draw it since I have been implemented', I disagree. onDraw is a function where a View draws stuff that all views have, such as the background. SurfaceView extends view. When you extend SurfaceView, you can override onDraw to tell android to draw stuff in addition to what the original onDraw in the View draws. In other words, Android always does all the drawing; overriding onDraw just tells it to draw a few more things when it's the right time to draw.