95

I am wanting to create help overlays like the ones you see when ICS loads for the first time or in apps like ES File Explorer or Apex Launcher (there are more, but I can't think of them right now). Is this just a relative layout with one view sitting on top of the other? I haven't been able to find any sample code for doing such a thing. Anyone know how this is done or have any ideas?

ES File Explorer ES File Explorer

ssuperz28
  • 1,834
  • 1
  • 14
  • 23

4 Answers4

85

Let's assume you ordinarily would call setContentView(R.layout.main), but on first run, you want to have this overlay.

Step #1: Create a FrameLayout in Java code and pass that to setContentView().

Step #2: Use LayoutInflater to inflate R.layout.main into the FrameLayout.

Step #3: Use LayoutInflater to inflate the overlay into the FrameLayout.

Step #4: When the user taps the button (or whatever) to dismiss the overlay, call removeView() to remove the overlay from the FrameLayout.

Since the overlay is a later child of the FrameLayout, it will float over top of the contents of R.layout.main.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 6
    @ssuperz28: Yeah, well, except for the hand-drawn arrowheads and bubble. You're on your own for those. :-) – CommonsWare Apr 18 '12 at 20:32
  • I don't know if you managed to do what you wanted, but here is another alternative. http://stackoverflow.com/questions/8841240/how-to-create-a-semi-transparent-instruction-page-in-android If you mantain the solution given by CommonsWare, the only thing that occurs me in order to set the arrows, is to define the FrameLayout of instructions with a resourceImage or backgroundImage already with the image with the arrows (and transparency). – Edison Santos Jul 29 '13 at 09:23
  • 1
    Is there a way to do this but doing it relative to the children's position who are below from the FrameLayout? – 4gus71n Oct 03 '13 at 01:49
  • @CommonsWare - sir this would work regardless of whichever device it may be ? – Rat-a-tat-a-tat Ratatouille Apr 03 '14 at 05:40
  • @Rat-a-tat-a-tatRatatouille: It should. I cannot rule out some device manufacturer doing something strange, but that "strange" would probably break other things as well. – CommonsWare Apr 03 '14 at 07:25
  • alright il try it and then get back with positive results i believe :)..thank u @CommonsWare – Rat-a-tat-a-tat Ratatouille Apr 03 '14 at 07:41
  • @CommonsWare - sir it worked well :) .. i mean irrespective of whichever device it is, 10" or 7" or 3.5" .. – Rat-a-tat-a-tat Ratatouille Apr 04 '14 at 04:57
  • Unfortunately this method generates a view for the coach marks that does not cover the action bar of a 4.x style designed app. – Nantoka Sep 16 '14 at 13:57
  • I have a question. I am assuming on the images above that these are text views (with compound drawable) and or image views. My question is, doesn't the arrows where they are pointing to displace as you increase density? (devices with bigger screen) How do you go about solving this – user3364963 Oct 13 '14 at 18:58
  • 2
    @user3364963: Dynamically adjust the positions of things. My answer was somewhat simplified. I assume that they determine the position of the to-be-highlighted elements and adjust coordinates of the "coach marks". A custom `ViewGroup` for the "coach marks" layer could handle that, and there are libraries (e.g., `ShowcaseView`) that offer canned implementations of that pattern. – CommonsWare Oct 13 '14 at 19:01
  • @CommonsWare thanks for the advice. I cannot use the ShowcaseView because I am targeting API 8. – user3364963 Oct 13 '14 at 19:59
  • I'm using a coordinator layout and it has an appbar included. Is there a way to bring view above toolbar using coordinator layout? – Akash Raghav Jul 20 '17 at 13:45
  • @AkashRaghav: I have no idea. You may want to ask a separate Stack Overflow question regarding that. – CommonsWare Jul 20 '17 at 13:47
  • I have asked a new question. Here is the link - https://stackoverflow.com/questions/45216512/create-an-overlay-view-to-cover-whole-activity-including-toolbar-in-coordinator – Akash Raghav Jul 21 '17 at 08:03
80

"Coach mark" is "Help overlay" in UX talk :-)

coach_mark.xml is your coach mark layout

coach_mark_master_view is the id of the top most view (root) in coach_mark.xml

