I managed to create the class that allows me to have a preview of the room (which is supported by a SurfaceView), and thus far everything is ok, the code work.
Now I was wondering if it was possible to create buttons (or more generally any other object) on this Surface.
I tried to load the layout with setContentView (my_layout) but doing so is not loaded (or at least, not shown) the SurfaceView object. So as I seemed to understand, you can only load one of the two, or maybe I missing something?
Sorry for that bad English, but this text was generated by Google Translate.
What you need to do is to create a framelayout and add buttons.
Or construct your view with addContentView
LayoutInflater inflater = getLayoutInflater();
getWindow().addContentView(inflater.inflate(R.layout.main, null), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
You can create a layout with transparent background and put it above your surface view.
Good thing is to create a FrameLayout with 2 elements in it. 1st being your SurfaceView with match_parent for both width and height so it occupies the whole parent FrameLayout.
2nd would be your layout with transparent background which can occupy, for example, part of the parent FrameLayout.
So then your SurfaceView gets created first and above it there will be your transparent layout with buttons.
That could work for kind of control panel or something but if you want kind of augmented reality you can have a look at the OpenCV SDK for Android where they do change the camera preview picture applying filters to it etc.
Related
I am a new developer working on Samsung Galaxy tab (model SM-T210R, Android version 4.4.2.
I'd like to develop an app with two media players alternatively playing but only one shown on the screen.
Currently, I am able to alternatively play two video files (one pause and the other play and then switch) by mainly following the good example from user MH (thanks) in
How to play multiple video files simultaneously in one layout side by side in different view in Android. I am using a linear layout.
However, two surfaceviews are being shown on the screen all the time, including the one from the media player being paused.
Could anyone instruct how to show on the screen only the one from the active media player? Thanks a lot.
I have tried the following but they did not work (maybe I missed something?):
(a) Overlap one surface view on the top of the other and set the top one transparent - However, once the media player associated with the top surface view is being played, the top surface view is not transparent anymore. Is there a way to set it to transparent in that scenario? Also, can I dynamically turn on and off the transparency setting?
(b) Use ViewSwitch class - Unfortunately, I cannot change from one surface view to another.
(c) I also tried the one in How to display two videos simultaneously with surface view. In this case, I see two video views but I wanted to have one.
(d) I also tried this one android how to resize video width and height in surface view for media player. It cannot solve my two surface view into one display problem.
Thanks
Create a layout with two FrameLayouts, if the videos are to appear side by side than put them in a linear layout as you have it. If only one or the other are supposed to show, then put them in the same parent FrameLayout
This an example of one or the other:
<FrameLayout>
<FrameLayout id="video1"/>
<FrameLayout id="video2"/>
</FrameLayout>
In the java code, add each of the SurfaceViews as a child to the FrameLayout
When video1 is paused, set its visibility to hidden and the other to visible, when that is paused, switch the visibility again.
Update
Use only the FrameLayout in the xml files. Create an instance of a SurfaceView in the Java code and apply LayoutParams if needed, then attach them to the FrameLayouts
FrameLayout l1 = (FrameLayout) findViewById(R.id.video1);
FrameLayout l2 = (FrameLayout) findViewById(R.id.video2);
l2.setVisibility(View.INVISIBLE); // You can use GONE as well
SurfaceView sv1 = new SurfaceView(...);
SurfaceView sv2 = new SurfaceView(...);
l1.addView(sv1);
l2.addView(sv2);
Now you can alternate between VISIBLE and INVISIBLE based on the play state of the video.
Thanks, Gary. Your notes gave me some idea. I think the two-layout plus visibility setting is the right way to go but there must be a bug in Android as the invisible setting not functioning for SurfaceView (I have tried many. I will check this later).
Anyway, I follow the two-layout set up idea and use media player setDisplay() to change the view. It is working. Basically I did this,
// Create a third dummy view
SurfaceView svDummy = new SurfaceView(...);
// Add to layout 2
l2.addView(svDummy);
// get holders
mHolder1 = sv1.getHolder();
mHolder2 = sv2.getHolder();
mHolderDummy = svDummy.getHolder();
MediaPlayer mMediaPlayerA;
MediaPlayer mMediaPlayerB;
Note that layout 1 is on top (according to the sequence in FrameLayout definition in the xml file) and is used as the active view all the time.
I first set mMediaPlayerA on sv1 and pause mMediaPlayerB.
Then, I alternatively set this.
mMediaPlayerA.pause();
mMediaPlayerA.setDisplay(svDummyHolder); // This is needed. Otherwise, does not work
mMediaPlayerB.setDisplay(sv1Holder); // sv1Holder is the active one all the time
mMediaPlayerA.setDisplay(sv2Holder);
mMediaPlayerB.start();
...
mMediaPlayerB.pause();
mMediaPlayerB.setDisplay(svDummyHolder); // This is needed. Otherwise, does not work
mMediaPlayerA.setDisplay(sv1Holder); // sv1Holder is the active one all the time
mMediaPlayerB.setDisplay(sv2Holder);
mMediaPlayerA.start();
The dummay view is needed. Otherwise, it did not work.
The summary is: to make this work, each media player needs a physical SurfaceView (not shared by others) and each SurfaceView needs to be mapped to a physical layout.
Again, thanks.
I'm following the examples in a recent book (Learn OpenGL ES For Mobile Game and Graphics Development) and the suggestion made there is to programmatically add a new layout (let's call it settingsLayout) in the main activity and then:
LayoutInflater settingsInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View settingsLayoutView = settingsInflater.inflate(R.layout.mySettingsLayout,settingsLayout,false);
settingsLayout.addView(settingsLayoutView);
addContentView(settingsLayout,settingsLayoutParams);
This works fine, but I've added it to the callback for one of my action bar menu items, and I'd like to be able to remove this view when the back button is used. So far, that is causing me a lot of headache.
Meanwhile, it seems that the most natural way to implement dynamic views (addable to backstack, etc) is through Fragments. However, fragments need to belong to a layout, and currently my code assigns the GLSurfaceView directly as the content view for my main activity, without using a layout at all. Since GLSurfaceView is a subclass of View (and not View Group), I cannot use it to spawn children such as fragments.
The author of the book claims that this approach is "sleek", but doesn't give any other reason for assigning the GLSurfaceView directly as the content view. Is there a performance issue to be aware of? Or is it just as "sleek" to make a "master" layout to which both my GLSurfaceView and subsequently spawned views belong?
Is there some other even more natural way to get buttons, text boxes, etc. to dynamically appear and disappear on top of my GLSurfaceView?
I'm not sure what your specific performance concern is -- rendering the View objects, or rendering GL? Nothing you do is going to affect the performance of the GL rendering (except perhaps changing the size of the window).
SurfaceView and GLSurfaceView provide a transparent "place holder" in the View hierarchy that other elements use when computing the layout, but the actual pixels are drawn on a separate layer. This is why the SurfaceView is either behind all View elements or in front of them all -- the layer is passed to the system compositor (SurfaceFlinger), which takes care of generating the final display image.
I'm drawing some graphics and i would like to add scroll to it. But with the surface view how to add the scroll programatically ?
SurfaceView is a very special component, it's not easy to mix it with other components. The main reason is due to how it works: when you use a SurfaceView, a new window will be created (by default behind the activity) and all the rendering in the SurfaceView will go to that window. SurfaceView will also "draw a hole" in the activity, so the window behind it will be visible.
SurfaceView needs to synchronize the window position with it's position, which is not done perfectly. For example if you put a SurfaceView inside something which can scroll, the window won't scroll (at least it didn't the last time I tried, around Froyo time).
Please provide some more information about what you are trying to do. If you just want to create a custom component, it's easier to just subclass View and override onDraw(Canvas).
I´m having a problem with my Android Project.
I have a screen filling custom View, which displays a canvas. The canvas consists of a background picture and another picture layer, in which can be finger drawn. Additionally, the canvas view can be dragged and pinch-zoomed.
Now I implemented a detection for 'longClicks', i.e. finger down on same region for 1 second. As a result of this gesture, a small menu should pop up over the pointed region. The menu itself should consist of something like a TabHost/TabWidget, i.e. smaller icons on riders on top which reveal separate EditText, Buttons etc. at the lower part of the menu.
Now the question is: How can it technically be done?
1) I played around with TabHost etc., but I think it´s only possible to use when having a TabActivity. Is this correct?
2) Then I searched for a possibility to overlay my main activity with this TabActivity, resulting in that it´s possible, but I couldn´t really control where the overlay Activity was placed, it always started on top left. Is there a possibility to place an Activity somewhere on the screen?
3) Next I discarded my idea with the tabbed menu and searched for a possibility to only overlay my view with another view (and have the possibility to remove it later again). I read, that it´s possible with the ViewManager. But how do I access the ViewManager? Documentation says: http://developer.android.com/reference/android/view/ViewManager.html
call Context.getSystemService().
but via this function, I can only get the WindowManager and not the ViewManager. wtf?
I´m really stuck right now...can somebody give me a hand here?
edit:
I managed the view over view problem by programmatically instanciating a Layout and then handing it in as contentView.
rl = new RelativeLayout(getBaseContext());
rl.addView(cview);
cview.setId(1111);
View overlay = getLayoutInflater().inflate(R.layout.menuoverlay, rl, false);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_LEFT, cview.getId());
lp.addRule(RelativeLayout.CENTER_VERTICAL, cview.getId());
rl.addView(overlay, lp);
Now when making the Layout static and by writing some getter/setter methods, I'm now able to control adding and removing of views.
private static rl;
//scroll scroll
public static void addView(View view){
rl.addView(view);
}
1) I played around with TabHost etc., but I think it´s only possible to use when having a TabActivity. Is this correct?
No. For an example of using TabHost without a TabActivity, take a look at Is it realizable on Android?
I finally used PopupWindow now.
http://developer.android.com/reference/android/widget/PopupWindow.html
i have the following problem.
I am working with a library of maps which paints the icons on the map using drawables and canvas.
Now, i'm trying to modify it in order to the user can click on icons. So i want to attach drawables into different ImageView with a onClickListener.
However, i don't know how i can paint the ImageView using canvas from method onDraw.
I've tried with:
ImageView iv = new ImageView(context);
iv.setDrawableResource(drawable);
iv.draw(c)
But it doesn't appears in screen.
Any idea? Thanks
You might have better luck if you provided more context -- what's "c" represent here? But in any case, you can't just create new imageviews, you need to attach them to your layout, either by inflating them with a parent view argument from XML, or calling your parent layout's addView() programatically.
Generally, you'll rarely call any draw() methods by hand (unless you're implementing a custom view of some sort); you'll inflate your views from XML into your layout, or else instantiate your views, set whatever LayoutParams you need, and add them to a layout. The Android UI libraries handle figuring out when standard views are invalidated and need to be redrawn, for performance reasons and your own sanity.