使用自定义视图即时崩溃

时间:2018-02-16 20:54:38

标签: android android-layout android-custom-view

我以前从未使用过自定义视图,所以很可能我做错了。

以下是我的SmartTabLayout课程的Java代码,该代码应根据其所有标签的总组合宽度在MODE_FIXEDMODE_SCROLLABLE之间切换。

import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;

public class SmartTabLayout extends android.support.design.widget.TabLayout {

    public SmartTabLayout(Context context) {
        super(context);
    }

    public SmartTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SmartTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (getTabCount() == 0) return;
        try {
            ViewGroup tabLayout = (ViewGroup)getChildAt(0);
            int combinedWidth = 0;
            for (int i = 0; i < tabLayout.getChildCount(); i++)
                combinedWidth += tabLayout.getChildAt(i).getMeasuredWidth();
            setTabMode(combinedWidth <= getMeasuredWidth() ? MODE_FIXED : MODE_SCROLLABLE);
        } catch (Exception e) {
            // e.printStackTrace();
        }
    }
}

我的布局XML文件包含以下部分:

<SmartTabLayout
    android:id="@+id/tabLayout"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabGravity="fill"
    app:tabMode="scrollable"
    android:layout_gravity="center_horizontal">

    <android.support.design.widget.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Left" />

    <android.support.design.widget.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Center" />

    <android.support.design.widget.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Right" />

</SmartTabLayout>

当我(在我的XML文件中)将SmartTabLayout更改为android.support.design.widget.TabLayout时,一切正常,但没有所需的“智能”功能。所以我假设XML代码很好。但是当我在XML文件中使用SmartTabLayout时,应用程序在启动后立即崩溃。调试器甚至不会调用我的自定义代码的一行。我错过了什么?

日志(如下)包含以下消息:

  

路径上没有找到“android.view.SmartTabLayout”类...

