floating icon like facebook chat head

How to Create Floating Icon like Facebook Messenger icon Android

All of us love Facebook messenger icon(float over the screen ). The Facebook messenger icon (floating icon) remain on top and can float anywhere on screen. You can touch it anytime, it will let you inside the current active messenger window.

It is Pretty Cool !!! It is very convenient to perform multitask on one finger touch. You can drag it to any where on screen.

Today in this post, I will show you ” How to create floating icon like Facebook Messenger App”.  Some people called it as floating widget. Also in this project When you click on floating icon it will show a chat window ,where you can type a message.

Floating Icon- 3 Important Point

Facebook chat head(Messenger icon) or Generally say it floating icon is nothing but a floating view. In your android app, you have to define the app permission – android.permission.SYSTEM_ALERT_WINDOW . This permission let you drag your app icon over other app or Home screen.

Second important thing is icon can be click any time, so you have to create a service that can monitor click event on floating icon.

I have used the background service to add the floating widget into the view hierarchy of the current screen. So, this floating view is always on top of application windows.

Third thing is, to drag floating icon across the screen I am using OnTouchListener() to listen to drag events and change the position of the chat has in the screen.

1) Create Floating View Layout
2) Create activity_main.xml
3) Create floating service
4) Add Permission in Manifest file
5) Check run time Permission
6) Run code on device

Login & Download source code

download-code350-100

50 day android course

 

Create Floating View Layout

Create a new project in android studio, My project name is “FloatingWidget”. On res folder create new xml layout file name as “floatingview.xml”.

Collapsed view

The floating widget will remain collapsed when the view is launched. When the user clicks on this view, an expanded view will open.

Expanded View

On this view, I put a EditText to type message. You can create any type of form in this expanded view. Like you can put shortcut of different apps or can create google search bar etc.

<?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">

    <!--Root container-->
    <RelativeLayout
        android:id="@+id/root_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:ignore="UselessParent">

        <!--View while view is collapsed-->
        <RelativeLayout
            android:id="@+id/collapse_view"
            android:layout_width="wrap_content"
            android:visibility="visible"
            android:layout_height="wrap_content">

            <!--Icon of floating widget -->
            <ImageView
                android:id="@+id/collapsed_iv"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_marginTop="8dp"
                android:src="@mipmap/floatingbutton"
                tools:ignore="ContentDescription"/>

            <!--Close button-->
            <ImageView
                android:id="@+id/close_btn"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_marginLeft="40dp"
                android:src="@drawable/ic_close"
                tools:ignore="ContentDescription"/>
        </RelativeLayout>

        <!--View while view is expanded-->
        <RelativeLayout
            android:id="@+id/expanded_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"

            android:background="@drawable/rounded_corner_fb"
            android:visibility="gone"
            android:orientation="vertical"
            android:padding="8dp"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="2dp"
            android:layout_marginTop="40dp">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_alignParentRight="true"
                android:layout_gravity="top|right"
                android:layout_marginRight="10dp"
                android:layout_marginTop="5dp"
                android:layout_marginBottom="15dp">

                <ImageView
                    android:id="@+id/open_exp_button"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:layout_alignParentBottom="true"
                    android:src="@android:drawable/ic_notification_overlay"
                    android:layout_marginRight="20dp"/>

                <ImageView
                    android:id="@+id/close_exp_button"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:src="@android:drawable/ic_delete"/>


            </LinearLayout>


            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:id="@+id/displaytext"
                android:layout_gravity="bottom"
                android:gravity="left"
                android:layout_marginRight="30dp"
                android:background="@drawable/msgback"
                android:visibility="gone"
                android:padding="5dp"
                android:layout_above="@+id/editlayout"/>


            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/editlayout"
                android:orientation="horizontal"
                android:layout_marginBottom="5dp"
                android:layout_alignParentBottom="true">
                <EditText
                    android:id="@+id/edittext"
                    android:layout_weight="1"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:text="your text here"
                    android:textColor="#000000"
                    android:layout_gravity="center_vertical"
                    android:maxLines="5"
                    android:textSize="20sp"
                    android:paddingRight="60dp"
                    android:focusable="true"
                    android:background="@drawable/rounded_corner_5px"
                    android:focusableInTouchMode="true"/>
                <ImageButton
                    android:id="@+id/sendText"
                    android:layout_marginLeft="-60dp"
                    style="?android:buttonBarButtonStyle"
                    android:layout_gravity="center_vertical"
                    android:paddingBottom="5dp"
                    android:src="@android:drawable/ic_menu_send"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>



        </RelativeLayout>


    </RelativeLayout>

