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).
Related
I have a card-like view with elevation and a white background that I want to expand to fill up the whole screen. It's a card in a list (my own custom layout, not a CardView), and I want to make it take up the whole screen when it's tapped via a Fragment transition.
My first idea is to create a fake, identical view in the new fragment, place it at the item's position, and animate it to the top, while animating its layout bounds to take up the whole screen. However, I don't think this is the best idea, as Android will have to remeasure the layout every single frame while the animation is running (likely to lag). Is there a way I can get this effect in a clean way? I'm going to be using fragment transitions, so hopefully I can use Animator in some way, but I'll take any solution.
You can try to do the same, but instead of relayouting, do redrawing. Create custom implementation of view's onDraw(), it's not that hard.
View will fill entire screen but at the start of animation will draw only initial part.
Or you can just try your approach, it's easy to implement and may be it is not that slow.
Also, may be directly modifying view's setLeft(), setRight(), etc. with Animators is a valid solution.
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 was having some issues having a view on top of my surface view. I followed the instructions on this answer: https://stackoverflow.com/a/2934759/1315692
That worked great EXCEPT for a view that is custom drawn.
The custom drawn view ALWAYS remains on top. What do I need to do to be able to put a view on top of it? Thanks for any suggestions or insights.
I figured out a solution. It may not be the best solution but it is working for me.
I drew my view that I wanted on top in the draw routine of the object that was stubbornly staying on top USING THE SAME CANVAS. I added a field of type View to my SurfaceView (because that is where the view that remained on top is drawn) with a setter. Then in my draw routine I simply called passedInView.draw(canvas);
If you are at a point where you are not drawing on top of the surface view at all then start with the link from my question. That should be all you need. This is for a situation where a custom drawn view still remains.
Now this can cause some undesired behavior in regards to tapping (you can tap right through your on top view)...so you will need code to handle that but if all else fails, as it had for me, this got my view on top.
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.
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