Rabeea Qabaha
Rabeea Qabaha

Reputation: 378

Start fragment activity

I have an application with many fragments, and am trying to go from one fragment to another when a button is clicked.

The part I'm having trouble with is startActivity(new Intent(HomeFragment.this, FindPeopleFragment.class));

package info.androidhive.slidingmenu;

import info.androidhive.slidingmenu.HomeFragment;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.Toast;

public class HomeFragment extends Fragment {

public HomeFragment() {
}

ImageButton bSearchByLocation, bSearchByNumber;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    super.onCreateView(inflater, container, savedInstanceState);
    View InputFragmentView = inflater.inflate(R.layout.fragment_home,
            container, false);

    bSearchByNumber = ((ImageButton) InputFragmentView
            .findViewById(R.id.bSearchByLocation));
    bSearchByLocation = ((ImageButton) InputFragmentView
            .findViewById(R.id.bSearchByNumber));

    bSearchByLocation.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.bSearchByNumber) {
                Toast.makeText(getActivity(), "1", Toast.LENGTH_SHORT)
                        .show();
                 startActivity(new Intent(HomeFragment.this, FindPeopleFragment.class));
            }
        }
    });
    bSearchByNumber.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.bSearchByLocation) {
                Toast.makeText(getActivity(), "2", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    });
    return InputFragmentView;
}
}

after i do the solution the code look like this :

package info.androidhive.slidingmenu;

import info.androidhive.slidingmenu.HomeFragment;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class HomeFragment extends Fragment {

public HomeFragment() {
}

ImageButton bSearchByLocation, bSearchByNumber;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    super.onCreateView(inflater, container, savedInstanceState);
    View InputFragmentView = inflater.inflate(R.layout.fragment_home,
            container, false);

    bSearchByNumber = ((ImageButton) InputFragmentView
            .findViewById(R.id.bSearchByLocation));
    bSearchByLocation = ((ImageButton) InputFragmentView
            .findViewById(R.id.bSearchByNumber));

    bSearchByLocation.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.bSearchByNumber) {
                Toast.makeText(getActivity(), "1", Toast.LENGTH_SHORT)
                        .show();
                startActivity(new Intent(getActivity(), FindPeopleFragment.class));
            }
        }
    });
    bSearchByNumber.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.bSearchByLocation) {
                Toast.makeText(getActivity(), "2", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    });
    return InputFragmentView;
}
}

but when i Run it , the application crash and closed. this is my androidmanifest code :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.androidhive.slidingmenu"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="11"
    android:targetSdkVersion="17" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
    android:name="info.androidhive.slidingmenu.MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name="info.androidhive.slidingmenu.FindPeopleFragment"></activity>
</application>

</manifest>

and this is my logchat: enter image description here

by the way .... i use this surce code and work on it : http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer

Upvotes: 3

Views: 25647

Answers (3)

Blo
Blo

Reputation: 11978

In Fragment, you should get the hosting activity (the context) as getActivity(). Try this instead:

startActivity(new Intent(getActivity(), FindPeopleFragment.class));  

Declare the FindPeopleFragment class in your manifest:

<activity
    android:name="com.packagename.FindPeopleFragment" />  

All Activities (not Fragment) must to be declare in your manifest file.

Also, check if FindPeopleFragment extends Activity or FragmentActivity. If this extends Fragment, don't do an Intent. You must to make a FragmentTransaction to replace (or add above) your old Fragment (HomeFragment).


UPDATE

You are wrong in the way to achieve this. You try to start a new Activity which, in your case, is a Fragment and not an activity (extends Fragment). To achieve this, you can:

// call a method when click event
((MyFragmentActivity) getActivity()).replaceFragments();

Then, inside your FragmentActivity, set the method as:

// replace the fragment container with this method
public void replaceFragments() {
    Fragment newFragment = new FindPeopleFragment();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.commit();
}  

UPDATE2

As @Squonk said in comment and also in his answer, my answer above is a solution but not the right one. To have a really proper solution, you need to declare a Callback interface and associate the Fragment with any Activity.

First declare an interface and attach it to your activity in your fragment:

OnFragSelected mCallback;

public interface OnFragSelected {
    public void OnFragSelected(int id);
}  

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

Then call this in your on click event:

@Override
public void onClick(View v) {
    mCallback.OnFragSelected(800);
}  

Finally, in your fragment activity:

... implements HomeFragment.OnFragSelected {

    Fragment newFragment;

    @Override
    public void OnFragSelected(int id) {
        // example: id = 800
        // ...
        newFragment = new FindPeopleFragment();
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, newFragment);
        transaction.commit();
    }

}  

This way "is more flexible [...] Multiple activities can now embed your Fragment, they just have to implement the communication interface". This is important because "your fragment is re-usable and therefore do not depend on that specific Activity". Also, if you "use the fragment elsewhere, you eradicate the risk of a RuntimeException because it is strongly typed."

This question and these answers about Fragment 2 fragment communicating can show you the difference. Here, you have the google example and this answer: onAttach callback from fragment to activity might you to figure it out.

Upvotes: 6

Squonk
Squonk

Reputation: 48871

A Fragment should be modular, self-contained and reusable - it shouldn't know about other application components.

Don't start an Activity directly from a Fragment. Instead you should declare an interface which your parent Activity implements. When you click a button in your Fragment it should make a call to a method in the interface telling the parent Activity which button has been pressed. The parent Activity can then start which ever Activity is needed.

See Creating Event Callbacks

Upvotes: 0

mike20132013
mike20132013

Reputation: 5425

Do this to your intent :

startActivity(new Intent(getActivity(), FindPeopleFragment.class));

and add this to your manifest :

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="info.androidhive.slidingmenu.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
 <activity android:name="com.yourpackagename.FindPeopleFragment"></activity>
</application>

Add your activity to your manifest inside the applications tag.

It should work now .. :)

Upvotes: 1

Related Questions