Reputation: 378
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:
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
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
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.
Upvotes: 0
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