In this tutorial we will learn creating a Floating Widget in our Application. You may have already seen a floating widget that is visible over the other apps. A very common example of Android Floating Widget can be seen with the Facebook Messenger App and I am sure many of you are already using messenger. So if you want to create a widget like that then, that is what we will be creating in this Android Floating Widget Tutorial.
Table of Contents
How can we create a Floating Widget?
Basically an Android Floating Widget is a normal view that is drawn over the apps. Or it doesn’t matter in which screen you are it will be drawn over, so it becomes very handy for user to perform multi tasking.
If you want to draw a Floating Widget in your application then your application mus have the SYSTEM_ALERT_WINDOW permission. Now you already know it that after Android Marshmallow we need to ask permissions at run time.
You can go to this Android Marshmallow Permissions Example to learn about runtime permissions.
Now lets create a new project and implement Android Floating Widget.
Creating a New Project
- So lets create a new project using Android Studio.
- Select an Empty Activity and wait till your project is completely loaded.
Creating UI
- For this project we need two layouts. The first layout is for the activity_main.xml from here we will create the Widget. The another layout is for our widget. Now lets start with the activity_main.xml.
Creating MainActivity UI
- Here activity_main.xml will contain only a single button and by pressing it we can create our widget. So paste the following code inside your activity_main.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/buttonCreateWidget" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Create Floating Widget" /> </RelativeLayout> |
Creating Android Floating Widget UI
- Now lets come to the main part of the UI. The UI for our widget. We have two states for the widget, the first state is when it is collapsed, and other state is when it is expanded.
- So create a new layout file named layout_floating_widget.xml inside layout directory and write the following xml code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RelativeLayout android:id="@+id/relativeLayoutParent" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:ignore="UselessParent"> <!-- this is the collapsed layout --> <RelativeLayout android:id="@+id/layoutCollapsed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:visibility="visible"> <ImageView android:id="@+id/collapsed_iv" android:layout_width="70dp" android:layout_height="70dp" android:layout_marginTop="8dp" android:src="@drawable/icon_simplified_coding" /> <ImageView android:id="@+id/buttonClose" android:layout_width="25dp" android:layout_height="25dp" android:layout_marginLeft="50dp" android:src="@drawable/icon_close" /> </RelativeLayout> <!-- this is the expanded layout --> <LinearLayout android:id="@+id/layoutExpanded" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#a0c3d7" android:orientation="horizontal" android:padding="8dp" android:visibility="gone"> <ImageView android:id="@+id/buttonSimplifiedCodingExpanded" android:layout_width="80dp" android:layout_height="80dp" android:src="@drawable/icon_simplified_coding" tools:ignore="ContentDescription" /> <LinearLayout android:id="@+id/buttonSimplifiedCoding" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="15dp" android:paddingRight="15dp" android:paddingTop="15dp" android:text="Simplified Coding" android:textAlignment="center" android:textAppearance="@style/Base.TextAppearance.AppCompat.Large" android:textColor="#ffffff" android:textStyle="bold" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="www.simplifiedcoding.net" android:textAlignment="center" android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" android:textColor="#ffffff" android:textStyle="bold" /> </LinearLayout> </LinearLayout> </RelativeLayout> </FrameLayout> |
- You can see in the above layout the expanded part  has the android:visibility=”gone” so we will switch the view states of widget on click.
- In the above layout I have used some icons so if you want these icons download my project from the bottom of this post and you will get the icons. As the icon part will give you errors right now.Â
Creating Android Floating Widget
Service for our Android Floating Widget
- Create a java class named FloatingViewService.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
package net.simplifiedlearning.androidfloatingwidget; import android.app.Service; import android.content.Intent; import android.graphics.PixelFormat; import android.os.IBinder; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; public class FloatingViewService extends Service implements View.OnClickListener { private WindowManager mWindowManager; private View mFloatingView; private View collapsedView; private View expandedView; public FloatingViewService() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); //getting the widget layout from xml using layout inflater mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null); //setting the layout parameters final WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); //getting windows services and adding the floating view to it mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); mWindowManager.addView(mFloatingView, params); //getting the collapsed and expanded view from the floating view collapsedView = mFloatingView.findViewById(R.id.layoutCollapsed); expandedView = mFloatingView.findViewById(R.id.layoutExpanded); //adding click listener to close button and expanded view mFloatingView.findViewById(R.id.buttonClose).setOnClickListener(this); expandedView.setOnClickListener(this); //adding an touchlistener to make drag movement of the floating widget mFloatingView.findViewById(R.id.relativeLayoutParent).setOnTouchListener(new View.OnTouchListener() { private int initialX; private int initialY; private float initialTouchX; private float initialTouchY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: initialX = params.x; initialY = params.y; initialTouchX = event.getRawX(); initialTouchY = event.getRawY(); return true; case MotionEvent.ACTION_UP: //when the drag is ended switching the state of the widget collapsedView.setVisibility(View.GONE); expandedView.setVisibility(View.VISIBLE); return true; case MotionEvent.ACTION_MOVE: //this code is helping the widget to move around the screen with fingers params.x = initialX + (int) (event.getRawX() - initialTouchX); params.y = initialY + (int) (event.getRawY() - initialTouchY); mWindowManager.updateViewLayout(mFloatingView, params); return true; } return false; } }); } @Override public void onDestroy() { super.onDestroy(); if (mFloatingView != null) mWindowManager.removeView(mFloatingView); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.layoutExpanded: //switching views collapsedView.setVisibility(View.VISIBLE); expandedView.setVisibility(View.GONE); break; case R.id.buttonClose: //closing the widget stopSelf(); break; } } } |
- Now we will code the MainActivity to launch our Android Floating Widget when the button is clicked.
Launching Android Floating Widget
- Now come inside MainActivity.java and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package net.simplifiedlearning.androidfloatingwidget; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.Settings; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static final int SYSTEM_ALERT_WINDOW_PERMISSION = 2084; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) { askPermission(); } findViewById(R.id.buttonCreateWidget).setOnClickListener(this); } private void askPermission() { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivityForResult(intent, SYSTEM_ALERT_WINDOW_PERMISSION); } @Override public void onClick(View v) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { startService(new Intent(MainActivity.this, FloatingViewService.class)); finish(); } else if (Settings.canDrawOverlays(this)) { startService(new Intent(MainActivity.this, FloatingViewService.class)); finish(); } else { askPermission(); Toast.makeText(this, "You need System Alert Window Permission to do this", Toast.LENGTH_SHORT).show(); } } } |
- Now at last we need to define the service and the SYSTEM_ALERT_WINDOW permission in the manifest.
Modifying Android Manifest File
- Here is my AndroidManifest.xml file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.simplifiedlearning.androidfloatingwidget"> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".FloatingViewService" android:enabled="true" android:exported="false" /> </application> </manifest> |
- Now thats it try running the application.
- You can see it is working fine. Now you can design your Android Floating Widget as per your requirements and do whatever you want.
So thats all for this Android Floating Widget Tutorial friends. If you are having any queries then please comment. And I will try to solve your problems. Thank You 🙂