【问题标题】:Crash when i use custom view in android当我在android中使用自定义视图时崩溃
【发布时间】:2020-07-18 14:11:36
【问题描述】:

我在使用自定义视图时遇到问题,当我创建自定义视图时我的应用程序崩溃了,当我看到日志时 我在使用自定义视图的 XML 文件中查看错误,但无法解决问题。 当我想使用 xmlns:custom="http://schemas.android.com/apk/com.zeroone.customview2" 发生错误,Android Studio 显示此消息: 在 Gradle 项目中,始终使用 http://schemas.android.com/apk/res-auto 来自定义属性

我不知道我的问题是什么,如果你知道请帮助我

这是 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.zeroone.customview2.CustomView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        custom:rect_color="#BC7C33"
        custom:text_color="#0AD6C2"
        custom:mText="@string/app_name"/>

</RelativeLayout>

这是 attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomView">
        <attr name="rect_color" format="color"/>
        <attr name="text_color" format="color"/>
        <attr name="mText" format="string"/>
        <attr name="image" format="reference"/>
        <attr name="text_size" format="dimension"/>
        <attr name="padding" format="dimension"/>
    </declare-styleable>
</resources>

这是 CustomView.kt


import android.content.Context
import android.content.res.Resources
import android.content.res.TypedArray
import android.graphics.*
import android.util.AttributeSet
import android.view.View

class CustomView(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) :
    View(context, attrs, defStyleAttr) {

    private var mColor: Int = Color.GREEN
    private var mColorText: Int = Color.RED
    private var image  = R.drawable.ic_launcher_background
    private var padding = 0f
        set(value) {
            field = value
            invalidate()
        }
    private var mText = "Hello"

    init {
        val a: TypedArray =
            context!!.obtainStyledAttributes(attrs, R.styleable.CustomView, defStyleAttr, 0)
        try {
            mColor = a.getColor(R.styleable.CustomView_rect_color, Color.BLUE)
            mColorText = a.getColor(R.styleable.CustomView_text_color, Color.WHITE)
            mText = a.getString(R.styleable.CustomView_mText)!!
            image = a.getResourceId(R.styleable.CustomView_image , R.drawable.ic_launcher_background)
            padding = a.getDimension(R.styleable.CustomView_padding, 0f)
        } finally {
            a.recycle()
        }
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)



        val paint = Paint().apply {
            isAntiAlias = true
            color = mColor
            style = Paint.Style.FILL
            textSize = dp2f(15f)
            textAlign = Paint.Align.CENTER
        }
        val paint2 = Paint().apply {
            isAntiAlias = true
            color = Color.RED
            style = Paint.Style.FILL
        }
        val rectF = RectF().apply {
            left = 30f
            top = 30f
            right = 30f
            bottom = 30f
        }
        val bitmap = BitmapFactory.decodeResource(null , image)

        val viewWidthHalf = this.measuredWidth / 2
        val viewHeightHalf = this.measuredHeight / 2
        var radius = 0
        radius = if (viewWidthHalf > viewHeightHalf) viewHeightHalf - 10 else viewWidthHalf - 10
        canvas!!.drawCircle(
            viewWidthHalf.toFloat(),
            viewHeightHalf.toFloat(),
            radius.toFloat(),
            paint
        );
        paint.color = mColorText
        canvas.drawText(mText, viewWidthHalf.toFloat(), viewHeightHalf.toFloat(), paint);
    }

    fun dp2f(flaot: Float): Float {
        return Resources.getSystem().displayMetrics.density * flaot
    }
}

这是日志

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.zeroone.customview2, PID: 24583
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.zeroone.customview2/com.zeroone.customview2.MainActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class com.zeroone.customview2.CustomView
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2551)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2625)
        at android.app.ActivityThread.access$700(ActivityThread.java:183)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1484)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:194)
        at android.app.ActivityThread.main(ActivityThread.java:5667)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:962)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
     Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class com.zeroone.customview2.CustomView
        at android.view.LayoutInflater.createView(LayoutInflater.java:616)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161)
        at com.zeroone.customview2.MainActivity.onCreate(MainActivity.kt:9)
        at android.app.Activity.performCreate(Activity.java:6147)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2498)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2625) 
        at android.app.ActivityThread.access$700(ActivityThread.java:183) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1484) 
        at android.os.Handler.dispatchMessage(Handler.java:111) 
        at android.os.Looper.loop(Looper.java:194) 
        at android.app.ActivityThread.main(ActivityThread.java:5667) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:372) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:962) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
     Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
        at java.lang.Class.getConstructor(Class.java:531)
        at java.lang.Class.getConstructor(Class.java:495)
        at android.view.LayoutInflater.createView(LayoutInflater.java:580)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:365) 
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555) 
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161) 
        at com.zeroone.customview2.MainActivity.onCreate(MainActivity.kt:9) 
        at android.app.Activity.performCreate(Activity.java:6147) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2498) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2625) 
        at android.app.ActivityThread.access$700(ActivityThread.java:183) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1484) 
        at android.os.Handler.dispatchMessage(Handler.java:111) 
        at android.os.Looper.loop(Looper.java:194) 
        at android.app.ActivityThread.main(ActivityThread.java:5667) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:372) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:962) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 

【问题讨论】:

    标签: java android xml android-layout kotlin


    【解决方案1】:

    尝试使用@JvmOverloads annotation 注释您的主构造函数并为参数添加默认值:

    class CustomView @JvmOverloads constructor(
        context: Context, 
        attrs: AttributeSet? = null, 
        defStyle: Int = 0
    ) : View(context, attrs, defStyle)
    

    您得到该异常的原因可能是CustomView 没有所需的公共构造函数,它接受ContextAttributeSet 参数。

    【讨论】:

      猜你喜欢
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      相关资源
      最近更新 更多