Создание собственного класса FrameLayout не работает - PullRequest
2 голосов
/ 07 октября 2019

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

Я запускал один и тот же код с обычным FrameLayout, и у меня не было сбоев,Таким образом, приложение вылетает не по другой причине.

Класс FrameLayout:

package com.example.motivationsappbetter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.MotionEvent;
import android.widget.FrameLayout;

public class MainFrameLayout extends FrameLayout {
    private boolean canTouch = true;

    public MainFrameLayout(@NonNull Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (canTouch) 
            return super.onInterceptTouchEvent(ev);
        else 
            return true;
    }

    public void setCanTouch(boolean b){
        canTouch = b;
    }
}

MainActivity:

public class MainActivity extends AppCompatActivity {

    MainFrameLayout mainFrame;

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


        mainFrame = findViewById(R.id.main_frame);
        mainFrame.getForeground().setAlpha(0);
    }
}

Файл Activity_main.xml:

<?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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.motivationsappbetter.MainFrameLayout
        android:id="@+id/main_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <include
            layout="@layout/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <FrameLayout
            android:id="@+id/frameLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="56dp"
            android:layout_marginBottom="56dp">

        </FrameLayout>

        <android.support.design.widget.BottomNavigationView
            android:id="@+id/navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="?android:attr/windowBackground"
            app:labelVisibilityMode="unlabeled"
            app:menu="@menu/navigation"
            tools:layout_editor_absoluteY="675dp">

        </android.support.design.widget.BottomNavigationView>

    </com.example.motivationsappbetter.MainFrameLayout>

    <io.github.yavski.fabspeeddial.FabSpeedDial
        android:id="@+id/fabspeeddial"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="false"
        android:layout_alignParentBottom="false"
        android:layout_gravity="bottom|center"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="3dp"
        app:elevation="10dp"
        app:fabGravity="bottom_end"
        app:fabMenu="@menu/fab_menu"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"></io.github.yavski.fabspeeddial.FabSpeedDial>


</android.support.constraint.ConstraintLayout>

Это сообщение об ошибке:

2019-10-07 16:20:11.624 25601-25601/com.example.motivationsappbetter E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.motivationsappbetter, PID: 25601
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.motivationsappbetter/com.example.motivationsappbetter.MainActivity}: android.view.InflateException: Binary XML file line #11: Binary XML file line #11: Error inflating class com.example.motivationsappbetter.MainFrameLayout
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2793)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2864)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6523)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
     Caused by: android.view.InflateException: Binary XML file line #11: Binary XML file line #11: Error inflating class com.example.motivationsappbetter.MainFrameLayout
     Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class com.example.motivationsappbetter.MainFrameLayout
     Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
        at java.lang.Class.getConstructor0(Class.java:2204)
        at java.lang.Class.getConstructor(Class.java:1683)
        at android.view.LayoutInflater.createView(LayoutInflater.java:625)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:798)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:738)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:869)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:832)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
        at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
        at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
        at com.example.motivationsappbetter.MainActivity.onCreate(MainActivity.java:59)
        at android.app.Activity.performCreate(Activity.java:6915)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2746)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2864)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6523)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

Я буду рад за полезные ответы: P

PS: Извините за мой плохой английский

Ответы [ 2 ]

2 голосов
/ 07 октября 2019

В пользовательском представлении должен быть хотя бы один из обязательных общедоступных конструкторов, который принимает аргументы Context, AttributeSet:

public class MainFrameLayout extends FrameLayout {
    private boolean canTouch = true;

    public MainFrameLayout(@NonNull Context context) {
        super(context);
    }

    public MainFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MainFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MainFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (canTouch)
            return super.onInterceptTouchEvent(ev);
        else
            return true;
    }


    public void setCanTouch(boolean b) {
        canTouch = b;
    }
}
1 голос
/ 07 октября 2019

Исключение дает вам ответ в поле «Причина». В нем говорится, что метод не найден для конструктора, который принимает Context и AttrubuteSet.

Причина: java.lang.NoSuchMethodException: [класс android.content.Context, интерфейс android.util.AttributeSet]

Android использует разные конструкторы для разных версий -при создании пользовательских классов представления вам необходимо включить переопределения для всех из них:

public FrameLayout(@NonNull Context context) {...}

public FrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {...}

public FrameLayout(@NonNull Context context, @Nullable AttributeSet attrs,
        @AttrRes int defStyleAttr) {...}

public FrameLayout(@NonNull Context context, @Nullable AttributeSet attrs,
        @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {...}

Таким образом, ваш код будет работать на всех версиях Android и выбрать правильный конструктор для этой версии.


См. Завершенный класс, который показывает все обязательные методы, переопределенные в ответе mohammadReza Abiri's ответ

...