I have a ListView populated from a custom adapter. Each row has 1 button in it. In the xml the button has the onClick attribute passed. I have only the xml, not any OnClickListeners set. Also note that the public void myMethod (View v) exists in my CustomActivity. I get the following exception
10-02 03:01:46.463: E/AndroidRuntime(26857): java.lang.IllegalStateException: Could not find a method myClickHandler(View) in the activity class **android.app.Application** for onClick handler on view class android.widget.Button with id 'myButton'
Method in Activity:
public void myClickHandler(View v) {
... do stuff here...
}
Button XML:
<Button
android:id="@+id/myButton"
android:layout_width="44dp"
android:layout_height="44dp"
android:background="@drawable/eye_icon"
android:onClick="myClickHandler"
/>
One Interesting note in the Exception is that the app tries to find the method in android.app.Application and not in my custom Activity.
Any suggestions?
It’s important that MyActivity
and getContext()
of CustomAdapter
must be the same instance. Compare yours with mine.
My codes:
MyActivity.java
public class MyActivity extends Activity {
public static final String TAG = "MyActivity";
private ListView mListView;
private CustomAdapter mAdapter;
private ArrayList<String> mData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
mListView = (ListView) findViewById(R.id.listView);
mData = new ArrayList<String>();
mData.add("111");
mData.add("222");
mData.add("333");
mData.add("444");
mData.add("555");
mAdapter = new CustomAdapter(this, R.layout.list_item_view, mData);
mListView.setAdapter(mAdapter);
}
public void onClickHandler(View view) {
Log.i(TAG, "onClickHandler()");
}
}
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<String> {
public CustomAdapter(Context context, int resource, ArrayList<String> objects) {
super(context, resource, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item_view, null);
}
return convertView;
}
}
activity_my.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MyActivity">
<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
list_item_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:id="@+id/button"
android:onClick="onClickHandler"/>
</LinearLayout>
When creating the custom Adapter
, I was passing as the Context
the result of the getApplicationContext()
method. This was wrong. I should pass this
(my custom Activity
) as the Context
. It works like a charm now.
I'm assuming you wrote a custom adapter for this view so in your adapter when you call getView simply findElementById on the button and set the onClickListener there.
This is one example of why the onClick
attribute is considered broken. It is probably best to create a custom Adapter and in the getView()
method, set the OnClickListener
manually.