6

I have been looking at stackoverflow to solve my problem and found something pretty good, but it does not work for me or I am to stupid to see it (How to implement OnFragmentInteractionListener)

I want to place a fragment inside a Frame, so I created it and so on. I have to implenet an interface and its method. I (think) I did it, but my App crashes everytime...

*Edit: My App crashes, when I call openHome or openRecommended, the onCreate method works, I get these errors, but everything is beeing displayed correctly.

This is my code:

MainActivity.java

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;


public class MainActivity extends Activity implements HomeFragment.OnFragmentInteractionListener, RecommendedFragment.OnFragmentInteractionListener
{
    FragmentTransaction fragmentTransaction;
    HomeFragment homeFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        homeFragment = new HomeFragment();

        getFragmentManager().beginTransaction().add(R.id.mainFrame, homeFragment).commit();
    }

    protected void openHome(View view)
    {
        /*Intent homeIntent = new Intent(this, HomeFragment.class);
        startActivity(homeIntent);

        homeFragment = new HomeFragment();
        getFragmentManager().beginTransaction().replace(R.id.mainFrame, homeFragment).commit();*/

        System.out.println("Success");
    }

    public void openRecommended(View view)
    {
        Intent recommendedIntent = new Intent(this, RecommendedFragment.class);
        startActivity(recommendedIntent);

        RecommendedFragment recommendedFragment = new RecommendedFragment();
        getFragmentManager().beginTransaction().replace(R.id.mainFrame, recommendedFragment).commit();
    }

    @Override
    public void onFragmentInteractionHome(Uri uri)
    {

    }

    @Override
    public void onFragmentInteractionRecommended(Uri uri)
    {

    }
}

HomeFragment.java

import android.app.Activity;
import android.app.Fragment;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link HomeFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link HomeFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class HomeFragment extends Fragment
{
    private OnFragmentInteractionListener mListener;


    public static HomeFragment newInstance()
    {
        HomeFragment fragment = new HomeFragment();
        return fragment;
    }

    public HomeFragment()
    {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState)
    {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_home, container, false);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri)
    {
        if (mListener != null)
        {
            mListener.onFragmentInteractionHome(uri);
        }
    }

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            mListener = (OnFragmentInteractionListener) activity;
        }
        catch (ClassCastException e)
        {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach()
    {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p/>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener
    {
        // TODO: Update argument type and name
        public void onFragmentInteractionHome(Uri uri);
    }
}

RecommendedFragment looks the same, except some methods have a different name.

I always get this error:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.domain.app/com.domain.app.MainActivity}: java.lang.ClassCastException: com.domain.app.MainActivity@b1d296b0 must implement OnFragmentInteractionListener at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) at android.app.ActivityThread.access$800(ActivityThread.java:135) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.ClassCastException: com.domain.app.MainActivity@b1d296b0 must implement OnFragmentInteractionListener at com.domain.app.HomeFragment.onAttach(HomeFragment.java:74) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:849) at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062) at android.app.BackStackRecord.run(BackStackRecord.java:684) at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447) at android.app.Activity.performStart(Activity.java:5240) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2168)             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)             at android.app.ActivityThread.access$800(ActivityThread.java:135)             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)             at android.os.Handler.dispatchMessage(Handler.java:102)             at android.os.Looper.loop(Looper.java:136)             at android.app.ActivityThread.main(ActivityThread.java:5017)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:515)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)             at dalvik.system.NativeStart.main(Native Method)

I really need help here, I am stuck for hours...

John

Community
  • 1
  • 1
