Do you want to create an Android floating widget for your app? No need to look here and there. Through this post, we will take you through the process of creating a floating widget in Android. Stay tuned until the end, and you will be able to create a floating widget for your application.
Table of Contents
Floating widgets are the views that generally float over the device screen. This Android floating view will remain floating no matter whatever screen you are in. The floating widget in Android basically helps in multitasking as a user can work on other apps and control your app as well.
For instance, if the user is using a calculator and your app is a music player, the user can still use your app through floating layout Android while using the calculator at the same time.
In this Android layout height wrap app development tutorial, we will see the implementation process of the Android floating widget in an Android app.
Looking for an Android App Developers?
Get in touch with us. We have experienced Android app developers who develops custom app solution tailored to your
Steps to Create Android Floating Widget
First of all, open your Android Studio and create a new project.
In the next tab, select your target Android device.
Select ‘Empty Activity’ and click on next.
Lastly, customize the activity.
Create Java class name “FloatWidgetService”
package com.floatingwidget; import android.app.Service; import android.content.Intent; import android.graphics.PixelFormat; import android.os.IBinder; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; public class FloatWidgetService extends Service { private WindowManager mWindowManager; private View mFloatingWidget; public FloatWidgetService() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); mFloatingWidget = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null); 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 ); params.gravity = Gravity.TOP | Gravity.LEFT; params.x = 0; params.y = 100; mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); mWindowManager.addView(mFloatingWidget, params); final View collapsedView = mFloatingWidget.findViewById(R.id.collapse_view); final View expandedView = mFloatingWidget.findViewById(R.id.expanded_container); ImageView closeButtonCollapsed = (ImageView) mFloatingWidget.findViewById(R.id.close_btn); closeButtonCollapsed.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { stopSelf(); } }); ImageView closeButton = (ImageView) mFloatingWidget.findViewById(R.id.close_button); closeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { collapsedView.setVisibility(View.VISIBLE); expandedView.setVisibility(View.GONE); } }); mFloatingWidget.findViewById(R.id.root_container).setOnTouchListener(new View.OnTouchListener() { private int initialX; private int initialY; private float initialTouchX; private float initialTouchY; 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: int Xdiff = (int) (event.getRawX() - initialTouchX); int Ydiff = (int) (event.getRawY() - initialTouchY); if (Xdiff < 10 && Ydiff < 10) { if (isViewCollapsed()) { collapsedView.setVisibility(View.GONE); expandedView.setVisibility(View.VISIBLE); } } return true; case MotionEvent.ACTION_MOVE: params.x = initialX + (int) (event.getRawX() - initialTouchX); params.y = initialY + (int) (event.getRawY() - initialTouchY); mWindowManager.updateViewLayout(mFloatingWidget, params); return true; } return false; } }); } private boolean isViewCollapsed() { return mFloatingWidget == null || mFloatingWidget.findViewById(R.id.collapse_view).getVisibility() == View.VISIBLE; } @Override public void onDestroy() { super.onDestroy(); if (mFloatingWidget != null) mWindowManager.removeView(mFloatingWidget); } }
Add Permission in Manifest
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Add Service in Manifest
<service android:name=".FloatWidgetService" android:enabled="true" android:exported="false"/>
MainActivity
package com.floatingwidget; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.provider.Settings; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static final int APP_PERMISSION_REQUEST = 102; @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)) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivityForResult(intent, APP_PERMISSION_REQUEST); } else { initializeView(); } } private void initializeView() { Button mButton = (Button) findViewById(R.id.createBtn); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startService(new Intent(MainActivity.this, FloatWidgetService.class)); finish(); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == APP_PERMISSION_REQUEST && resultCode == RESULT_OK) { initializeView(); } else { Toast.makeText(this, "Draw over other app permission not enabled.", Toast.LENGTH_SHORT).show(); } } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/createBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:backgroundTint="#00C1E7" android:text="Setup Floating Widget" android:textColor="@android:color/white" /> </RelativeLayout>
layout_floating_widget.xml
<?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/root_container" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:ignore="UselessParent"> <RelativeLayout android:id="@+id/collapse_view" 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/diamond" tools:ignore="ContentDescription" /> <ImageView android:id="@+id/close_btn" android:layout_width="25dp" android:layout_height="25dp" android:layout_marginLeft="50dp" android:src="@drawable/error" tools:ignore="ContentDescription" /> </RelativeLayout> <LinearLayout android:visibility="gone" android:id="@+id/expanded_container" android:layout_width="wrap_content" android:layout_height="80dp" android:background="#00C1E7" android:orientation="horizontal" android:padding="5dp"> <ImageView android:layout_width= "70dp" android:layout_height= "70dp" android:src= "@drawable/diamond" tools:ignore= "ContentDescription" /> <TextView android:lineSpacingExtra="1dp" android:layout_width="100dp" android:layout_height="match_parent" android:gravity="center_vertical" android:padding="5dp" android:text="Floating Widget contols here" android:textColor="@android:color/white" android:textSize="14sp" android:textStyle="bold" /> <TextView android:id="@+id/close_button" android:layout_width="25dp" android:layout_height="25dp" android:src="@drawable/error" tools:ignore="ContentDescription" /> </LinearLayout> </RelativeLayout> </FrameLayout>
That’s It!
Although, if you face any issue, or implementing floating widget Android in your startup app development, considering advice from an expert and Android app development company is better for your app as well as your startup. Here, we have listed a few of the most common questions we receive on a daily basis.
Grab a free copy of Floating Android Widget Tutorial from Github.
Frequently Asked Questions
Where are floating widgets used in Android?
One of the most popular use-cases of floating widgets is Facebook’s chat head bubble button. Apart from that, apps like Uber and Ola also have floating widgets that help drivers switch from the app to maps and vice versa.
What are the benefits of Android floating widgets?
Android floating widgets make multi-tasking easy and seamless. They allow users to toggle between two apps swiftly and with just a single tap.
Can I create Android floating widgets/buttons in iOS?
Yes. You can create it by creating your own subclass of UIWindow, and then creating an instance of that subclass. For more information, you can follow this thread.
Conclusion
We hope this tutorial helped you create an Android floating widget for your app. Being an Android app development company, we have been working with Android for a decade now. Thus, if you are nurturing an idea for creating your own app or seeking guidance — feel free to get in touch with us. We will be happy to help.