Reputation: 433
i am populating a set of custom_rows
into my listview
from baseadapter
.
And i set the listview in my fragment.
I am trying to set android:onClick="openComment
to the button which is in my custom_row.xml
but the i get the below error
java.lang.IllegalStateException: Could not find method openComment(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatImageView with id 'open'
In my Fragment i have the method openComment. How do i call the the method from the button click. This is Fragment shows how i call the method.
public class Home extends android.support.v4.app.Fragment implements View.OnClickListener {
....
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myview = inflater.inflate(R.layout.home, container,false);
listView = (ListView) myview.findViewById(R.id.activity_main);
return myview;
}
....
....
public void openComment(View v)
{
//getting the position of clicked row
final int position = listView.getPositionForView((View) v.getParent());
System.out,print("button clicked");
}
my custom_row.xml
looks like this. it has a textview and a button
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/open"
android:onClick="openComment"
android:layout_width="45dp"
android:layout_height="45dp"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Below is my ListView activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@+id/custom_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
Upvotes: 1
Views: 3330
Reputation: 1011
I came across this and even though it’s been over a year since @Kingfisher Phuoc gave the correct answer, I’d like to share my view as well.
However, I dont think it's a good idea to solve this way.
I couldn’t agree more. It isn’t the best practice to write the logic of a button that’s inside a fragment inside the activity containing the fragment rather than the fragment itself. It’s against the Single responsibility principle and it’s a shame that Google designed Android in a way that it prevents developers to make use of best practices.
So how I do it:
Check out JakeWharton’s ButterKnife library. With this you can bind the views.
So in your activity class’ onCreate you do:
// Bind your views here using @BindView(R.id.someview) MyView myView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
and bind the views it contains. Just like that inside the fragment class’ onCreateView you do:
// Bind your views here using @BindView(R.id.someview) MyView myView;
@BindView(R.id.custom_list)
ListView listView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main, container, false);
// Make sure you unbind too as fragments work differently than activities, check the documentation on how.
ButterKnife.bind(this, view);
return view;
}
Check out the documentation and you can even find code to simplify your BaseAdapter implementation to connect openComment to OnClick properly rather than defining it in XML.
Upvotes: 1
Reputation: 8200
Actually, you must declare your openComment(View v)
function inside your host activity
instead of your fragment
. You can declare the function inside your activity
as below:
public void openComment(View v){
yourFragment.openComment(v);
}
However, I dont think it's a good idea to solve this way. You should implement onClickListener
inside your adapter or your fragment.
Upvotes: 3
Reputation: 17142
You can do this:
private ListView listView;
private View myview;
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myview = inflater.inflate(R.layout.home, container,false);
listView = (ListView) myview.findViewById(R.id.activity_main);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Use the position argument
if(view.getId() == R.id.open)
System.out.print("button clicked");
}
});
return myview;
}
And you won't need that :onClick
attribute in your XML layout.
Upvotes: 0
Reputation: 2858
call it from BaseAdapter. like
Button btn_opencomment=(Button)yourview.findViewById(R.id.open);
btn_opencomment.setOnClickListener(new View.OnClickListener() {
@override
public void onClick(View v)
{
//getting the position of clicked row
final int position = listView.getPositionForView((View)
v.getParent());
System.out,print("button clicked");
//this is your method.what ever you have to do onclick of item.write here..
});
return yourview;
}
Upvotes: 0