Inflate Floating Action Button from android.support.design.widget.FloatingActionButton
android, android-studio, java, layout-inflater, material-design
Solution
It seems that the theme is set in activities but not in services. To programmatically specify one, add this in the service's `onCreate` method.
setTheme(R.style.AppTheme);
It will fix your specific error but the app will not run as-is.
1.
I had to change
`windowManager.addView(fab, params);` to `windowManager.addView(layout, params);`
2.
The app will not run with the `targetSdkVersion` set at 23 or higher. (set `targetSdkVersion 22` in your `build.gradle` file) This answer will maybe help
A few notes:
1.
You are not using the style you declared in `styles.xml`
In `AndroidManifest.xml`, you need to change `android:theme="@style/Theme.AppCompat"` to `android:theme="@style/AppTheme"`
Setting it only to `<Application>` will apply it to all the activities.
2.
In your `AndroidManifest.xml`, the line
`<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="18" />`
can be removed since this information is already specified in the `build.gradle` file.
Problem
(Project overview part) I would like to do flying button which is over all the other apps and system icons. Once you press it, kind of menu pops up where you have several options to choose from. Once you press and move the button, you can move it to any place on a screen. So far, I have both flying button on a screen (actually flying bmp file) in one project and floating button with popping up menu in second project. What I want to do now is to replace bmp file with real floating button with menu. The way I'm trying to do that: (The most important starts here) :) I add flying button to windowManager by addView method. Flyingbutton is an View object. This is the point where I came a cropper. I was trying to carry out how to find view by id in Service class and I did that by inflating android.support.design.widget.FloatingActionButton class but now I see the inflate method doesn't go well with that class. I saw few threads on Stack Overflow but none of them helped me. Any idea? Perhaps you will see that the background so far is not transparent but this not the problem at this moment. :) 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> ``` gradle apply plugin: 'com.android.application' android { compileSdkVersion 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' } ```