JRsz
  • 2,891
  • 4
  • 28
  • 44
  • **com.domain.app.MainActivity@b1d296b0 must implement OnFragmentInteractionListener** – mstrthealias Sep 09 '14 at 21:44
  • It does?! public class MainActivity extends Activity implements HomeFragment.OnFragmentInteractionListener, RecommendedFragment.OnFragmentInteractionListener Or am I wrong? – JRsz Sep 09 '14 at 21:47
  • I'm wondering if `MainActivity` needs to extends `FragmentActivity` instead of `Activity`... – mbmc Sep 09 '14 at 21:49
  • I checked this before, it does if you use supportlibrary, but if you do not use these a normal Activity will just work fine. This is in the answer to one of my previus question, the only other atm ^^ – JRsz Sep 09 '14 at 21:50
  • Could you print the id of `MainActivity` before calling `getFragmentManager().beginTransaction`, then print the id of `activity` in `onAttach`. Just to make sure it's the same object. – mbmc Sep 09 '14 at 22:05
  • I am not really sure what you mean, but the part inside the onCreate method works, I get errors in the logcat, but it displays this fragment. When I try to call openHome or openRecommended it crashes... – JRsz Sep 09 '14 at 22:14
  • That part is not needed: Intent recommendedIntent = new Intent(this, RecommendedFragment.class); startActivity(recommendedIntent); since you add the fragment right after. – mbmc Sep 09 '14 at 22:18
  • ok, that is good to know, but the openHome method has nothing in it, except a message to the console, but nevertheless it crashes, if I push it – JRsz Sep 09 '14 at 22:22
  • remove that code from `openHome` and `openRecommended` – mbmc Sep 09 '14 at 22:26
  • both have no code, but the app still crashes :( – JRsz Sep 09 '14 at 22:31
  • The app shouldn't crash when you call empty methods. You still get those ClassCastException errors ? You're saying openRecommended is empty but it's not the case in the above code. Could you update the question with the new errors you're getting and the updated code (use pastebin in case there's a lot of it and you want to keep your question clean) ? thanks ;) – 2Dee Sep 10 '14 at 07:50
  • after I restarted my PC and Android Studio, it works fine, I have no idea why :D Yeah, pastebin is a great idea, thanks. I will have to go towork now, but when I come back, I will test it and see if it works or not :) This is a bit stupid, but could you rate this question up, so I get enough rep to chat at least? right now I cannot do anything :/ Or do you have any other tip? Answering questions is not so easy for me, I have tried it :D – JRsz Sep 10 '14 at 07:58

1 Answers1

7

I’ve removed useless references and everything related with RecommendedFragment class. If you post it I will update my answer.

I’ve tested it and it works. But try to explain what is the meaning of openHome() method, because it is never used based on your code, and nevertheless you say that the app crashes when you call it.

I added this method to the interface because it seems to me the most logical thing to do.

  //MainActivity

public class MainActivity extends Activity implements HomeFragment.OnFragmentInteractionListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getFragmentManager().beginTransaction()
                .add(R.id.mainFrame, new HomeFragment())
                .commit();
    }

    @Override
    public void openHome(View view) {
        System.out.println("Success");
    }

    @Override
    public void onFragmentInteractionHome(Uri uri) {
        Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show();
    }

}

//HomeFragment

public class HomeFragment extends Fragment {

    private OnFragmentInteractionListener mListener;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_home, container, false);
    }

    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteractionHome(uri);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
            mListener.onFragmentInteractionHome(Uri.parse("doWhatYouWant"));
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }


    public interface OnFragmentInteractionListener {
        public void onFragmentInteractionHome(Uri uri);
        public void openHome(View view);
    }

}
Víctor Albertos
  • 8,093
  • 5
  • 43
  • 71
  • openHome() is called by an Image Button, from an .xml File... it seems to work, that is amazing, but I got to go to work now, so I will test it in the evening, but thanks for now :) – JRsz Sep 10 '14 at 07:52
  • everything works fine now, must have been a bug with Android Studio or I am too stupid to see it :D However, thanks a lot :) I would rate your answer up, but for that I need 15 rep :/ – JRsz Sep 11 '14 at 09:24
  • Now you have a little more of rep ;) I'm glad that the problem is "resolved"! – Víctor Albertos Sep 11 '14 at 09:43
  • API 23+ and above its not working Mr.Víctor Albertos, Can u explain how to do it, i refers some top reputation link regarding this issue, but not working, kindly help me, thanks in advance – MohanRaj S Aug 06 '16 at 06:20
  • Link I referred http://stackoverflow.com/questions/32077086/android-onattachcontext-not-called-for-api-23 , i followed Francesco Florio code, but failed. – MohanRaj S Aug 06 '16 at 06:35