Sound Conception Sound Conception - 1 month ago 8
Android Question

Error inflating custom button class. NoSuchMethodException

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

Answer

This constructor is missing:

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

    }

Add this constructor to your custom button class.