0

My test project has a main activity as follows:

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) {
        getMenuInflater().inflate(R.menu.display_message, menu);
        return true;
    }

    public void sendMessage(View view){
        FragmentManager frManager = getFragmentManager();
        FragmentTransaction transaction = frManager.beginTransaction();
        Frag fr= new Frag();
        transaction.add(R.id.stuuf, fr);
        transaction.addToBackStack(null);
        transaction.commit();
    }
}

And the following main layout:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/stuuf"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:paddingTop="?android:attr/actionBarSize" >

    <Button android:id="@+id/submit_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_send"
        android:onClick="sendMessage"/>

    </TableLayout>

When the user clicks the button the following fragment is displayed containing a second button:

<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: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=".Frag" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="180dp"
        android:onClick="buttonClicked"
        android:text="Button" />
    </RelativeLayout>

And the class that is supposed to control it:

public class Frag extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.frag_test, null);
    }

    public void buttonClicked(){
        System.out.println("Hello!");
    }

}

Now, there is a problem that when I click the second button, the system goes to look for the buttonClicked() method in MainActivity and not in Frag, thereby giving me the following error:

java.lang.IllegalStateExcetion: Could not find method buttonClicked(View) in the activity class com.spacitron.mytestproject.MainActivity for onClick handler on view class android.widget.Button with id 'button1'

Obviously I should be able to handle what happens in the fragment from the fragment class itself so I must be doing something totally wrong, I just can't pinpoint what.

spacitron
  • 2,095
  • 7
  • 30
  • 39

3 Answers3

2

The problem is that you're using onClick method in the fragments layout and Android is expecting to find that in the activity. There are 2 methods to fix this:

  1. The healthiest: remove onClick attributes from XML and rely on OnClickListener implementations.
  2. Delegate the call from activity to the fragment - declare the method in the activity and delegate that to the fragment. Something like below:

In the activity class have this:

public void buttonClicked(View view){
    Fragment current = getFragmentManager().findFragmentById(R.id.stuuf);
    if(current != null) {
        ((Frag)current).buttonClicked();
    }
}

On the long run, I would strongly suggest to not use onClick XML attributes. Reasons are explained in this SO answer.

Community
  • 1
  • 1
gunar
  • 14,660
  • 7
  • 56
  • 87
1

It looks like you're missing some steps, put this in your second fragment (and remove the onClick from the xml)

public void onViewCreated(View view, ...) {

    View btn = view.findViewById(R.id.button1);
    btn.setOnClickListener(new View.OnClickLisener() {

        public void onClick(View view) {
            Log.d("My App", "The button was clicked");
        }

    }

}
Nick Cardoso
  • 20,807
  • 14
  • 73
  • 124
0

A Fragment is build on top of an activity, and the onClick attribute is connected wit han activity.

I would suggest you to use ClickListeners for both the buttons :-

@Override
public void onViewCreated((View view, Bundle savedInstanceState) {
Button fragmentButton = (Button)view.findViewById(R.id.button1);
fragmentButton.setOnClickListener(new View.OnClickLisener() {

    public void onClick(View view) {
        //Do Something here
    }

});

}
Rahul Gupta
  • 5,275
  • 8
  • 35
  • 66