Android使用onClick错误调用片段上的方法

时间:2015-11-17 08:08:05

标签: java android xml listview android-fragments

我正在从custom_rows填充一组listview到我的baseadapter。 我在我的片段中设置了listview。 我正在尝试将android:onClick="openComment设置为我custom_row.xml中的按钮,但我得到以下错误

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'

在我的片段中,我有方法openComment。如何从按钮单击调用该方法。 这是Fragment显示我如何调用该方法。

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");
}

我的custom_row.xml看起来像这样。它有一个文本视图和一个按钮

<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>

以下是我的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>

4 个答案:

答案 0 :(得分:3)

实际上,您必须在主机openComment(View v)内声明activity功能,而不是fragment。您可以在activity中声明该功能,如下所示:

public void openComment(View v){
    yourFragment.openComment(v);
}

但是,我认为解决这个问题不是一个好主意。您应该在适配器或片段中实现onClickListener

答案 1 :(得分:1)

我遇到过这个问题,即使@Kingfisher Phuoc给出了正确答案已有一年多了,我也想分享一下我的看法。

  

但是,我不认为以这种方式解决这个问题。

我完全同意。在包含片段而不是片段本身的活动内部的片段内编写按钮的逻辑并不是最佳实践。这与Single responsibility principle相反,谷歌以一种阻止开发人员利用最佳实践的方式设计Android是一种耻辱。

所以我该怎么做:

查看JakeWharton的ButterKnife图书馆。有了这个,你可以绑定视图。

所以在你的活动课'onCreate中你做:

// 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);
}

并绑定它包含的视图。就像片段类'onCreateView中的内容一样:

// 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;
}

查看documentation,你甚至可以找到简化BaseAdapter实现的代码,以便将openComment正确连接到OnClick,而不是用XML定义它。

答案 2 :(得分:0)

你可以这样做:

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;
}

您的XML布局中不需要:onClick属性。

答案 3 :(得分:0)

从BaseAdapter调用它。像

 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;
     }