I've added a navigation drawer to my applicaton, it's one single activity that manage 3 fragments.
Now when I click in an item from the navigation drawer list, I get the position of selected item and I call the following method to display the selected fragment :
private void displayView(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = MapFragment.newInstance();
break;
case 2:
fragment = new NearbyFragment();
break;
default:
break;
}
if (fragment != null) {
replaceFragment(fragment);
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
}
and here is the replaceFragment() method :
private void replaceFragment(Fragment fragment) {
String backStateName = fragment.getClass().getName();
String fragmentTag = backStateName;
boolean fragmentPopped = mFragmentManager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped && mFragmentManager.findFragmentByTag(fragmentTag) == null){
//fragment not in back stack, create it.
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.replace(R.id.content_frame, fragment, fragmentTag);
//ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
ft.addToBackStack(backStateName);
ft.commit();
}
}
the problems:
when I click the home menu (case 0), the navigation closes with a smooth animation without any problems.
But when I select the map or nearby menu (case 1 and 2), the animation stops waiting for the fragment to load.
I want to use AsyncTask, to replace the fragment in a background thread but I don't know how
if only someone could explain to me what exactly should I do, or has a better idea it would be great.
When you implement your ActionBarDrawerToggle, the framework provides callbacks on close & open of the drawer:
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
/* replaceFragment() should be called here */
replaceFragment(fragment);
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
/* do nothing here */
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
So your displayView() method should look like this:
private void displayView(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = MapFragment.newInstance();
break;
case 2:
fragment = new NearbyFragment();
break;
default:
break;
}
if (fragment != null) {
//replaceFragment(fragment);
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
}
What I have done here is call replaceFragment() in the callback for drawer closed.
Try this. This should work.
Related
There is problem with my fragment, they are showed together, one on the second fragment. How to disapear, and only show one of them?
Definiton:
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fr = new avc);
FragmentTransaction ft = ((TestingActivity)context).getFragmentManager().beginTransaction();
ft.replace(R.id.test, fr);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
}
});
And definiton of container below:
<FrameLayout
android:id="#+id/test"
android:layout_width="match_parent"
android:layout_height="match_parent" />
You can use some thing like this. Make a function for showing a fragment and call each time this function with different parameter.
eg. If You want to show "HomeFragment" then call displayView(0) and if you want to show "FindPeopleFragment" then call displayView(1)
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new FindPeopleFragment();
break;
case 2:
fragment = new PhotosFragment();
break;
case 3:
fragment = new CommunityFragment();
break;
case 4:
fragment = new PagesFragment();
break;
case 5:
fragment = new WhatsHotFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
This is how I used navigation drawer to display Fragments:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new Fragment0();
break;
case 1:
fragment = new Fragment1();
break;
case 2:
fragment = new Fragment2();
break;
case 3:
fragment = new Fragment3();
break;
case 4:
fragment = new Fragment4();
break;
case 5:
fragment = new Fragment5();
}
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment)
.addToBackStack(null)
.commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(drawerll);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
Suppose if the user navigates to Fragment 2-> Fragment 5-> Fragment3.
If the user clicks the back button I need to have the descending order and on each fragment I am displaying the name of the Fragment when he goes to that particular fragment ie:
Fragment 3-> Fragment 5-> Fragment2.
This is what I have tried:
First Method:
FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
fm.popBackStackImmediate();
}
Second Method:
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
I'm unable to get this working**(ie.. I'm unable to move it back to the fragment where I have come from**) and unable to display the name of the fragment based on the backstack
Any help is greatly appreciated.
Your navigation is working fine I guess and the issue you are facing is the tittle for which you can use
public class SampleFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Creating view correspoding to the fragment
View v = inflater.inflate(R.layout.fragment_layout, container, false);
// Updating the action bar title
getActivity().getActionBar().setTitle("Screen name");
return v;
}
}
in every fragment. And whenever you backpress the onCreateView method of fragmemt(the one which is poping from the backstack) gets called and the tittle will again set replacing the old tittle.
1. Handle back
You can use getSupportFragmentManager().popBackStack() method in onBackPressed:
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
getSupportFragmentManager().beginTransaction().commit();
}
else {
super.onBackPressed();
}
}
Don't forget to add the fragment in BackStack like :
transaction.addToBackStack(null);
2. Display Name
To show the current fragment name in actionbar, you can get it on onResume of your Fragment :
#Override
protected void onResume() {
super.onResume();
((FrgmentActivtiyName)getActivity).changeTitle("title");
}
Define a method which set the title in the actionbar in your FrgmentActivity:
public void changeTitle(String titleToSet) {
// set title as titleToSet
}
Hope it helps ツ
Please try this:
In the activity which holds the fragments, override the onbackPressed() method by,
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
getSupportFragmentManager().beginTransaction().commit();
}
else {
super.onBackPressed();
}
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
menuList.setItemChecked(position, true);
menuList.setSelection(position);
}
I am working on an android app and I want to make a ListFragment and use it in navigation drawer as a fragment. It is possible?
I make the ListFragment but i have errors on my main activity:
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
ListFragment lf=null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new FindPeopleFragment();
break;
case 2:
fragment = new PhotosFragment();
break;
case 3:
lf = new CommunityFragment();
break;
case 4:
fragment = new PagesFragment();
break;
case 5:
fragment = new WhatsHotFragment();
break;
default:
break;
}
if (lf != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, lf).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
The error is: the method replace(int,Fragment) in the type FragmentFransaction is not applicable for the arguments (int,ListFragment).
This error is at this line of code(at replace):
if (lf != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, lf).commit();
where lf is a ListFragment.
So can I use ListFragment with Navigation Drawer?
You are using ListFragment from android.support.v4.app.ListFragment. If you indeed want to use support package, your Activity should extend FragmentActivity and then you should call getSupportFragmentManager() instead of getFragmentManager(). Otherwise please use android.app.ListFragment. So, probaly you should replace this:
import android.support.v4.app.ListFragment;
with this:
import android.app.ListFragment;
This is one of the method() of Navigation Drawer activity...
Code Snippet:
/**
* Diplaying fragment view for selected nav drawer list item
**/
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new ViewFragment();
break;
case 1:
//here i should call the FragmentActivity
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// Log.e("MainActivity", "Error in creating fragment");
}
}
create intent with fragment activity and use startActivity() to launch the fragment Activity.
switch (position) {
case 0:
fragment = new ViewFragment();
break;
case 1:
//here i should call the FragmentActivity
Intent intent = new Intent(Context, FragmentActivity.class);
startActivity(intent);
default:
break;
}
But make sure that your FragmentActivity. In FragmentActivity you have to use fragment to display the content.
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
FragmentActivity fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new HomeFragment();//LessonPlanFragment();
break;
case 2:
fragment = new HomeFragment();//GradeBookFragment();
break;
case 3:
fragment = new HomeFragment();//StudentFragment();
break;
case 4:
fragment = new HomeFragment();//ReportsFragment();
break;
case 5:
fragment = new HomeFragment();//AppSettingsFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
android.app.FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.frame_container, fragment);
ft.commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
I have tried using the support library but nothing helped. The error message reads "het method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arguments (int, FragmentActivity).
This won't work. You're trying to replace Fragment with FragmentActivity and this is impossible. You can only do that with Fragments. For clarification FragmetnActivity acts as host Activity for Fragments in support library.