</FrameLayout>

 

Create activity_main.xml

In main layout file I am using a button to launch floating icon. I real project you need to do auto service launch when new notification come for your app. To do this you have to use Broadcast Receiver.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="blueappsoftware.floatingwidget.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dp"
        android:text="Click button to see floating widget!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/notify_me"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Create Floating Widget" />

</android.support.constraint.ConstraintLayout>

 

Create floating Service

Now I am going to create service that will keep care about floating icon. create new java file name as FloatingService.java There is three part of this service-

  1. Create Container view
  2. Create onclick listener on Expanded view items
  3. Create onTouch listener for drag and launch view

Create Container view

First I am going to create a view that will hold floating icon. In this java file I am going to define primary location of the floating icon which is top left corner of device screen. Inside onCreate() method I am using WindowManager to define location of icon.

There is an Important Flag

WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM

I have created this project to demonstrate floating icon so when you click on edittext in expanded view, it will not show keypad to type word on it. You have to use WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE with some other configuration.

public class FloatingService extends Service {
    private WindowManager mWindowManager;
    private View mFloatingView;

    public FloatingService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //Inflate the floating view layout we created
        mFloatingView = LayoutInflater.from(this).inflate(R.layout.floatingview, null);

        //Add the view to the window.
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
                PixelFormat.TRANSLUCENT);

        //Specify the view position
        params.gravity = Gravity.TOP | Gravity.LEFT;        //Initially view will be added to top-left corner
        params.x = 0;
        params.y = 100;

        //Add the view to the window
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mFloatingView, params);


  }
}

Create onclick listener on Expanded view items

In this part I define onClick Listener on editText and close button. You know about how to set onClick() on item so I am not going to explain it here.

Create onTouch listener for drag and launch view

Now its time to define where you floating icon will go with your finger movement. To get the finger movement attach onTouchListener on view.

 //Drag and move floating view using user's touch action.
        mFloatingView.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:

                        //remember the initial position.
                        initialX = params.x;
                        initialY = params.y;

                        //get the touch location
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        int Xdiff = (int) (event.getRawX() - initialTouchX);
                        int Ydiff = (int) (event.getRawY() - initialTouchY);


                        //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking.
                        //So that is click event.
                        if (Xdiff < 10 && Ydiff < 10) {
                            if (isViewCollapsed()) {
                                //When user clicks on the image view of the collapsed layout,
                                //visibility of the collapsed layout will be changed to "View.GONE"
                                //and expanded view will become visible.
                                collapsedView.setVisibility(View.GONE);
                                expandedView.setVisibility(View.VISIBLE);
                                typetext.requestFocus();

                                // attach keypad with edittext and other configuration you have to define there
                                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                                imm.showSoftInput(typetext, InputMethodManager.SHOW_IMPLICIT);

                            }
                        }
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        //Calculate the X and Y coordinates of the view.
                        params.x = initialX + (int) (event.getRawX() - initialTouchX);
                        params.y = initialY + (int) (event.getRawY() - initialTouchY);


                        //Update the layout with new X & Y coordinate
                        mWindowManager.updateViewLayout(mFloatingView, params);
                        return true;
                }
                return false;
            }
        });
    }

Complete FloatingService.java file

package blueappsoftware.floatingwidget;

import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.media.Image;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by Jaink on 26-07-2017.
 */

public class FloatingService extends Service {
    private WindowManager mWindowManager;
    private View mFloatingView;

    public FloatingService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //Inflate the floating view layout we created
        mFloatingView = LayoutInflater.from(this).inflate(R.layout.floatingview, null);

        //Add the view to the window.
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
                PixelFormat.TRANSLUCENT);

        //Specify the view position
        params.gravity = Gravity.TOP | Gravity.LEFT;        //Initially view will be added to top-left corner
        params.x = 0;
        params.y = 100;

        //Add the view to the window
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mFloatingView, params);

