37

I am trying to create a custom button with two text fields. When I create an instance from code, it works. When I try and inflate from XML it crashes.

What I've done so far to try and resolve this issue:

  • Followed and understood the LabelView code sample in the SDK.
  • Followed and understood this excellent Devoxx custom FlowLayout presentation.
  • Followed and understood numerous tutorials on the subject.
  • Spent hours reviewing similar questions on stackoverflow.
  • Stripped the code back to the basics of simply passing the attribute set on up to the super class.

From the questions I've read, the most common cause is not defining the required constructor which takes the attribute set i.e.

MyClass(Context context, AttributeSet attrs) {
    super(context, attrs);
}

Near the end of the list of errors in LogCat I have:

Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]

This might lead to the conclusion that I've made the same mistake as many others, but when you look at my code below you can see that I have defined the constructor of this form.

I seem to be doing exactly as all the sources say. I just cant see what I'm missing.

src/com.soundconception.custombuttontest2/TitledValueButton.java

package com.soundconception.custombuttontest2;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.Button;

public class TitledValueButton extends Button {

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

    protected TitledValueButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="TitledValueButton">
        <attr name="titleText" format="string" />
    </declare-styleable>

</resources>

res/layout/activity_main.xml

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.soundconception.custombuttontest2"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

        <com.soundconception.custombuttontest2.TitledValueButton 
            android:id="@+id/test_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1..2..3.."
            app:titleText="Testing" />

</RelativeLayout>

src/com.soundconception.custombuttontest2/MainActivity.java

package com.soundconception.custombuttontest2;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

LogCat

threadid=1: thread exiting with uncaught exception (group=0x41a5a700)
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.soundconception.custombuttontest2/com.soundconception.custombuttontest2.MainActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class com.soundconception.custombuttontest2.TitledValueButton
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class com.soundconception.custombuttontest2.TitledValueButton
at android.view.LayoutInflater.createView(LayoutInflater.java:603)
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.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:267)
at android.app.Activity.setContentView(Activity.java:1895)
at com.soundconception.custombuttontest2.MainActivity.onCreate(MainActivity.java:12)
at android.app.Activity.performCreate(Activity.java:5133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
... 11 more
Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
at java.lang.Class.getConstructorOrMethod(Class.java:423)
at java.lang.Class.getConstructor(Class.java:397)
at android.view.LayoutInflater.createView(LayoutInflater.java:568)
... 22 more
Sound Conception
  • 5,263
  • 5
  • 30
  • 47

3 Answers3

52

This constructor is missing:

public TitledValueButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }

Add this constructor to your custom button class.

Grace Huang
  • 5,355
  • 5
  • 30
  • 52
Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77
30

One more constructor is missing. Add this for remove the crash.

Remember constructor must be in public mode.

public TitledValueButton(Context context, AttributeSet attrs) {

    super(context, attrs); // This should be first line of constructor 
}

and

public TitledValueButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

}

Remember constructor must be in public mode.

Lavekush Agrawal
  • 6,040
  • 7
  • 52
  • 85
5

I had the same error message when trying to to declare a non-static inner class in my layout (using the dollar-sign). Simply adding the static keywoard to my class made it work.

domenukk
  • 953
  • 15
  • 28