public void onCoachMark(){

    final Dialog dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
    dialog.setContentView(R.layout.coach_mark);
    dialog.setCanceledOnTouchOutside(true);
    //for dismissing anywhere you touch
    View masterView = dialog.findViewById(R.id.coach_mark_master_view);
    masterView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dialog.dismiss();
        }
    });
    dialog.show();
}

Adding sample of coach_mark.xml (to this excellent solution given by Oded Breiner), so its easy for ppl to copy & paste to see working example quickly.

Sample of coach_mark.xml here, change the -> drawable/coach_marks to your image:

coach_mark.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/coach_mark_master_view">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
         <ImageView
             android:id="@+id/coach_marks_image"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_centerInParent="true"
             android:layout_gravity="center_horizontal"
             android:src="@drawable/coach_marks" />
    </RelativeLayout>
</LinearLayout>

And optionally use this theme to remove padding:

<style name="WalkthroughTheme" parent="Theme.AppCompat">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>
Oded Breiner
  • 28,523
  • 10
  • 105
  • 71
  • Hello, how can you stretch this Dialog to match the screen? From the documentation, `A dialog is a small window that prompts [...]. A dialog does not fill the screen and is normally used for modal events [...].`. If I use this code, I get my master view compressed in a small portion of the screen. If i set `android:layout_width="640dp" android:layout_height="480dp"` (that is, the actual values of the screen I'm testing with), it works correctly. (of course this is not a feasible solution) – ocramot Apr 23 '15 at 10:43
  • @ocramot : the above example should be full screen because of match_parent and Window.FEATURE_NO_TITLE – Oded Breiner Apr 28 '15 at 19:20
  • Then there must be some other problem, because I'm seeing it in a different way – ocramot Apr 28 '15 at 21:14
  • 1
    I know this is at least a few months old but did that full screen question ever get figured out? – cbhedd Jun 10 '15 at 19:49
  • @cbhedd - Maybe it's the theme, which theme are you using? – Oded Breiner Jun 11 '15 at 02:12
  • @oded which theme you are using? – Raj Shah Jun 12 '15 at 22:29
  • 3
    To those that do not know how to set the theme of the dialog, just instantiate the dialog like so: `new Dialog(getContext(), R.style.WalkthroughTheme);` – w3bshark Dec 02 '15 at 03:55
  • Process: com.mintwalk, PID: 3207 java.lang.OutOfMemoryError: Failed to allocate a 1489584 byte allocation with 144144 free bytes and 140KB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) – Ramesh Bhati Oct 13 '16 at 13:56
  • @RameshM.Bhati looks like you might be loading images that are too big, try using smaller images or use an image loading library like: http://square.github.io/picasso – Oded Breiner Oct 14 '16 at 08:39
4

You can do that pretty quickly. You add, for exemple a LinearLayout where you put a picture with alpha which correspond to your help information and what do you want to draw like an overlay. In you xml of your activity you put this layout in a RelativeLayout after the layout of your activity with the Gone visibility. When you want to draw the help information, you just neeed to set this visibility to visible.

I hope, I'm clear, if you have any question,I'm be please to answer them.

FUBUs
  • 617
  • 5
  • 9
  • Thanks for your input. This is how I pictured it being done. I have to give credit to the answer below though as that is the way I'm going to build it. It seems more manageable and I don't have to alter my main activity layout. – ssuperz28 Apr 18 '12 at 20:29
1

See my another answer how programmatically show an overlay layout on top of the current activity. Activity's layout.xml does not need to know anything about the overlay skin. You can put overlay semi-transparent, cover only part of the screen, one or more textview and buttons on it... How to overlay a button programmically?

  • create res/layout/paused.xml RelativeLayout template or use any layout toplevel
  • create a function to show overlay skin
  • key is to get handle to layout.xml, use LayoutInflater class to parse xml to view object, add overlay view to current layout structure
  • My example uses a timer to destroy overlay object by completely removing it from the view structure. This is probably what you want as well to get rid of it without a trace.

My goal was that main activities are not aware of any overlay skin, overlays come and go, many different overlays, still able to use overlay1.xml text files as a template, and content should programmatically be updated. I do pretty much what CommonsWare told us my post shows the actual program code to get started.

disclaimer: OPs "Thanks for your input. This is how I pictured it being done. I have to give credit to the answer below" comment does not mean my answer but CommonsWare answer. Stackoverflow have changed post orderings.

Community
  • 1
  • 1
Whome
  • 10,181
  • 6
  • 53
  • 65