//The root element of the collapsed view layout
        final View collapsedView = mFloatingView.findViewById(R.id.collapse_view);
        //The root element of the expanded view layout
        final View expandedView = mFloatingView.findViewById(R.id.expanded_container);

        //Set the close button on floating widget
        ImageView closeButtonCollapsed = (ImageView) mFloatingView.findViewById(R.id.close_btn);
        closeButtonCollapsed.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //close the service and remove the from from the window
                stopSelf();
            }
        });
        //display typed message.
        final TextView displaytext = (TextView) mFloatingView.findViewById(R.id.displaytext);

        // while floating view is expanded.
        //type message.
        final EditText typetext = (EditText) mFloatingView.findViewById(R.id.edittext);
        // Request focus and show soft keyboard automatically



        ImageView senttext = (ImageView ) mFloatingView.findViewById(R.id.sendText);
        senttext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.e("float "," image send click");
               displaytext.setText(typetext.getText().toString());
                displaytext.setVisibility(View.VISIBLE);
            }
        });


        //Set the close button on expanded view
        ImageView closeButton = (ImageView) mFloatingView.findViewById(R.id.close_exp_button);
        closeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                collapsedView.setVisibility(View.VISIBLE);
                expandedView.setVisibility(View.GONE);
            }
        });


        //Open the application on open button click on expanded view
        ImageView openButton = (ImageView) mFloatingView.findViewById(R.id.open_exp_button);
        openButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // open main activity
                Intent intent = new Intent(FloatingService.this, MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);


                //close the service and remove view from the view hierarchy
                stopSelf();
            }
        });

        //Drag and move floating view using user's touch action.
        mFloatingView.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:

                        //remember the initial position.
                        initialX = params.x;
                        initialY = params.y;

                        //get the touch location
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        int Xdiff = (int) (event.getRawX() - initialTouchX);
                        int Ydiff = (int) (event.getRawY() - initialTouchY);


                        //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little while clicking.
                        //So that is click event.
                        if (Xdiff < 10 && Ydiff < 10) {
                            if (isViewCollapsed()) {
                                //When user clicks on the image view of the collapsed layout,
                                //visibility of the collapsed layout will be changed to "View.GONE"
                                //and expanded view will become visible.
                                collapsedView.setVisibility(View.GONE);
                                expandedView.setVisibility(View.VISIBLE);
                                typetext.requestFocus();

                                // attach keypad with edittext
                                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                                imm.showSoftInput(typetext, InputMethodManager.SHOW_IMPLICIT);

                            }
                        }
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        //Calculate the X and Y coordinates of the view.
                        params.x = initialX + (int) (event.getRawX() - initialTouchX);
                        params.y = initialY + (int) (event.getRawY() - initialTouchY);


                        //Update the layout with new X & Y coordinate
                        mWindowManager.updateViewLayout(mFloatingView, params);
                        return true;
                }
                return false;
            }
        });
    }


    /**
     * Detect if the floating view is collapsed or expanded.
     *
     * @return true if the floating view is collapsed.
     */
    private boolean isViewCollapsed() {
        return mFloatingView == null || mFloatingView.findViewById(R.id.collapse_view).getVisibility() == View.VISIBLE;
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mFloatingView != null) mWindowManager.removeView(mFloatingView);
    }
}

 

Add Permission in AndroidManifest.xml

The last step of this project is adding floating view by starting the FloatingViewService. First you have to define permission on AndroidManifest.xml file
android.permission.SYSTEM_ALERT_WINDOW permission. For android version <= API22, this permission is granted by default. But for the android versions running API > 22, we need to check for the permission runtime. Also define FloatingServer.java file as service in manifest file.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="blueappsoftware.floatingwidget">

    <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=".FloatingService"
            android:enabled="true"
            android:exported="false"/>

    </application>

</manifest>

Add Run time Permission

package blueappsoftware.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.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int CODE_PERMISSION = 2084;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Check if the application has draw over other apps permission or not?
        //This permission is by default available for API<23. But for API > 23
        //you have to ask for the permission in runtime.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {


            //If the draw over permission is not available open the settings screen
            //to grant the permission.
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, CODE_PERMISSION);
        } else {
            initializeView();
        }
    }

    /**
     * Set and initialize the view elements.
     */
    private void initializeView() {
        findViewById(R.id.notify_me).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startService(new Intent(MainActivity.this, FloatingService.class));
                finish();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CODE_PERMISSION) {
            //Check if the permission is granted or not.
            if (resultCode == RESULT_OK) {
                initializeView();
            } else { //Permission is not available
                Toast.makeText(this,
                        "Draw over other app permission not available. Closing the application",
                        Toast.LENGTH_SHORT).show();

                finish();
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }
}

 

Run Code

Now run this code in real device. Your floating icon is ready to use. If you have any problem on execution of code, leave comment below.

Do you know how to create parallax animation on android? if no, read my this post

You can learn android App development with me in 50 Days. I am going to start online course where I will teach you both Basic and Advance Android App Development.

50 day android course

 

Posted in andorid.

I Am Post Graduation (M.Tech. C.S.E) from VNIT, Nagpur. I Have Published Two Research Paper On International Journal. My Apps on Google Play Store- Sanyukt Parivar(Mp Police ), NOTOtag- Digital Chhindwara, The Tubby-VoiceRecognizer & More.
Contact me at kamal.bunkar@blueappsoftware.in

33 Comments

  1. I love your blog.. very nice colors & theme. Did you create this
    website yourself or did you hire someone to do it for you?
    Plz respond as I’m looking to create my own blog and would like to find
    out where u got this from. appreciate it

  2. Pretty great post. I just stumbled upon your weblog and wanted to say
    that I’ve truly loved browsing your blog posts.
    In any case I’ll be subscribing for your feed and I hope you write once more very soon!

  3. Hi there! This post could not be written any better!
    Reading through this post reminds me of my good old room mate!
    He always kept talking about this. I will forward this article to him.
    Fairly certain he will have a good read. Thank you for sharing!

  4. Hi there! Quick question that’s totally off topic.
    Do you know how to make your site mobile friendly?
    My weblog looks weird when browsing from my iphone4.
    I’m trying to find a template or plugin that might
    be able to fix this issue. If you have any recommendations, please share.
    Thank you!

  5. This is really attention-grabbing, You are an overly skilled blogger.
    I have joined your feed and look forward to in the hunt
    for extra of your great post. Also, I have shared your site in my social networks

  6. I’m really enjoying the theme/design of your blog.

    Do you ever run into any browser compatibility issues?

    A few of my blog audience have complained about my site not
    working correctly in Explorer but looks great in Chrome.
    Do you have any solutions to help fix this issue?

  7. I was recommended this web site by my cousin. I’m
    not sure whether this post is written by him as no one else
    know such detailed about my problem. You are wonderful!

    Thanks!

  8. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates.
    I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this.
    Please let me know if you run into anything. I truly enjoy reading your
    blog and I look forward to your new updates.

  9. Having read this I thought it was very informative. I appreciate you finding the time and
    energy to put this short article together. I once again find myself personally spending a lot of time both reading and posting comments.
    But so what, it was still worthwhile!

  10. hi! may i know is your code complete? because i run the program and does nothing, i have download the given source code.

    • Yes this code is working…You have to create file on php server to store FCM key into your database for future use. First check on your android studio log whether FCM token is printing OR not. If it is printing in log than send token to your web server.

  11. Good day! I could have sworn I’ve been to
    this website before but after going through
    a few of the articles I realized it’s new to me.

    Nonetheless, I’m certainly delighted I found it and I’ll be book-marking it and checking back regularly!

  12. Spot on with this write-up, I absolutely feel this website needs much more attention. I’ll probably be returning to read
    through more, thanks for the info!

  13. Hey very cool website!! Man .. Excellent ..
    Amazing .. I will bookmark your site and take the feeds additionally?
    I am glad to search out numerous useful info here
    in the submit, we need work out more strategies
    on this regard, thanks for sharing. . . . . .

  14. Pingback: ExoPlayer Android Example- Best Alternative of VideoView By Kamal

  15. Pingback: Simplest way to get WordPress Post in Android App- REST API

  16. I just like the helpful information you supply to your articles.

    I’ll bookmark your blog and test once more here frequently.
    I’m fairly sure I will learn many new stuff proper here!
    Good luck for the following!

Comments are closed.