I've created a simple Android app with two tabs (for now). The first tab contains a SurfaceView that has a its SurfaceHolder contain a Camera instance:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/camera_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="#+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
However, I'm not sure if I should release the camera when the second tab is displayed. I tried doing this and the view lags around ~2 seconds on a Nexus 6 device every time I switch to and from the camera tab. Is it considered bad practice if I simply just keep the camera running, and is there a best approach to implement camera views with tabs?
I also tried if asynchronously loading the surface view/camera would be viable, but according to the Android Camera class reference:
This class is not thread-safe, and is meant for use from one event thread
I've also stumbled upon this similar SO question (for reference):
https://stackoverflow.com/questions/28634291/android-which-tab-view-approach-for-cpu-heavy-camera-preview-tab-fragments
Related
I created an Activity, which I load from a fragment within my "main" activity.
Within this new activity I placed an ImageView with an image from my drawable directory (I have about 10 other drawables I present the exact same way in the main activity).
The problem is that although in the IDE I see the image, it is not displayed in run time (via the simulator).
-- to clarify, the image is static hence the difference compared to other questions (I'm not loading it by code).
Any ideas on how to solve it?
My hunch is that it relates to the fact it's a new activity, but I'm new to android development, so I can't base it on any knowledge...
I did not add any code to the java section of the activity (didn't touch any "on.." nor added functionality to this specific file)
P.S. I tried cleaning the project, tried presenting an image that is presented on the main activity, and restarting anything that I can... nothing helped :(
My Activity xml is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="reducted">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/manageSubscriptionScreenLogo"
android:layout_width="match_parent"
android:layout_height="110dp"
app:srcCompat="#drawable/managesubscription_header" />
</LinearLayout>
</RelativeLayout>
It doesn't matter I take the ImageView and place it outside of the LinearLayout (and remove it), or change the size to wrap_content or match_parent (I tried all combinations), the image is not presented.
How it looks in the IDE:
And how it looks in run time:
Try using android:src="#drawable/managesubscrip_header" instead of app:srcCompat="#drawable/managesubscription_header" in ImageView to avoid automatic scaling of the drawable.
Let me know if it helps
I have a GLSurfaceView that I want to put inside a ScrollView. I accomplished this by adding a FrameLayout inside a LinearLayout which was added to the ScrollView.
Everyhing works nice, except that I am getting a black border on top of the GLSurfaceView when scrolling. When the screen is still, everyhing looks nice. Anybody have any ideas.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="900dp"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="35dp"
android:visibility="visible"
android:weightSum="1"
android:overScrollMode="never">
<FrameLayout
android:id="#+id/ecg_graph"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Generally speaking, you don't want to move SurfaceView (or its subclasses) around the screen. Bear in mind that SurfaceView has two parts, the Surface and the View. The View part -- usually just a transparent "hole" used during layout -- is handled by the app. The Surface part is a separate graphics layer composited by the system, and its size and position are managed by the Window Manager.
When you move a SurfaceView, the View part moves immediately, but the Surface lags behind, because moving it requires communicating with other processes. You should expect to see a black bar in the direction that the View is moving, because you've temporarily exposed an area outside what the Surface covers.
The preferred way to handle this is to use a TextureView, which behaves just like other Views. You would need to do your own EGL setup and thread management, since GLSurfaceView won't be handling those for you. You can find some examples in Grafika.
I am creating an app which does some tracking on a map. The tracking part works great inside my activity.
However, I want to have some kind of small overlay in the bottom right corner (like the minimalised video playback in the YouTube app) that stays there, even when I switch activities.
I have looked at this, but it's not really what I need. I don't need it to be moveable, and I think this is impossible to keep when switching activities.
Is there some kind of class that I can implement (Widget, Fragment, ...) that would fit my needs?
Thank you,
DebboR
This is a bit late and probably not relevant to you anymore, but maybe somebody else will find this helpful.
I don't think it's possible to switch activities and keep a certain view on screen. How I think this should be done is have a main activity with fragments that swap and in the activity's layout have a view overlay on top of the fragments container.
For example:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- Container for the fragments -->
<FrameLayout
android:id="#+id/fragment_container"
android:layout_below="#id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- This view will overlay the fragment in the bottom right corner -->
<View
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
In Android 2.3 application I used to support two cameras: one built-in and onу externally MJPG-streamed using Wi-Fi. The built-in camera must be recording video all the time and a user must have the ability to switch view between those. So, each camera had a dedicated SurfaceView to draw on. As the last child added to a FrameLayout has a higher Z-order, I programatically add the required camera view to a FrameLayout last to make it visible. I can't skip adding built-in camera since it can't record video without the preview display.
This scheme no longer works with Android 4: the built-in camera preview is always shown in spite of being added first or last. I played with 'setVisibility' methods on views and noticed that if one of views is set to be invisible (or gone) then none of them is showed at all. ViewGroup's 'bringChildToFront' method had no effect as well.
So, is there some workaround to make this work on Android 4? And I know that having multiple SurfaceViews is considered bad. Some code follows.
FrameLayout:
<FrameLayout android:id="#id/data"
android:layout_width="fill_parent" android:layout_height="fill_parent"/>
Code that populates the layout (no longer works on Android 4):
private void setCorrectView() {
data.removeAllViews();
List<Recorder> others = recorders.getOthers();
for (Recorder other : others) {
addToTheView(other);
}
addToTheView(recorders.getCurrent());
}
private void addToTheView(Recorder recorder) {
View view = recorder.getView(this); // get recorder's surface view
data.addView(view);
}
The same effect if I use FrameLayouts from XML:
<FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="#id/data"
android:layout_width="fill_parent" android:layout_height="fill_parent"/>
<FrameLayout
android:id="#+id/data_invisible"
android:layout_width="fill_parent" android:layout_height="fill_parent"/>
</FrameLayout>
Wherever I put built-in camera's surface view - it's always shown. Looks like internal camera's preview is now always on top in Android 4.
Answering to myself. To make this work I set the views' visibility to View.VISIBLE before starting the camera and set it to View.INVISIBLE after. This link may be helpful.
Is there any way to share the same object of the View across various activities? For example myApp has 4 activities, and every activity shows a Logo at the top of the screen. Now each activity will initiate 4 copies of the same Logo. So is there any way to get around this? And if 3 out of 4 share the same logo?
I can't say that it is completely impossible for you to do that. What I can say with almost certainty is that you should not attempt it or expect anything good to happen if you do manage it. Don't fight the framework, let it work for you. If the duplication is that much of an issue you create an abstract class that your Activities inherit from.
Also, since View's maintain a reference to the Context they were created in. If you did manage to pass a View from one Activity to another you would be creating a memory leak. Since the View would hold a reference to the old Activity via the Context it was created in.
Use seperate layout to make your logo.
Ex: title.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#drawable/headercon" >
<ImageView
android:id="#+id/headerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="#drawable/header" />
</LinearLayout>
This layout can be included in any other layout by using include tag
Ex:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
...
<include layout="#layout/title" />
...
</RelativeLayout>