Nano Hash - криптовалюты, майнинг, программирование

Раздувание плавающей кнопки действия из android.support.design.widget.FloatingActionButton

(Часть обзора проекта)

Я хотел бы сделать летающую кнопку над всеми другими приложениями и системными значками. Как только вы нажмете ее, появится всплывающее меню, в котором у вас есть несколько вариантов на выбор. Как только вы нажмете и переместите кнопку, вы можете переместить ее в любое место на экране.

Пока у меня есть как летающая кнопка на экране (на самом деле летающий файл bmp) в одном проекте, так и плавающая кнопка с всплывающим меню во втором проекте.

Что я хочу сделать сейчас, так это заменить файл bmp настоящей плавающей кнопкой с меню.

Как я пытаюсь это сделать:

(Самое важное начинается здесь) :)

Я добавляю летающую кнопку в windowManager методом addView. Flyingbutton — это объект View. Это тот момент, когда я попал в аварию.

Я пытался выяснить, как найти представление по идентификатору в классе службы, и я сделал это, раздув класс android.support.design.widget.FloatingActionButton, но теперь я вижу, что метод раздувания не подходит для этого класса.

Я видел несколько тем на Stack Overflow, но ни одна из них мне не помогла.

Есть идеи?

Возможно, вы увидите, что фон пока не прозрачен, но сейчас это не проблема. :)

logcat говорит...

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 применить плагин: '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'
}


Ответы:


1

Кажется, что тема задана в действиях, а не в услугах. Чтобы указать его программно, добавьте его в метод службы onCreate.

setTheme(R.style.AppTheme);

Это исправит вашу конкретную ошибку, но приложение не будет работать как есть.

1.

я должен был изменить

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

2.

Приложение не будет работать с targetSdkVersion, установленным на 23 или выше. (установите targetSdkVersion 22 в файле build.gradle) Этот ответ может помочь


Несколько заметок:

1.

Вы не используете стиль, объявленный в styles.xml

В AndroidManifest.xml вам нужно изменить android:theme="@style/Theme.AppCompat" на android:theme="@style/AppTheme"

Установка только <Application> применит его ко всем действиям.

2.

В вашем AndroidManifest.xml строка

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

можно удалить, так как эта информация уже указана в файле build.gradle.

30.10.2016
  • Это не сработало. Вот что у меня есть в 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> </resources> 31.10.2016
  • в настоящее время работает! Большое спасибо! :) Теперь мне интересно, почему я получаю маржу. Если я перемещаю кнопку к любому краю экрана, между краем и кнопкой остается довольно много места. Кнопка никогда не касается края. Я установил android:layout_margin=0dp, и у меня еще осталось место. 31.10.2016
  • Я нашел миллион разных ответов на эту ошибку, но помог только этот. Спасибо! 05.01.2018
  • Я хочу сказать то же, что и @GabeO'Leary, только это решит мою проблему. 19.03.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..