我应该在某处明确指向我的自定义视图类吗?

    02-16 15:56:14.328 24316-24316/? E/Zygote: v2
    02-16 15:56:14.328 24316-24316/? I/libpersona: KNOX_SDCARD checking this for 10327
    02-16 15:56:14.328 24316-24316/? I/libpersona: KNOX_SDCARD not a persona
    02-16 15:56:14.330 24316-24316/? E/Zygote: accessInfo : 0
    02-16 15:56:14.331 24316-24316/? W/SELinux: SELinux selinux_android_compute_policy_index : Policy Index[2],  Con:u:r:zygote:s0 SPD:SEPF_SECMOBILE_7.0_0006 RAM:SEPF_SECMOBILE_7.0_0010, [-1 -1 -9 -1 0 1]
    02-16 15:56:14.332 24316-24316/? I/SELinux: SELinux: seapp_context_lookup: seinfo=untrusted, level=s0:c512,c768, pkgname=com.example.android 
    02-16 15:56:14.339 24316-24316/? I/art: Late-enabling -Xcheck:jni
    02-16 15:56:14.381 24316-24316/? D/TimaKeyStoreProvider: TimaSignature is unavailable
    02-16 15:56:14.381 24316-24316/? D/ActivityThread: Added TimaKeyStore provider
    02-16 15:56:14.406 24316-24316/com.example.android W/ActivityThread: Application com.example.android is waiting for the debugger on port 8100...
    02-16 15:56:14.409 24316-24316/com.example.android I/System.out: Sending WAIT chunk
    02-16 15:56:15.420 24316-24323/com.example.android I/art: Debugger is active
    02-16 15:56:15.611 24316-24316/com.example.android I/System.out: Debugger has connected
    02-16 15:56:15.611 24316-24316/com.example.android I/System.out: waiting for debugger to settle...
    02-16 15:56:15.811 24316-24316/com.example.android I/System.out: waiting for debugger to settle...
    02-16 15:56:16.012 24316-24316/com.example.android I/System.out: waiting for debugger to settle...
    02-16 15:56:16.212 24316-24316/com.example.android I/System.out: waiting for debugger to settle...
    02-16 15:56:16.412 24316-24316/com.example.android I/System.out: waiting for debugger to settle...
    02-16 15:56:16.613 24316-24316/com.example.android I/System.out: waiting for debugger to settle...
    02-16 15:56:16.813 24316-24316/com.example.android I/System.out: waiting for debugger to settle...
    02-16 15:56:17.013 24316-24316/com.example.android I/System.out: debugger has settled (1370)
    02-16 15:56:17.112 24316-24316/com.example.android W/System: ClassLoader referenced unknown path: /data/app/com.example.android-2/lib/arm64
    02-16 15:56:17.129 24316-24316/com.example.android D/ContextRelationMgrBrdg: loadKlass() : caller=com.samsung.android.bridge.multiscreen.common.ContextRelationManagerBridge.<clinit>:28 com.samsung.android.bridge.multiscreen.common.ContextRelationManagerBridge.getInstance:-1 
    02-16 15:56:17.139 24316-24316/com.example.android I/InstantRun: starting instant run server: is main process
    02-16 15:56:17.210 24316-24316/com.example.android W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
    02-16 15:56:17.315 24316-24316/com.example.android D/TextView: setTypeface with style : 0
    02-16 15:56:17.316 24316-24316/com.example.android D/TextView: setTypeface with style : 0
    02-16 15:56:17.348 24316-24316/com.example.android D/AndroidRuntime: Shutting down VM
    02-16 15:56:17.354 24316-24316/com.example.android E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android, PID: 24316
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android/com.example.android.Main}: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class SmartTabLayout
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2947)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3008)
    at android.app.ActivityThread.-wrap14(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6688)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
    Caused by: android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class SmartTabLayout
    Caused by: android.view.InflateException: Binary XML file line #0: Error inflating class SmartTabLayout
    Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.SmartTabLayout" on path: DexPathList[[zip file "/data/app/com.example.android-2/base.apk", zip file "/data/app/com.example.android-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_4_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_5_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_6_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_7_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_8_apk.apk", zip file "/data/app/com.example.android-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.example.android-2/lib/arm64, /system/lib64, /vendor/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at android.view.LayoutInflater.createView(LayoutInflater.java:616)
    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:707)
    at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:68)
    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:724)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:792)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:734)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:865)
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:828)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:525)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:378)
    at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
    at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
    at com.example.android.Main.onCreate(Main.java:52)
    at android.app.Activity.performCreate(Activity.java:6912)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2900)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3008)
    at android.app.ActivityThread.-wrap14(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6688)
    at java.lang.reflect.Method.invoke(Native Method)02-16 15:56:17.355 24316-24316/com.example.android E/AndroidRuntime:
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

3 个答案:

答案 0 :(得分:0)

日志指向

java.lang.ClassNotFoundException: Didn't find class "android.view.SmartTabLayout" 

错误,请尝试将布局更改为

<<package_name>.SmartTabLayout
    android:id="@+id/tabLayout"

.../>

答案 1 :(得分:0)

正如我们许多人所想的那样,将<SmartTabLayout>更改为<com.example.android.SmartTabLayout>会成为一种伎俩。

但这还不足以让它发挥作用。我不得不补充道:

package com.example.android;

在我的SmartTabLayout类文件的开头。现在它可以工作,但它会显示警告

  

包名'com.example.android'与该文件不对应   路径''

所以我必须将我的Java类源代码从...\java目录移动到...\java\com.example.android文件夹,现在它可以在没有警告的情况下运行。

文件的移动是有道理的,因为我添加了package com.example.android;

但为什么我必须将此自定义视图作为我的包的一部分才能使其正常工作?甚至不应该在包装外工作?奇怪的。但正如我写的那样,这是我第一次体验自定义视图,所以我学到了一些东西。

希望它能帮助遇到同样问题的其他人。

答案 2 :(得分:-2)

尝试对前两个构造函数的超级调用进行以下更改:

public SmartTabLayout(Context context) {
        super(context, null);
    }

    public SmartTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
    }

    public SmartTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }