How to properly overlay UI Widgets over SurfaceView?

I've got a portrait camera preview working inside a RelativeLayout, a button and a textview. They are there, but not visible, they react to touch actions properly. How do i setup the Z-Order or priority? This is my main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+layout/frame"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

<SurfaceView android:id="@+id/surface" android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView>
<Button android:layout_height="wrap_content" android:layout_width="match_parent" android:onClick="hablar" android:text="Button" android:id="@+id/button1"></Button>
<EditText android:layout_height="wrap_content" android:layout_width="match_parent" android:text="EditText" android:id="@+id/edita"></EditText>
</RelativeLayout>
</FrameLayout>

Answers


The SurfaceView Overlay sample in ApiDemos shows how to do this. Look for the "SurfaceView Overlay" section here: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/index.html


just put a View over SurfaceView:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">

    <SurfaceView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <View
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="lalalalala" />
</FrameLayout>

Hmm, I have it working in a FrameLayout where the SurfaceView is sibling to a ZoomControl. That is, this structure works for me:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <SurfaceView
        android:id="@+id/surface"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <ZoomControls
        android:id="@+id/zoom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        />
</FrameLayout>

Maybe the RelativeLayout breaks it?


The answer is not intuitive at all, but I found how to do it. Unlike Linear Layouts, order of declaration does NOT define the Z order in Relative Layouts. I was able of overlaying a textview over the Camera Preview by declaring both views in XML and, and overlaying them programatically on my Activity's onCreate Method.

Suppose you have an XML with a TextView with a nice transparent backgroud that you want to overlay over the Camera Preview frame layout, because why not?, it looks cool!:

<RelativeLayout>
      <TextView
        android:id="@+id/txtnombotiga"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Ola ke ase"
        android:textColor="#000000"
        android:textSize="16sp"    
        android:background="#55ffffff" 
       />
  <FrameLayout
      android:id="@+id/cameraPreview"
      android:layout_width="match_parent"
      android:layout_height="240dp">     
  </FrameLayout>
</RelativeLayout>

If left like that, the camera will cover your text, no matter what :( To solve it, let´s go programatical, and: 1) detach the TextView from its parent Layout 2) attach it to the camera´s frame layout after attaching the camera first.

Heres the code

OnCreate(){ ...blaa blaaa...

//Create camera instance and reference to our frame Layout
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);        
FrameLayout preview = (FrameLayout) findViewById(R.id.cameraPreview);
//Add camera to the Frame Layout
preview.addView(mPreview);
//Get reference to the TextView you want to overlay and type something funny
TextView txt=(TextView)findViewById(R.id.txtnombotiga);     
txt.setText("ola keee aseee!");
//1) Step 1, here comes the magic! dettach the textView from its original Layout
((ViewGroup)txt.getParent()).removeView(txt);
//1) Step 2, voila! attach it to the View, order matters here so it will appear on 
//top of the camera!
preview.addView(txt);

This is the general way to do it, If you need more details let me know. I need to meet deadlines at work, so I use the first solution that comes up to my mind, sometimes not the most elegant or efficient, if you know a better way of doing it, please share it with us!


Need Your Help

Detect a key being held down in java 7

java swing key-bindings

I'm trying to key bind the a and d keys to make a character move left and right, but the actions only happen once when you press the keys. How can I modify this code to make it do the event while a...