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>
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.
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.
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.
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.