I currently have a MainActivity.java which should be the only activity class. Though in that activity class I have a nav-drawer which links to other fragment views.
Currently the main issue Im facing is implementing tabs under a fragment and making them just be available for only that fragment and subfragments. I ran my application and the tabs appeared, but they also appear on other fragments after I visit the TeamsAndDriversFragment.
In my MainActivity.java I have the following function which helps point to the fragments it will generate once someone clicks on them in the nav-drawer:
/**
* 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 TimeAndScoringFragment();
break;
case 1:
fragment = new ScheduleFragment();
break;
case 2:
fragment = new StandingsFragment();
break;
case 3:
fragment = new TeamsAndDriversFragment();
break;
case 4:
fragment = new NewsFragment();
break;
default:
break;
}
if (fragment != null) {
// Create a fragment transaction object to be able to switch fragments
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.frame_container, fragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.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");
}
}
Here is my current TeamsAndDriversFragment class where I have an actionbar navigation with tabs:
public class TeamsAndDriversFragment extends Fragment implements TabListener {
private List<Fragment> fragList = new ArrayList<Fragment>();
#Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
ActionBar bar = getActivity().getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab mTeamsTab = bar.newTab();
mTeamsTab.setText("Teams");
mTeamsTab.setTabListener(this);
bar.addTab(mTeamsTab);
Tab mDriversTab = bar.newTab();
mDriversTab.setText("Drivers");
mDriversTab.setTabListener(this);
bar.addTab(mDriversTab);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Fragment f = null;
TabFragment tf = null;
if(fragList.size() > tab.getPosition()) {
fragList.get(tab.getPosition());
}
if(f == null) {
tf = new TabFragment();
Bundle data = new Bundle();
data.putInt("idx", tab.getPosition());
tf.setArguments(data);
fragList.add(tf);
} else {
tf = (TabFragment) f;
}
ft.replace(android.R.id.content, tf);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if(fragList.size() > tab.getPosition()) {
ft.remove(fragList.get(tab.getPosition()));
}
}
}
In the displayView() method simply remove all tabs from the ActionBar, this way you'll always have a clean ActionBar with the exception of the TeamsAndDriversFragment fragment:
private void displayView(int position) {
getSupportActionBar().removeAllTabs();
// ...
}
Related
I'm making an app that has launches with a Swiping Tabs Fragment, but I also want to have a Preferences menu using Fragment Transaction. When I press the Settings button in my app, the preferences menu does appear and is interactive, but the layout seems to be transparent showing the Tabs below. Is there anything that can be done to fix this, or is there a better method?
Code that calls the Preferences Menu from the Options:
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getFragmentManager().popBackStackImmediate();
break;
case R.id.logout:
FirebaseAuth.getInstance().signOut();
finish();
startActivity(new Intent(this, Activity_Main.class));
break;
case R.id.action_settings:
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new Fragment_Settings()).addToBackStack(null)
.commit();
break;
}
return true;
}
Code that calls Tabs Fragments:
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new Fragment_Flower();
case 1:
// Games fragment activity
return new Fragment_Overview();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
}
Initialising Transaction in onCreate:
startService(new Intent(this, SensorListener.class));
if (b == null) {
// Create new fragment and transaction
Fragment newFragment = new Fragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
//Replace whatever is in the fragment_container view with this
// fragment,
// and add the transaction to the back stack
transaction.replace(android.R.id.content, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
Any help will be greatly appreciated!
Just set background color in your layout file. It may avoid transparent backgound.
I'm confused how to open my different fragments by clicking on one Item in my navigation drawer.
In MainActivity I use the following Code:
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment;
int id = item.getItemId();
if (id == R.id.nav_listview) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment, new ListFragment());
ft.commit();
} else if (id == R.id.nav_add_data) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_legal_information) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
First of all I want to try to open my ListFragment:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ListFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list, container, false);
}
}
In my content main.xml I created the following fragment which should be replaced when clicking on the specific Items in the Navigation Drawer.
<fragment
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fragment" />
But it isnt working...
Can anyone help me?
Rastaman
To get what you want try this ,I was also held up with this somewhat complex looking code but its more of a easy way to use
Here's detailed explanation and walk through to this issue:
(Its seems Long But You can easily relate your work asap)
When you first create the Navigation Drawer Activity, there are 5 files we’ll look at:
MainActivity.java - this is the code behind for everything in our app.
activity_main.xml - this is the layout for the app including the nav drawer and an include for the app_bar_main.
app_bar_main.xml - this is the layout with the toolbar (at the top), a floating action button (at the bottom right), and an include for content_main.
content_main.xml - this is the layout for the content of the main page.
nav_header_main.xml - this is the UI for the top part of the nav drawer.
Step 1:
open up the app_bar_main.xml, comment out the include and add a new FrameLayout:
<!--<include layout="#layout/content_main" />-->
<FrameLayout
android:id="#+id/Fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
This FrameLayout is what we’ll use to load our fragments into.
Step 2:
Next, you’ll want to add a few fragments
To do so, right click on your project, or go to File –> New and from the Fragment list choose Fragment (Blank) or others
Step 3:
The next step is to load a fragment when the app first launches. Go to the MainActivity’s onCreate method and put the following in after the call to setSupportActionBar:
Fragment fragment = null;
Class fragmentClass = null;
fragmentClass = FragmentOne.class;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.Fragment_container, fragment).commit();
Step 4:
You’ll then need to add OnFragmentInteractionListener to the interfaces your MainActivity implements and also implement the onFragmentInteraction method.Like this
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, FragmentOne.OnFragmentInteractionListener ,FragmentTwo.OnFragmentInteractionListener,FragmentThree.OnFragmentInteractionListener {
Step 5:
Finally, in the onNavigationItemSelected method, you can add the ability to load different fragments when menu items are tapped:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
Fragment fragment = null;
Class fragmentClass = null;
if (id == R.id.nav_camera) {
fragmentClass = FragmentOne.class;
} else if (id == R.id.nav_gallery) {
fragmentClass = FragmentTwo.class;
} else if (id == R.id.nav_slideshow) {
fragmentClass = FragmentThree.class;
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Here I’m just loading one of the two fragments I’ve added to my app. Note that because I have two different fragments, I had to implement the interfaces for both FragmentOne.OnFragmentInteractionListener and FragmentTwo.OnFragmentInteractionListener.
That’s all you need to do to implement fragment loading in your Navigation Drawer.
What the user taps a menu item, the drawer will slide back in smoothly and the new fragment will have already started / finished loading. This also prevents any possible jankiness that you could see when launching a new activity.
EXTRA
One last thing to note is that if you switch to a different fragment and then rotate the device or cause another recreation of the activity, the code above will cause the first fragment to be reloaded. One easy way to deal with that is to wrap the fragment block in the onCreate method in a check to see if the savedInstanceState is not null like this:
protected void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState == null) {
//Fragment load code
}
...
}
Try this Code
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment=null;
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
int id = item.getItemId();
if (id == R.id.nav_listview) {
fragment= new ListFragment();
} else if (id == R.id.nav_add_data) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_legal_information) {
}
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/container" />
Please Change The name of your fragment class ListFragment Because ListFragment is already Sub Class of Fragments in android.app package android OS
Mhmm I found an answer. But I am confused.
If I use:
if (id == R.id.nav_listview) {
fragment= new com.thomas.testapp.ListFragment();
It works. But I only have to use the package name if I want to open my ListFragment. Why?
I suggest to Create codes More Dynamic
first of all, if you have custom class to create Navigation Drawer, use listener to call methods from your activity
there is class call HomeFragment extends Fragment, so we have :
if(condition){
fragment = new HomeFragment();
// if there is Listener
if(mListener != null){
mListener.someMethod
}
// Other Settings And Codes
}
public class MainActivity extends AppCompatActivity {
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...From section above...
// Find our drawer view
nvDrawer = (NavigationView) findViewById(R.id.nvView);
// Setup drawer view
setupDrawerContent(nvDrawer);
}
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
selectDrawerItem(menuItem);
return true;
}
});
}
public void selectDrawerItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
Class fragmentClass;
switch(menuItem.getItemId()) {
case R.id.nav_first_fragment:
fragmentClass = FirstFragment.class;
break;
case R.id.nav_second_fragment:
fragmentClass = SecondFragment.class;
break;
case R.id.nav_third_fragment:
fragmentClass = ThirdFragment.class;
break;
default:
fragmentClass = FirstFragment.class;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
// Highlight the selected item has been done by NavigationView
menuItem.setChecked(true);
// Set action bar title
setTitle(menuItem.getTitle());
// Close the navigation drawer
mDrawer.closeDrawers();
}
// ...
}
I am trying to use this code
public class TabActivity extends SherlockFragmentActivity implements ActionBar.TabListener, OnItemSelectedListener
{
enum TabType
{
SEARCH, LIST, FAVORITES
}
// Tab back stacks
private HashMap<TabType, Stack<String>> backStacks;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Initialize ActionBar
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set back stacks
if (savedInstanceState != null)
{
// Read back stacks after orientation change
backStacks = (HashMap<TabType, Stack<String>>) savedInstanceState.getSerializable("stacks");
}
else
{
// Initialize back stacks on first run
backStacks = new HashMap<TabType, Stack<String>>();
backStacks.put(TabType.SEARCH, new Stack<String>());
backStacks.put(TabType.LIST, new Stack<String>());
backStacks.put(TabType.FAVORITES, new Stack<String>());
}
// Create tabs
bar.addTab(bar.newTab().setTag(TabType.SEARCH).setText("Search").setTabListener(this));
bar.addTab(bar.newTab().setTag(TabType.LIST).setText("List").setTabListener(this));
bar.addTab(bar.newTab().setTag(TabType.FAVORITES).setText("Favorites").setTabListener(this));
}
#Override
protected void onResume()
{
super.onResume();
// Select proper stack
Tab tab = getSupportActionBar().getSelectedTab();
Stack<String> backStack = backStacks.get(tab.getTag());
if (! backStack.isEmpty())
{
// Restore topmost fragment (e.g. after application switch)
String tag = backStack.peek();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
if (fragment.isDetached())
{
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.attach(fragment);
ft.commit();
}
}
}
#Override
protected void onPause()
{
super.onPause();
// Select proper stack
Tab tab = getSupportActionBar().getSelectedTab();
Stack<String> backStack = backStacks.get(tab.getTag());
if (! backStack.isEmpty())
{
// Detach topmost fragment otherwise it will not be correctly displayed
// after orientation change
String tag = backStack.peek();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
ft.detach(fragment);
ft.commit();
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
// Restore selected tab
int saved = savedInstanceState.getInt("tab", 0);
if (saved != getSupportActionBar().getSelectedNavigationIndex())
getSupportActionBar().setSelectedNavigationItem(saved);
}
#Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
// Save selected tab and all back stacks
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
outState.putSerializable("stacks", backStacks);
}
#Override
public void onBackPressed()
{
// Select proper stack
Tab tab = getSupportActionBar().getSelectedTab();
Stack<String> backStack = backStacks.get(tab.getTag());
String tag = backStack.pop();
if (backStack.isEmpty())
{
// Let application finish
super.onBackPressed();
}
else
{
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
// Animate return to previous fragment
ft.setCustomAnimations(R.anim.slide_from_right, R.anim.slide_to_left);
// Remove topmost fragment from back stack and forget it
ft.remove(fragment);
showFragment(backStack, ft);
ft.commit();
}
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
{
// Select proper stack
Stack<String> backStack = backStacks.get(tab.getTag());
if (backStack.isEmpty())
{
// If it is empty instantiate and add initial tab fragment
Fragment fragment;
switch ((TabType) tab.getTag())
{
case SEARCH:
fragment = Fragment.instantiate(this, SearchFragment.class.getName());
break;
case LIST:
fragment = Fragment.instantiate(this, ListFragment.class.getName());
break;
case FAVORITES:
fragment = Fragment.instantiate(this, FavoritesFragment.class.getName());
break;
default:
throw new java.lang.IllegalArgumentException("Unknown tab");
}
addFragment(fragment, backStack, ft);
}
else
{
// Show topmost fragment
showFragment(backStack, ft);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft)
{
// Select proper stack
Stack<String> backStack = backStacks.get(tab.getTag());
// Get topmost fragment
String tag = backStack.peek();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
// Detach it
ft.detach(fragment);
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft)
{
// Select proper stack
Stack<String> backStack = backStacks.get(tab.getTag());
if (backStack.size() > 1)
ft.setCustomAnimations(R.anim.slide_from_right, R.anim.slide_to_left);
// Clean the stack leaving only initial fragment
while (backStack.size() > 1)
{
// Pop topmost fragment
String tag = backStack.pop();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
// Remove it
ft.remove(fragment);
}
showFragment(backStack, ft);
}
private void addFragment(Fragment fragment)
{
// Select proper stack
Tab tab = getSupportActionBar().getSelectedTab();
Stack<String> backStack = backStacks.get(tab.getTag());
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// Animate transfer to new fragment
ft.setCustomAnimations(R.anim.slide_from_left, R.anim.slide_to_right);
// Get topmost fragment
String tag = backStack.peek();
Fragment top = getSupportFragmentManager().findFragmentByTag(tag);
ft.detach(top);
// Add new fragment
addFragment(fragment, backStack, ft);
ft.commit();
}
private void addFragment(Fragment fragment, Stack<String> backStack, FragmentTransaction ft)
{
// Add fragment to back stack with unique tag
String tag = UUID.randomUUID().toString();
ft.add(android.R.id.content, fragment, tag);
backStack.push(tag);
}
private void showFragment(Stack<String> backStack, FragmentTransaction ft)
{
// Peek topmost fragment from the stack
String tag = backStack.peek();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
// and attach it
ft.attach(fragment);
}
// The following code shows how to properly open new fragment. It assumes
// that parent fragment calls its activity via interface. This approach
// is described in Android development guidelines.
#Override
public void onItemSelected(String item)
{
ItemFragment fragment = new ItemFragment();
Bundle args = new Bundle();
args.putString("item", item);
fragment.setArguments(args);
addFragment(fragment);
}
}
in my app, doing navigation with tabs. I know, there are used a lot of deprecated methods, but I want to start from this. Everything is working great except when app is getting to background and need to be resumed (after longer time, i think it is cleared from rams). I am getting
java.lang.ClassCastException: java.util.ArrayList cannot be cast to
java.util.Stack
when calling (73 line in code)
Stack backStack = backStacks.get(tab.getTag());
What is wrong? Why its works when activity is starting first time, but onResume it gives ANR?
This is happening I'd say because backStacks.get(tab.getTag()); returns a List not a Stack. Try this instead:
List backStack = backStacks.get(tab.getTag());
You also probably shouldn't be using raw types.
Okey, I found solution by my self. As I find out, there is the problem with HashMap serialization in JAVA, so I saved HashMap as object to cache and when needed - opening it from cache. Everything works as expected.
/**
* In case that there is kinda bug in JAVA serializing HASHMAP, backstacks hashmap is writing to cache as object.
*/
private void serializeBackStack() {
try {
FileOutputStream fos =
new FileOutputStream(getCacheDir() + "backstack.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(backStacks);
oos.close();
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/**
* Hashmap with backstacks is getting from object saved in cahse.
*
* #return HashMap
*/
private HashMap<TabType, Stack<String>> deserializeBackStack() {
HashMap<TabType, Stack<String>> map = new HashMap<>();
try {
FileInputStream fis = new FileInputStream(getCacheDir() + "backstack.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
map = (HashMap<TabType, Stack<String>>) ois.readObject();
ois.close();
fis.close();
} catch (IOException ioe) {
ioe.printStackTrace();
return new HashMap<>();
} catch (ClassNotFoundException c) {
c.printStackTrace();
return new HashMap<>();
}
if (map != null)
return map;
else
return new HashMap<>();
}
Actually, this is my main problem. I've got a NavigationDrawer and I was changing lot of things about it; because I've added a TabHostFragment inside of it. The problem is when I'm in one Fragment, I've an ActionBar icon that goes to another Fragment. At the time to do this, it works perfect; but when I go to another Fragment, it still on the back of the new Fragment. I tried to put a BackGround color of each Fragment and it isn't visible.
The problem is that the transaction is OK; but when I'm in the other Fragment, when I press in a BlankSpace (For example) and on the old Fragment has a button here with a Toast, it's still showing this Toast on the new Fragment.
Here are a little examples of what happens maybe with images, you can understand better my question:
This main problem comes when I go trough this Fragment (I call it on MainActivity) that has no sense; because I want to call it when I'm on a specific Fragment; but it's in the only part that I can call this Fragment...
This is the MainActivity, where I call this FragmentTransaction:
case R.id.newOffer:
android.app.FragmentManager fm = getFragmentManager();
android.app.FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frame_container, new TipusNouProducte());
ft.commit();
return true;
And by the way, I leave here the code from my NavigationDrawer for you that always when I'm going through a Fragment, it says "Error on creating Fragment":
private void displayView(int position) {
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
Fragment fragment = null;
switch (position) {
case 0:
fragment = new TabHostFragment();
break;
case 1:
fragment = new LocalizacionFragment();
break;
case 2:
fragment = new ListaProductosFragment();
break;
case 3:
fragment = new ConfiguracionFragment(this);
break;
case 4:
fragment = new AyudaSugerenciasFragment();
break;
case 5:
fragment = new AyudaSugerencias();
break;
case 6:
finish();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
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");
}
}
If you need more code that you think can cause this problem, feel free to ask me; then I'll update ASAP.
TabHostFragment.xml
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
MainActivity code looks like:
public class MainActivity extends FragmentActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
// saber si esta abierto
public boolean mDrawerOpened;
// nav drawer title
private CharSequence mDrawerTitle;
private FragmentTabHost mTabHost;
// used to store app title
private CharSequence mTitle;
//para ponerlo visible
public MenuItem mi;
// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;
private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = mDrawerTitle = getTitle();
// load slide menu items
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
// nav drawer icons from resources
navMenuIcons = getResources()
.obtainTypedArray(R.array.nav_drawer_icons);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.list_slidermenu);
navDrawerItems = new ArrayList<NavDrawerItem>();
// adding nav drawer items to array
// Home
navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
// Find People
//navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
// Photos
navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
// Communities, Will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
// Pages
navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1)));
// What's hot, We will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
//AyudaSugerencias
navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1)));
navDrawerItems.add(new NavDrawerItem(navMenuTitles[6], navMenuIcons.getResourceId(6, -1)));
// Recycle the typed array
navMenuIcons.recycle();
mDrawerList.setOnItemClickListener(new SlideMenuClickListener());
// setting the nav drawer list adapter
adapter = new NavDrawerListAdapter(getApplicationContext(),
navDrawerItems);
mDrawerList.setAdapter(adapter);
// enabling action bar app icon and behaving it as toggle button
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setBackgroundDrawable(new ColorDrawable(0xff1d97dd));
getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, //nav menu toggle icon
R.string.app_name, // nav drawer open - description for accessibility
R.string.app_name // nav drawer close - description for accessibility
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(
Html.fromHtml("<font color='ffffff'>"
+ mTitle + "</font>"));
// calling onPrepareOptionsMenu() to show action bar icons
invalidateOptionsMenu();
mDrawerOpened = false;
syncState();
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(
Html.fromHtml("<font color='ffffff'>"
+ mDrawerTitle + "</font>"));
// calling onPrepareOptionsMenu() to hide action bar icons
invalidateOptionsMenu();
mDrawerOpened = true;
syncState();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
// on first time display view for first nav item
displayView(0);
}
}
/**
* Slide menu item click listener
*/
private class SlideMenuClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// display view for selected nav drawer item
displayView(position);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Fragment fragment = null;
// toggle nav drawer on selecting action bar app icon/title
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action bar actions click
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case R.id.ofertasRefresh:
return true;
case R.id.menu_search:
return true;
case R.id.newOffer:
android.app.FragmentManager fm = getFragmentManager();
android.app.FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frame_container, new TipusNouProducte());
ft.commit();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/* *
* Called when invalidateOptionsMenu() is triggered
*/
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
if (mDrawerOpened) {
menu.removeItem(R.id.ofertasRefresh);
menu.removeItem(R.id.menu_search);
menu.removeItem(R.id.newOffer);
}
if (!mDrawerOpened) {
menu.add(Menu.NONE, R.id.ofertasRefresh, Menu.NONE, mTitle);
}
return super.onPrepareOptionsMenu(menu);
}
/**
* Diplaying fragment view for selected nav drawer list item
*/
private void displayView(int position) {
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
Fragment fragment = null;
switch (position) {
case 0:
fragment = new TabHostFragment();
break;
case 1:
fragment = new LocalizacionFragment();
break;
case 2:
fragment = new ListaProductosFragment();
break;
case 3:
fragment = new ConfiguracionFragment(this);
break;
case 4:
fragment = new AyudaSugerenciasFragment();
break;
case 5:
fragment = new AyudaSugerencias();
break;
case 6:
finish();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
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");
}
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
TabHostFragment looks like:
public class TabHostFragment extends Fragment {
// Declaring our tabs and the corresponding fragments.
public TabHostFragment(){
}
private FragmentTabHost mTabHost;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab_host_test2, container, false);
mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("Mis ofertas").setIndicator("Mis ofertas"),
MisOfertasFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Mis recomendaciones").setIndicator("Mis recomendaciones"),
RecomendacionesFragment.class, null);
return rootView;
}
}
I'm not certain that this is the cause of your problem, but one thing that's definitely wrong is the use of the native FragmentManager instead of the one from the support library.
In your code, replace
case R.id.newOffer:
android.app.FragmentManager fm = getFragmentManager();
android.app.FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frame_container, new TipusNouProducte());
ft.commit();
return true;
with
case R.id.newOffer:
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frame_container, new TipusNouProducte());
ft.commit();
return true;
You have used the support library's FragmentManager at other places in your code, so you should continue to use that everywhere.
Also, TipusNouProducte should extend android.support.v4.app.Fragment and NOT
android.app.Fragment.
I will update this answer if I find more issues.
http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
hi all, I have succeeded apply this Android Sliding Menu in my project.
however, how can i add some activity in diffferent page?
In MainActivity, displayView function controls the fragment which i have selected.you can see it only use in "Fragment fragment = null;",so , the CESDemo class is extends Fragment.But i cannot add my activity in the CESDemo, such as onTouch and so on.If i change it to FragmentActivity, it does not allow me for "ragmentManager.beginTransaction().replace(R.id.frame_container,fragment).commit();"
So, how can i apply some activity in different fragment,even i can design the layout but no any activity i can create.
MainActivity.java
private void displayView(int position) {
// update the main content by replacing fragments
//Fragment fragment = null;
Fragment fragment =null;
switch (position) {
case 0:
fragment = new CESHome();
break;
case 1:
fragment = new CESAll();
break;
case 2:
fragment = new CESPending();
break;
case 3:
fragment = new CESInProgress();
break;
case 4:
fragment = new CESCompleted();
break;
case 5:
fragment = new CESDemo();
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");
}
}
CESDemo.java
public class CESDemo extends Fragment {
public CESDemo(){}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_cesdemo, container, false);
return rootView;
}