How to Create Android Floating Widget To Let Multiple Views Float Over The Screen

0
Shares
How to Create Android Floating Widget To Let Multiple Views Float Over The Screen
2.8 (56%) 5 votes

android floating widget

Floating widgets are the views that generally float over the device screen. This Android floating widget will remain floating no matter whatever screen you’re in. The floating widget in Android basically helps in multitasking as a user can work on other app 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 Android floating images while using the calculator at the same time.

In this Android app development tutorial, we’ll see the implementation process of the Android floating widget in an Android app.

Let’s Get Started

Open your Android Studio and create a new project.

screen1

In the next tab, select your target Android device.

screen2

Select ‘Empty Activity’ and click on next.

screen3

Lastly, customize the activity.

screen4

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;
@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:
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 enable.", 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:textColor="@android:color/white"
android:backgroundTint="#00C1E7"
android:id="@+id/createBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Setup Floating Widget" />
</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" />
<ImageView
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!

Now run the project to see the results.

Although, if you face any issue, or implementing Android floating widget in your startup app, considering advice from an expert and Android app development company is better for you app as well as your startup.

Grab a free copy of Floating Widget Demo from Github.

 
0
Shares
 

Want to Develop Android App From Scratch? Contact Us Now