Java – Inflated float action buttons from android.support.design.widget.FloatingActionButton

Inflated float action buttons from android.support.design.widget.FloatingActionButton… here is a solution to the problem.

Inflated float action buttons from android.support.design.widget.FloatingActionButton

(Project Overview section).

I want to make a fly button on all other apps and system icons. Once you press it, a menu will pop up from which you can select multiple options. After pressing and moving the button, you can move it anywhere on the screen.

So far, I have an on-screen fly button (actually a flying bmp file) in one project and a float button with a pop-up menu in the second.

What I’m going to do now is replace the bmp file with a real float button with a menu.

The way I tried to do this :

(The most important thing starts here) 🙂

I added the fly button to the windowManager via the addView method. The flyingbutton is a View object. That’s where I came to the harvester.

I’m trying to do how to find a View by id in a service class, and I’m doing this by inflating the android.support.design.widget.FloatingActionButton class
But now I find that the inflate method does not work for the class.

I’ve seen very few posts on Stack Overflow, but none of them have helped me.

Any ideas?

Maybe you’ll find that the background isn’t transparent so far, but that’s not the current problem. 🙂

logcat says….

FATAL EXCEPTION: main

Process: com.example.komp.floatingbuttonpowtorka, PID: 32452

java.lang.RuntimeException: Unable to create service com.example.komp.floatingbuttonpowtorka.FlyingButton: android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2780)
    at android.app.ActivityThread.access$1800(ActivityThread.java:151)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424)
    at android.os.Handler.dispatchMessage(Handler.java:110)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:5333)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>
    at android.view.LayoutInflater.createView(LayoutInflater.java:620)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
    at com.example.komp.floatingbuttonpowtorka.FlyingButton.onCreate(FlyingButton.java:63)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2770)
    at android.app.ActivityThread.access$1800(ActivityThread.java:151) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424) 
    at android.os.Handler.dispatchMessage(Handler.java:110) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.app.ActivityThread.main(ActivityThread.java:5333) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.constructNative(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at android.view.LayoutInflater.createView(LayoutInflater.java:594)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696) 
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:755) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
    at com.example.komp.floatingbuttonpowtorka.FlyingButton.onCreate(FlyingButton.java:63) 
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2770) 
    at android.app.ActivityThread.access$1800(ActivityThread.java:151) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424) 
    at android.os.Handler.dispatchMessage(Handler.java:110) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.app.ActivityThread.main(ActivityThread.java:5333) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.IllegalArgumentException: You need to use a Theme.AppCompat theme (or descendant) with the design library.
    at android.support.design.widget.ThemeUtils.checkAppCompatTheme(ThemeUtils.java:34)
    at android.support.design.widget.FloatingActionButton.<init>(FloatingActionButton.java:110)
    at android.support.design.widget.FloatingActionButton.<init>(FloatingActionButton.java:104)
    at java.lang.reflect.Constructor.constructNative(Native Method) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
    at android.view.LayoutInflater.createView(LayoutInflater.java:594) 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696) 
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:755) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:353) 
    at com.example.komp.floatingbuttonpowtorka.FlyingButton.onCreate(FlyingButton.java:63) 
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2770) 
    at android.app.ActivityThread.access$1800(ActivityThread.java:151) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424) 
    at android.os.Handler.dispatchMessage(Handler.java:110) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.app.ActivityThread.main(ActivityThread.java:5333) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644) 
    at dalvik.system.NativeStart.main(Native Method)

MainActivity.java

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

startService(new Intent(MainActivity.this, FlyingButton.class));
        finish();
}

@Override
protected void onResume() {
    Bundle bundle = getIntent().getExtras();

if(bundle != null && bundle.getString("LAUNCH").equals("YES")) {
        startService(new Intent(MainActivity.this, FlyingButton.class));
    }
    super.onResume();
}
}

FlyingButton.java

public class FlyingButton extends Service {

private WindowManager windowManager;
private ImageView chatHead;

@Override
public IBinder onBind(Intent intent) {
     TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

chatHead = new ImageView(this);

chatHead.setImageResource(R.drawable.floating);

LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    View layout = inflater.inflate(R.layout.activity_main, null);

FloatingActionButton fab = (FloatingActionButton) layout.findViewById(R.id.fab);

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;

windowManager.addView(fab, params);

try {
        chatHead.setOnTouchListener(new View.OnTouchListener() {
            private WindowManager.LayoutParams paramsF = params;
            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:

 Get current time in nano seconds.

initialX = paramsF.x;
                        initialY = paramsF.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                    case MotionEvent.ACTION_MOVE:
                        paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
                        paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(chatHead, paramsF);
                        break;
                }
                return false;
            }
        });
    } catch (Exception e) {
         TODO: handle exception
    }

}

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

}

activity_main.xml

 <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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=". MainActivity">

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="16dp"
    android:src="@drawable/filter"
    app:backgroundTint="@color/colorAccent"
    xmlns:android="http://schemas.android.com/apk/res/android" />
</RelativeLayout>

styles.xml

<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

androidmanifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.komp.floatingbuttonpowtorka"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat" >

<activity
    android:name=". MainActivity"
    android:label="@string/app_name"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.AppCompat">
    <application android:name=". ApplicationContextProvider"
        android:label="@string/app_name"/>
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<service
    android:name="com.example.komp.floatingbuttonpowtorka.FlyingButton"
    android:exported="true" />
</application>

</manifest>

Gradients
Application plugin: ‘com.android.application’

Android {
Compile SDK version 23
buildToolsVersion “23.0.3”

defaultConfig {
    applicationId "com.example.komp.floatingbuttonpowtorka"
    minSdkVersion 15
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
}

Solution

It is as if the theme is set in the activity, not in the service.
To specify one programmatically, add it to the onCreate method of the service.

setTheme(R.style.AppTheme);

It will fix your specific error, but the app will not work as is.

1.

I had to change

windowManager.addView(fab, params); to windowManager.addView(layout, params);

2.

The application will not run with targetSdkVersion set to 23 or higher.
(Set build.gradle in your targetSdkVersion 22 file) This answer will maybe help


Some notes:

1.

You are not using the style declared in styles.xml

In the AndroidManifest .xml, you need to change android:theme=”@style/Theme.AppCompat" to android:theme="@style/AppTheme"

Set it only to <Application> apply it to all activities.

2.

In your AndroidManifest .xml, line

<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="18" />

It can be removed because this information is already specified in the file in build.gradle.

Related Problems and Solutions