Want to learn more about Android development? This resource changed my life.
In this tutorial I show how you can make an overlay or second activity which overlays your main activity with a transparent overlay which you can use to show an instruction in the screen. This is often used to show the user key features of your app when they use your app the first time.
Note that this tutorial is part of a set of tutorials to develop an app to store locally your clothing sizes. Yeah Yeah, pretty useful ;)
If your wondering how to make the background gradient or the used action bar please see the following two tutorials.
Tutorial Gradient Background
Tutorial Actionbar
In this video you can see how the overlay instruction in Android works
General Approach to create a one-time overlay.
- Use a FrameLayout to define two layouts. One layout of your mainactivity and the other layout for the overlay;
- Create a Method isFirstTime() to set SharedPreferences and visibility of your overlay
- Call this method in your code.
Below you see the XML of the layout of the MainActivity. The FrameLayout exist out of two RelativeLayouts. The first RelativeLayout defines the actually app. In my case the images of the clothing and the textviews which retrieve the locally stored preferences (not part of this tutorial). The second part of the FrameLayout is a RelativeLayout defining the overlay with and image pointing the user to the settings icons in the ActionBar. Note the background color of the second RelativeLayout is a light grey tint (#88666666)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main_layout" > <!--Below activity widgets when the transparent layout is gone --> <RelativeLayout xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gradient"> <include android:id="@+id/include1" layout="@layout/actionbar" /> <ImageView android:id="@+id/ivPants" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="80dp" android:paddingLeft="@dimen/padding10dp" android:src="@drawable/pants" /> <ImageView android:id="@+id/ivDressshirt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tvLength" android:layout_marginTop="55dp" android:paddingLeft="@dimen/padding10dp" android:src="@drawable/shirt" /> <ImageView android:id="@+id/ivSweater" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/ivDressshirt" android:layout_below="@+id/ivDressshirt" android:layout_marginTop="57dp" android:paddingLeft="@dimen/padding10dp" android:src="@drawable/sweater" /> <ImageView android:id="@+id/ivShoe" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/ivSweater" android:layout_below="@+id/ivSweater" android:layout_marginTop="57dp" android:paddingLeft="@dimen/padding10dp" android:src="@drawable/shoe" /> <TextView android:id="@+id/tvWaist" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/ivPants" android:layout_toRightOf="@+id/ivSweater" android:paddingLeft="@dimen/padding10dp" android:text="Waist" android:textSize="26sp" /> <TextView android:id="@+id/tvLength" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/ivPants" android:layout_toRightOf="@+id/ivSweater" android:paddingLeft="@dimen/padding10dp" android:text="Length" android:textSize="26sp" /> <TextView android:id="@+id/tvDressshirt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/ivDressshirt" android:layout_toRightOf="@+id/ivSweater" android:paddingLeft="@dimen/padding10dp" android:text="Dressshirt" android:textSize="26sp" /> <TextView android:id="@+id/tvSweater" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/tvDressshirt" android:layout_alignTop="@+id/ivSweater" android:paddingLeft="@dimen/padding10dp" android:text="Sweater" android:textSize="26sp" /> <TextView android:id="@+id/tvShoe" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/tvSweater" android:layout_alignTop="@+id/ivShoe" android:paddingLeft="@dimen/padding10dp" android:text="Shoe" android:textSize="26sp" /> </RelativeLayout> <!--Below is the transparent layout positioned at startup --> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#88666666" android:id="@+id/top_layout"> <ImageView android:id="@+id/ivInstruction" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingTop="25dp" android:layout_marginRight="15dp" android:clickable="false" android:paddingLeft="20dip" android:scaleType="center" android:src="@drawable/help" /> </RelativeLayout> </FrameLayout>
In summary you need to define two RelativeLayouts within one FrameLayout. One RelativeLayout representing your overlay and the other RelativeLayout your app.
Now you need to create a Method which create the SharedPreference that the overlay is only inflated the first time. The SharedPreferences is used to store that the user already saw the overlay. You can read more about SharedPreferences here Android SDK – SharedPreferences
private boolean isFirstTime() { SharedPreferences preferences = getPreferences(MODE_PRIVATE); boolean ranBefore = preferences.getBoolean("RanBefore", false); if (!ranBefore) { SharedPreferences.Editor editor = preferences.edit(); editor.putBoolean("RanBefore", true); editor.commit(); topLevelLayout.setVisibility(View.VISIBLE); topLevelLayout.setOnTouchListener(new View.OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { topLevelLayout.setVisibility(View.INVISIBLE); return false; } }); } return ranBefore; }
First we created a new SharedPreferences instance (to only this application MODE_PRIVATE) and created a Boolean telling if the overlay has already been displayed before or not (TRUE or FALSE). You can use the Editor (part of the SharedPreferences class of Android SDK) to modify the values of your SharedPreferences. IF the ranbefore did not run before we set the layout (overlay) as visible. With other words showing the user the instruction. Now we also want to configure what should happen when the user clicks anywhere on the screen. In this case we want the overlay to disappear directly without any message or something. For this you can use the onTouchListener and the method onTouch. Extra note: the topLevelLayout is the name of my RelativeLayout which I defined as the transparent layout (see XML in this post).
Now you have defined the behavior via a method called isFirstTime().
In your OnCreate method make the reference to your overlay layout and call the function
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); topLevelLayout = findViewById(R.id.top_layout); if (isFirstTime()) { topLevelLayout.setVisibility(View.INVISIBLE); }
Here you can see when the isFirstTime() method has run we set the topLevelLayout as Invisible, meaning the user already saw the overlay before.
This is all folks, In this tutorial I gave an example of an overlay activity in Android. The next tutorial we will extend this app with local storage and setting the clothing sizes.
Want to learn more about Android development? This resource changed my life.
Very interesting subject , regards for posting .
Hi Christian.
This was VERY helpful to me. Thanks for sharing.
One question, where do I get that arrow image and writing from? Did you create that?
Thanks,
Matt
Hi Matt,
Yes i created those via photoshop. Let me know i’m happy to sent you the source file.
Best
Christian
Hi Christian,
Amazing tutorial, very helpful, but I have one question: Is it possible to get the overlay also above the ActionBar? I’m using the ActionBar Sherlock.
Thanks in advance.
Kind regards, Martijn
Hi Martijn, thanks for reading my tutorial. I’m not sure what you mean with getting the overlay above the actionBar. The overlay is positioned over the complete activity. Do you mean to create a smaller overlay which only overlays the actionbar? Meaning a user could potentially ignore it and use the rest of the application while having an overlay over the actionBar?
Hi Christian,
Now, the ActionBar does not have a transparant layer above it, unlike the rest of the screen. Maybe it is because I’m using the ActionBar Sherlock I don’t know.
Hi Christian,
I am very beginner programmer, I try to insert overlay help to my app who just have one activity and one layout. And I still have problem with topLevelLayout, should I change it. or What?
Hi Christian,
NIce tutorial. Can you please send me those images?
Thanks.
Hi,
please send the complete source to my e-mail id. I liked the tutorial ..Its cool..thanks for sharing the knowledge..
thanks!
hi i tried to implement this into my own code made my own image but used your method but it tells me it cannot resolve topLevelLayout and cannot resolve motion event is it just a case of declaring them? dont think it is as i cant see them in your code any ideas?
Hi Martin,
Thanks for visiting my blog.
Check this post (on the bottom is the complete mainActivity). I think you are missing the declaration of
View topLevelLayout;
http://www.christianpeeters.com/android-tutorials/android-tutorial-local-storage-an-app-example/
Hi Christian,
Thanks for sharing. Your tutorial is informative.
Hope you continue to blog.
:)
Hi Christian,
Thanks for this tutorial, it is very helpful i was looking for this,
can you send me the image and text, Photoshop file.
it would very helpful
thanks
Hi,
I’m a new developer and I need to know how to embed weather overlays on google map in android.
Hey plz send me the source code..
Great Tutorial . Its really fast and simple perfect to start with