我想创建一个自己的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:对不起,我的英语不好
答案 0 :(得分:2)
自定义视图必须具有采用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 :(得分:1)
该异常为您提供了“原因”中的答案。它说没有为采用Context
和AttrubuteSet
的构造函数找到该方法。
原因:java.lang.NoSuchMethodException:[class 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 answer
中给定的所有必需方法