7

I have a custom view that draws HUD:

HUD

Here is my layout:

<?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"
    android:orientation="vertical" >

    <VideoView
        android:id="@+id/videoView1"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <com.widgets.HUD
            android:id="@+id/hud"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

</FrameLayout>
public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.hud_fragment, container, false);

    frameLayout = (FrameLayout) view.findViewById(R.id.frameLayout);

    hudWidget = (HUD) view.findViewById(R.id.hudWidget);

    videoView = (VideoView) view.findViewById(R.id.videoView1);
    videoView.setVideoURI(Uri.parse("http://88.150.210.138:5001/spor"));
    videoView.start();

    frameLayout.removeView(hudWidget);
    frameLayout.addView(hudWidget);
    hudWidget.bringToFront();

    return view;
}

I play an RTSP stream on my VideoView as soon as the video starts playing it looks like that:

Video On HUD

How can i force the HUD to draw on top of the VideoView? HUD extends SurfaceView

Project

  • The project I'm trying to add the the VideoView is DroidPlanner You can try cloning and see the problem. (Need to add the VideoView manually because it's not in the repo).

chengbo
  • 5,789
  • 4
  • 27
  • 41
Danpe
  • 18,668
  • 21
  • 96
  • 131
  • Have you tried `view.bringtoFront()` if your widget extends View . Your layout definition seems correct. – Vrashabh Irde Aug 12 '13 at 05:12
  • @Slartibartfast tried that, check my update. still the same. – Danpe Aug 14 '13 at 00:45
  • 1
    I tried to recreate your issue but actually failed. Here is the project I made: https://github.com/andrask/androidhud It reproduces the same type of interface that you created with a video view a button and a custom view. When the video starts, all the elements stay on top, nothing happens. The only difference is that it does not use fragments. Have you tried to use a single activity or statically linked fragment? – allprog Aug 15 '13 at 21:56
  • can you show me the result of : adb shell dumpsys SurfaceFlinger – pierrotlefou Aug 16 '13 at 08:52
  • @allprog My HUD view is SurfaceView maybe thats it ? And you need to change the folder name of your `com1` to `com` it causes Path problems for Git on Windows. – Danpe Aug 17 '13 at 10:20
  • Yeah, I'm using Mac and just tried to put together the test as fast as possible. I'll try to play a bit with your project – allprog Aug 17 '13 at 19:00
  • @Danpe I sent you a pull request with the working solution. It took quite a few hours to put together. :) – allprog Aug 19 '13 at 15:03

5 Answers5

3

I found the answer for your question: VideoView on top of SurfaceView The SurfaceView and the VideoView are both surface views and it was not supported to overlap these in old versions of Android but available since 2.0.

What you need to do:

  1. set the pixelformat to TRANSPARENT in order to let the video shine through the interface

hudWidget.getHolder().setFormat(PixelFormat.TRANSPARENT);

  1. set the HUD surface to be a Media Overlay.

hudWidget.setZOrderMediaOverlay(true);

  1. create a new surface and set that as the Display for a MediaPlayer that plays the video.

There is a pull request where you can try these. https://github.com/arthurbenemann/droidplanner/pull/247

The thread that brought the solution: https://groups.google.com/forum/?fromgroups#!msg/android-developers/nDNQcceRnYA/ps9wTBfXIyEJ

Community
  • 1
  • 1
allprog
  • 16,540
  • 9
  • 56
  • 97
  • Your answer looks good ! i tested it and I'm having problems, the stream gets stuck after 1-3 frames... Are you having this issue as well? or does it keeps playing on your side ? – Danpe Aug 19 '13 at 18:14
  • Yeah, it sometimes happened to me too as the main thread got blocked too long. I'm happy it works now. – allprog Aug 19 '13 at 19:45
1

From the documentation on FrameLayout available here: Link

Child views are drawn in a stack, with the most recently added child on top

Add an id to the FrameLayout in your layout file. In your onCreate(Bundle), you will have something similar:

// find your framelayout
frameLayout = (FrameLayout) findViewById(....);

videoView = (VideoView) findViewById(R.id.videoView1);

hudView = (com.widgets.HUD) findViewById(R.id.hud);

After the video starts, do the following:

frameLayout.removeView(hudView);

frameLayout.addView(hudView);
Vikram
  • 51,313
  • 11
  • 93
  • 122
1

make a Handler which invalidate your hudView every 50 or 100 milliseconds

like this:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.hud_fragment, container, false);

        frameLayout = (FrameLayout) view.findViewById(R.id.frameLayout);

        hudWidget = (HUD) view.findViewById(R.id.hudWidget);

        videoView = (VideoView) view.findViewById(R.id.videoView1);
        videoView.setVideoURI(Uri.parse("http://88.150.210.138:5001/spor"));
        videoView.start();

        frameLayout.removeView(hudWidget);
        frameLayout.addView(hudWidget);
        hudWidget.bringToFront();

        //The Handler which invalidate your (hudWidget) every 50 milliseconds 

        new Handler() {
            public void handleMessage(android.os.Message msg) {
                super.handleMessage(msg);
                hudWidget.invalidate();
                sendEmptyMessageDelayed(0, 50);

            };
        }.sendEmptyMessage(0);

        return view;
    }
Mohammad Ersan
  • 12,304
  • 8
  • 54
  • 77
0

Test FrameLayout to replace RelativeLayout.

Maybe It works good.

carbonara
  • 49
  • 6
0

Extend VideoView and call setWillNotDraw(false) in its constructor. This way you can draw in onDraw(Canvas) then.

Sevastyan Savanyuk
  • 5,797
  • 4
  • 22
  • 34