ViewPager crashes when re-opening: NullPointerException SparseArray.get(int) - android

I've recently switched my ViewPager's adapter from FragmentPagerAdapter to FragmentStatePagerAdapter. However, whenever I return to my ViewPager the app crashes. This was not happening with FragmentPagerAdapter. The Logcat shows:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.util.SparseArray.get(int)' on a null object reference
I'm in that awkward position where I don't know enough to understand what questions I should be asking. All of my searches have turned up nothing useful.
Logcat
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.util.SparseArray.get(int)' on a null object reference
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:905)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:216)
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1455)
at android.view.View.dispatchRestoreInstanceState(View.java:17706)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3745)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3751)
at android.view.View.restoreHierarchyState(View.java:17684)
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:415)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1454)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
MainActivity.java
public class MainActivity extends AppCompatActivity
implements FragmentQuiz_Selection_Instruments.QuizSelectionInterface,
FragmentQuiz_Started.OnQuizExit,
FragmentQuiz_Selection_Topics.StartQuizInterface {
private DrawerLayout mDrawerLayout;
private Fragment mQuizFragment;
private Fragment mInstrumentsFragment;
private Fragment mReferenceFragment;
private ArrayList<String> mQuizSelection;
private ViewModel_ForegroundView viewModel;
private BottomNavigationView bottomNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialise mQuizSelection
mQuizSelection = new ArrayList<String>();
mQuizSelection.clear();
//Initialise bottomNavigationView
bottomNavigationView = findViewById(R.id.navigation_bottom);
//Set Bottom-Navigation icon
bottomNavigationView.getMenu().getItem(1).setChecked(true);
//Initialise ViewModel_ForegroundView
viewModel = ViewModelProviders.of(this).get(ViewModel_ForegroundView.class);
//Initialise ActionBar
final Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
//Initialise Top-Navigation Drawer
mDrawerLayout = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.navigation_top);
// Set the onClickListener for the NavigationDrawer
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
// set item as selected to persist highlight
item.setChecked(true);
// close drawer when item is tapped
mDrawerLayout.closeDrawers();
// Handle item clicks
int itemId = item.getItemId();
if (itemId == R.id.nav_top_ww) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_WWind");
if (fragment == null) {
mInstrumentsFragment = FragmentInstruments_WWind.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(mInstrumentsFragment, "FragmentInstruments_WWind");
fragmentTransaction.commit();
} else {
mInstrumentsFragment = fragment;
}
} else if (itemId == R.id.nav_top_br) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_Brass");
if (fragment == null) {
mInstrumentsFragment = FragmentInstruments_Brass.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(mInstrumentsFragment, "FragmentInstruments_Brass");
fragmentTransaction.commit();
} else {
mInstrumentsFragment = fragment;
}
} else if (itemId == R.id.nav_top_pp) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_PercPit");
if (fragment == null) {
mInstrumentsFragment = FragmentInstruments_PercPit.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(mInstrumentsFragment, "FragmentInstruments_PercPit");
fragmentTransaction.commit();
} else {
mInstrumentsFragment = fragment;
}
} else if (itemId == R.id.nav_top_pu) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_PercUnp");
if (fragment == null) {
mInstrumentsFragment = FragmentInstruments_PercUnp.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(mInstrumentsFragment, "FragmentInstruments_PercUnp");
fragmentTransaction.commit();
} else {
mInstrumentsFragment = fragment;
}
} else if (itemId == R.id.nav_top_sp) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_StrPlu");
if (fragment == null) {
mInstrumentsFragment = FragmentInstruments_StrPlu.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(mInstrumentsFragment, "FragmentInstruments_StrPlu");
fragmentTransaction.commit();
} else {
mInstrumentsFragment = fragment;
}
} else if (itemId == R.id.nav_top_ky) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_Keys");
if (fragment == null) {
mInstrumentsFragment = FragmentInstruments_Keys.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(mInstrumentsFragment, "FragmentInstruments_Keys");
fragmentTransaction.commit();
} else {
mInstrumentsFragment = fragment;
}
} else if (itemId == R.id.nav_top_sb) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_StrBow");
if (fragment == null) {
mInstrumentsFragment = FragmentInstruments_StrBow.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(mInstrumentsFragment, "FragmentInstruments_StrBow");
fragmentTransaction.commit();
} else {
mInstrumentsFragment = fragment;
}
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, mInstrumentsFragment);
transaction.commit();
//Record foreground-fragment change
viewModel.recordForegroundFragment(mInstrumentsFragment);
//Set 'Quiz Exit' button's visibility to 'false,' set Quiz-Ext button.
viewModel.recordQuizBtnStatus(false);
setQuizExtBtn();
return true;
}
});
mDrawerLayout.addDrawerListener(
new DrawerLayout.DrawerListener() {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// Respond when the drawer's position changes
}
#Override
public void onDrawerOpened(View drawerView) {
// Respond when the drawer is opened
drawerView.bringToFront();
}
#Override
public void onDrawerClosed(View drawerView) {
// Respond when the drawer is closed
}
#Override
public void onDrawerStateChanged(int newState) {
// Respond when the drawer motion state changes
}});
// Bottom-Navigation Menu
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.nav_btm_quiz) {
if (mQuizFragment != null) {
String string = mQuizFragment.toString();
if (string.contains("Started") || string.contains("Topics")) {
viewModel.recordQuizBtnStatus(true);
}
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, mQuizFragment);
fragmentTransaction.commit();
//Record foreground-fragment change
viewModel.recordForegroundFragment(mQuizFragment);
} else {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentQuiz_Selection_Instruments");
if (fragment == null) {
mQuizFragment = FragmentQuiz_Selection_Instruments.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, mQuizFragment, "FragmentQuiz_Selection_Instruments");
fragmentTransaction.commit();
viewModel.recordForegroundFragment(mQuizFragment);
} else {
mQuizFragment = fragment;
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, mQuizFragment);
fragmentTransaction.commit();
viewModel.recordForegroundFragment(mQuizFragment);
}
}
} else if (itemId == R.id.nav_btm_instruments) {
viewModel.recordQuizBtnStatus(false);
if (mInstrumentsFragment != null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, mInstrumentsFragment);
fragmentTransaction.commit();
viewModel.recordForegroundFragment(mInstrumentsFragment);
} else {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_WWind");
if (fragment == null) {
mQuizFragment = FragmentInstruments_WWind.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.frame_layout, mQuizFragment, "FragmentInstruments_WWind");
fragmentTransaction.commit();
} else {
mQuizFragment = fragment;
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, fragment);
fragmentTransaction.commit();
}
}
} else if (itemId == R.id.nav_btm_reference) {
viewModel.recordQuizBtnStatus(false);
if (mReferenceFragment != null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, mReferenceFragment);
fragmentTransaction.commit();
} else {
mReferenceFragment = FragmentReference.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, mReferenceFragment, "FragmentReference");
fragmentTransaction.commit();
}
}
//Set Quiz-Ext button's visibility.
setQuizExtBtn();
//Call 'invalidateOptionsMenu' to set the Quiz-Exit button's visibility.
invalidateOptionsMenu();
return true;
}
});
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
/**Display FragmentInstruments_WWind when opening the app for the first time.
* If the app is being resumed, use getForegroundFragment.
*/
if (viewModel.getForegroundFragment() == null) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentInstruments_WWind");
if (fragment == null) {
mInstrumentsFragment = FragmentInstruments_WWind.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(mInstrumentsFragment, "FragmentInstruments_WWind");
fragmentTransaction.commit();
} else {
mInstrumentsFragment = fragment;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, mInstrumentsFragment);
transaction.commit();
//Record foreground-fragment change
viewModel.recordForegroundFragment(mInstrumentsFragment);
//Set Quiz-Exit Status
viewModel.recordQuizBtnStatus(false);
//Set 'Reference' icon as checked
bottomNavigationView.getMenu().getItem(1).setChecked(true);
} else if (viewModel.getForegroundFragment() != null) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment foregroundFragment = viewModel.getForegroundFragment();
transaction.replace(R.id.frame_layout, foregroundFragment);
transaction.commit();
//Record foreground-fragment change, set bottom-navigation icon
viewModel.recordForegroundFragment(foregroundFragment);
String fragment = foregroundFragment.toString();
if (fragment.contains("Quiz")) {
bottomNavigationView.getMenu().getItem(0).setChecked(true);
} else if (fragment.contains("Reference")) {
bottomNavigationView.getMenu().getItem(1).setChecked(true);
} else if (fragment.contains("Help")) {
bottomNavigationView.getMenu().getItem(2).setChecked(true);
}
}
}
#Override
protected void onPause(){
super.onPause();
//Actions onPause
viewModel.recordInstrumentsFragment(mInstrumentsFragment);
}
//Search function handled here
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the options menu from XML
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.action_bar, menu);
//Set 'Quiz Exit' button's visibility.
boolean status = viewModel.getQuizBtnStatus();
menu.findItem(R.id.ab_quiz_exit).setVisible(status);
return true;
}
//Handle action-bar button clicks
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
case R.id.ab_quiz_exit:
onQuizExit();
}
return super.onOptionsItemSelected(item);
}
Parent Fragment
public class FragmentInstruments_Brass extends Fragment {
public static FragmentInstruments_Brass newInstance() {
FragmentInstruments_Brass fragment = new FragmentInstruments_Brass();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Fragment screen orientation normal both portrait and landscape
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_instruments, container, false);
//Setting ViewPager for each tab
ViewPager viewPager = view.findViewById(R.id.viewPager_instruments);
tabsToViewPager(viewPager);
//Set tabs inside toolbar
TabLayout tabLayout = view.findViewById(R.id.tabLayout_instruments);
tabLayout.setupWithViewPager(viewPager, false);
return view;
}
//Add Fragments to Tabs
private void tabsToViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getChildFragmentManager());
//Brass Fragments
adapter.addFragment(new Inst_Br_Frag1(), "Name1");
adapter.addFragment(new Inst_Br_Frag2(), "Name2");
adapter.addFragment(new Inst_Br_Frag3(), "Name3");
adapter.addFragment(new Inst_Br_Frag4(), "Name4");
adapter.addFragment(new Inst_Br_Frag5(), "Name5");
adapter.addFragment(new Inst_Br_Frag6(), "Name6");
viewPager.setAdapter(adapter);
}
static class Adapter extends FragmentStatePagerAdapter {
//mFragmentList stores ChildFragments
private final List<Fragment> mFragmentList = new ArrayList<>();
//mFragmentTitleList stores the displayed name of each ChildFragment
private final List<String> mFragmentTitleList = new ArrayList<>();
Adapter(FragmentManager manager) {
super(manager);
}
// Return the Fragment associated with a specified position
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
// getCount() returns the number of views available
#Override
public int getCount() {
return mFragmentList.size();
}
void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
//This method may be called by the ViewPager to obtain a title string to describe the specified page.
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}

Related

Bottom menu bar goes blank by clicking second time on menu options

I have a problem with my Bottom bar in android. when i click on the bottom menu options it goes blank. Please help me out to fine what is the basic problem. Where is am I wrong.
It shows no error or exception in logcat.
Here is my code
public class BottomBarActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottom_bar);
final BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
// Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.action_library:
FragmentLibrary fragmentLibrary = new FragmentLibrary();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout1, fragmentLibrary);
fragmentTransaction.commit();
Toast.makeText(BottomBarActivity.this, "Library", Toast.LENGTH_SHORT).show();
break;
case R.id.action_notification:
//002
Fragment selectedFragmentNotification = FragmentNotification.newInstance();
FragmentTransaction fragmentTransactionNotification = getSupportFragmentManager().beginTransaction();
fragmentTransactionNotification.replace(R.id.frame_layout1, selectedFragmentNotification);
fragmentTransactionNotification.commit();
Toast.makeText(BottomBarActivity.this, "Notifications", Toast.LENGTH_SHORT).show();
break;
case R.id.action_more:
Fragment selectedFragmentMore = FragmentMore.newInstance();
FragmentTransaction fragmentTransactionMore = getSupportFragmentManager().beginTransaction();
fragmentTransactionMore.replace(R.id.frame_layout1, selectedFragmentMore);
fragmentTransactionMore.commit();
Toast.makeText(BottomBarActivity.this, "More", Toast.LENGTH_SHORT).show();
break;
case R.id.action_discovered:
Fragment selectedFragmentMain = FragmentMain.newInstance();
FragmentTransaction fragmentTransactionMain = getSupportFragmentManager().beginTransaction();
fragmentTransactionMain.replace(R.id.frame_layout1, selectedFragmentMain);
fragmentTransactionMain.commit();
Toast.makeText(BottomBarActivity.this, "Discover", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
});
//Manually displaying the first fragment
Fragment selectedFragment = FragmentMain.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_layout1, selectedFragment);
fragmentTransaction.commit();
}
}
Here is the Fragment Class Code.
This fragment is called when I click one of the menu item.
public class FragmentLibrary extends Fragment {
private static final String ARG_POSITION = "position";
private int position;
private PagerSlidingTabStrip tabs_L;
private ViewPager pager_L;
public FragmentLibrary() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_library, container, false);
pager_L = (ViewPager) view.findViewById(R.id.pagerL);
pager_L.setAdapter(new MyAdapterLibrary(getFragmentManager()));
tabs_L = (PagerSlidingTabStrip) view.findViewById(R.id.tabsL);
tabs_L.setViewPager(pager_L);
return view;
}
// ADAPTER CLASS
public class MyAdapterLibrary extends FragmentPagerAdapter {
private String[] titles = {
getString(R.string.tab_title_current_reading),
getString(R.string.tab_title_reading_lists),
getString(R.string.tab_title_history)
};
public MyAdapterLibrary(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FragmentCurrentReading.newInstance(position);
case 1:
return FragmentReadingLists.newInstance(position);
case 2:
return FragmentHistory.newInstance(position);
}
return null;
}
#Override
public int getCount() {
return titles.length;
}
#Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
}

start fragment from another fragment (Android)

i need to start a fragment from another fragment.
i have my MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
mNavigationView = (NavigationView) findViewById(R.id.shitstuff) ;
mFragmentManager = getSupportFragmentManager();
mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.replace(R.id.containerView,new TabFragment()).commit();
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
mDrawerLayout.closeDrawers();
//Selecao dos menus
if (menuItem.getItemId() == R.id.nav_reservas) {
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerView, new Reservas()).commit();
} else if (menuItem.getItemId() == R.id.nav_hotel) {
FragmentTransaction xfragmentTransaction = mFragmentManager.beginTransaction();
xfragmentTransaction.replace(R.id.containerView, new TabFragment()).commit();
} else if (menuItem.getItemId() == R.id.nav_check) {
FragmentTransaction xfragmentTransaction = mFragmentManager.beginTransaction();
xfragmentTransaction.replace(R.id.containerView, new CheckIn()).commit();
} else if (menuItem.getItemId() == R.id.nav_loc) {
FragmentTransaction xfragmentTransaction = mFragmentManager.beginTransaction();
xfragmentTransaction.replace(R.id.containerView, new Endereco()).commit();
} else if (menuItem.getItemId() == R.id.nav_avalie) {
FragmentTransaction xfragmentTransaction = mFragmentManager.beginTransaction();
xfragmentTransaction.replace(R.id.containerView, new Avalie()).commit();
} else if (menuItem.getItemId() == R.id.nav_info) {
FragmentTransaction xfragmentTransaction = mFragmentManager.beginTransaction();
xfragmentTransaction.replace(R.id.containerView, new Informacoes()).commit();
} else if (menuItem.getItemId() == R.id.nav_guia) {
FragmentTransaction xfragmentTransaction = mFragmentManager.beginTransaction();
xfragmentTransaction.replace(R.id.containerView, new GuiaDaCidade()).commit();
}
return false;
}
}
);
and i start the GuiaDaCidade extends fragment.
public class GuiaDaCidade extends Fragment {
View rootView;
#Nullable
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.guia_da_cidade, null);
View botaoPasseios = (View) rootView.findViewById(R.id.btpasseios);
View botaoAgenda = (View) rootView.findViewById(R.id.btagenda);
botaoPasseios.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});
I need that when the button is clicked start the Passeios extends Fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.guia_passeios, null);
expListView = (ExpandableListView) rootView.findViewById(R.id.listaexp);
prepareListData();
listAdapter = new ExpandableListAdapter(getActivity(), listDataHeader, listDataChild);
expListView.setAdapter(listAdapter);
expandeAll();
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
mudaTela(groupPosition, childPosition);
return false;
}
});
return rootView;
}
I already tried everything possible but no way is working.
before you start another fragment, if you want to keep your current fragment into backstack so that it is available when user presses back button, add it to back stack using fragment manager. Then just use the same line: fragmentTransaction.replace(containerView,new Fragment(), TAG).commit();
GuiaDaCidade
botaoPasseios.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Passeios fragment = new Passeios();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.your_guiadacidade_layoutID, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
});

Facebook like dynamic viewpager

I am trying to create facebook like viewpager (swipable tabs and proper backstack) I can create swipable tabs but cant handle the proper back navigation. Bellow is my code
public class MainActivity extends FragmentActivity {
private ViewPager mPager;
// private SlidePagerAdapter mPagerAdapter;
private MyPagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Instantiate a ViewPager and a PagerAdapter. */
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setOffscreenPageLimit(4);
}
#Override
public void onBackPressed() {
Fragment currentVisibleFragment = mPagerAdapter.getRegisteredFragment(mPager.getCurrentItem());
if (currentVisibleFragment != null && currentVisibleFragment.isVisible()) {
FragmentManager childFm = currentVisibleFragment.getChildFragmentManager();
System.out.println("============================================");
System.out.println("childFm.getBackStackEntryCount()=== " + childFm.getBackStackEntryCount());
System.out.println("============================================");
if (childFm.getBackStackEntryCount() > 0) {
childFm.popBackStack();
return;
}
}
super.onBackPressed();
}
}
Adapter of my class is as bellow
public class MyPagerAdapter extends SmartFragmentStatePagerAdapter {
private static int NUM_ITEMS = 3;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return new FragmentA();
case 1: // Fragment # 0 - This will show FirstFragment different title
return new FragmentB();
case 2: // Fragment # 1 - This will show SecondFragment
return new FragmentC();
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
here is the exteded adapter
public abstract class SmartFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
// Sparse array to keep track of registered fragments in memory
private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public SmartFragmentStatePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Register the fragment when the item is instantiated
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
// Unregister when the item is inactive
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
// Returns the fragment for the position (if instantiated)
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
and Fragments are as bellow
public class FragmentA extends Fragment {
public static final String TAG = "FragmentA";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.first_fragment, container, false);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getChildFragmentManager().beginTransaction();
/*
* IMPORTANT: We use the "root frame" defined in
* "root_fragment.xml" as the reference to replace fragment
*/
trans.replace(R.id.framelayout_infragment_one, new FragmentA1());
/*
* IMPORTANT: The following lines allow us to add the fragment
* to the stack and return to it later, by pressing back
*/
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
public class FragmentA1 extends Fragment {
public static final String TAG = "FragmentA1";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.first_fragment, container, false);
view.setBackgroundColor(Color.RED);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getChildFragmentManager().beginTransaction();
/*
* IMPORTANT: We use the "root frame" defined in
* "root_fragment.xml" as the reference to replace fragment
*/
trans.replace(R.id.framelayout_infragment_one, new FragmentA2());
/*
* IMPORTANT: The following lines allow us to add the fragment
* to the stack and return to it later, by pressing back
*/
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
//second inner fragment
public class FragmentA2 extends Fragment {
public static final String TAG = "FragmentA2";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.second_fragment, container, false);
view.setBackgroundColor(Color.GRAY);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setText(TAG);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(R.id.root_frame, new FragmentC());
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
});
return view;
}
}
When I am going to frament A2 expected behaviour when user press back is I want to go to Frament A1 but I am going to Frament A. Fragment B,B1,B2 are same as A A1 A2 resp...
Please help
I managed it by maintaining stacks by myself
public static HashMap<String, Stack<Fragment>> mStacks;
mStacks = new HashMap<String, Stack<Fragment>>();
mStacks.put("TAB1", new Stack<Fragment>());
mStacks.put("TAB2", new Stack<Fragment>());
mStacks.put("TAB3", new Stack<Fragment>());
mStacks.put("TAB4", new Stack<Fragment>());
//when starting new fragment add that to stack like this
public void pushFragments(Fragment fragment) {
setSelectedPageN(pager.getCurrentItem());
mStacks.get(ApplicationConstants.CURRENT_TAB).push(fragment);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (ApplicationConstants.CURRENT_TAB.equals("TAB1")) {
ft.replace(R.id.container_feed, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB2")) {
ft.replace(R.id.container_chart, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB3")) {
ft.replace(R.id.container_explore, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals("TAB4")) {
ft.replace(R.id.container_profile, fragment);
}
ft.commit();
}
//When you want to finish
public void popFragments() {
/*
* Select the second last fragment in current tab's stack.. which will
* be shown after the fragment transaction given below
*/
setSelectedPageN(pager.getCurrentItem());
Fragment fragment = mStacks.get(ApplicationConstants.CURRENT_TAB).elementAt(mStacks.get(ApplicationConstants.CURRENT_TAB).size() - 2);
if (fragment instanceof ProfileContainerFragment) {
fragment = new ProfileFragment();
} else if (fragment instanceof FeedNewUserGuideline && !isShowFeedTutorial) {
fragment = new FeedFragment();
}
/* pop current fragment from stack.. */
mStacks.get(ApplicationConstants.CURRENT_TAB).pop();
/*
* We have the target fragment in hand.. Just show it.. Show a standard
* navigation animation
*/
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);
if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_FEED)) {
ft.replace(R.id.container_feed, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_CHART)) {
ft.replace(R.id.container_chart, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_EXPLORE)) {
ft.replace(R.id.container_explore, fragment);
} else if (ApplicationConstants.CURRENT_TAB.equals(ApplicationConstants.TAB_PROFILE)) {
ft.replace(R.id.container_profile, fragment);
}
ft.commit();
}
//When user back press
#Override
public void onBackPressed() {
try {
if (((BaseFragment) mStacks.get(ApplicationConstants.CURRENT_TAB).lastElement()).onBackPressed() == false) {
switch (pager.getCurrentItem()) {
case KeyConstants.POSITION_ONE_FEED:
if (mStacks.get(ApplicationConstants.TAB_FEED).size() == 1) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();
// super.onBackPressed(); // or call finish..
} else {
popFragments();
}
break;
case KeyConstants.POSITION_TWO_CHART:
if (mStacks.get(ApplicationConstants.TAB_CHART).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_ONE_FEED);
} else {
popFragments();
}
break;
case KeyConstants.POSITION_THREE_EXPLORE:
if (mStacks.get(ApplicationConstants.TAB_EXPLORE).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_TWO_CHART);
} else {
popFragments();
}
break;
case KeyConstants.POSITION_FOUR_PROFILE:
if (mStacks.get(ApplicationConstants.TAB_PROFILE).size() == 1) {
pager.setCurrentItem(KeyConstants.POSITION_THREE_EXPLORE);
} else {
popFragments();
}
break;
default:
break;
}
} else {
// do nothing.. fragment already handled back button press.
}
} catch (Exception e) {
e.printStackTrace();
}
}

switch fragments with button (with NavigationDrawer)

I have a NavigationDrawer which I use to switch between Fragments. What i would like to do is have a button in one of my fragments which acts as a 'shortcut' to another Fragment in the NavigationDrawer.
In the NavigationDrawer I switch fragments like this:
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
selectItem(position);
}
}
public void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager
.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
private FragmentBase createFragmentByPosition(int position) { // FragmentBase just extends Fragment
FragmentBase fragment = null;
if (position == 0) {
fragment = new Fragment1();
Bundle args = new Bundle();
fragment.setArguments(args);
} else if (position == 1) { // Reminder
fragment = new Fragment2();
Bundle args = new Bundle();
fragment.setArguments(args);
}
return fragment;
}
I'm not sure how I would go about doing this. I tried getting an instance of the NavigationDrawer class and then calling selectItem with the desired position, but this doesn't work as it gives an error "no view found".
In the NavigationDrawer class:
public Navigation_Drawer getInstance() {
if (null == instance) {
instance = new Navigation_Drawer();
}
return instance;
}
In FragmentB (position 1):
//onClick
Navigation_Drawer nd = new Navigation_Drawer().getInstance();
nd.selectItem(0); // Try to go to FragmentA
This seems far too simple so no wonder it doesn't work!
First, on selectItem method, using add method instead of replace method:
public void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
// fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
fragmentTransaction.add(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
Second, getInstance method in Navigation_Drawer should not create a new Navigation_Drawer when instance is null, set instance to this in onCreate in Navigation_Drawer, then return instance when call getInstance:
private static Navigation_Drawer mInstance;
public static Navigation_Drawer getInstance() {
return mInstance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
mInstance = this;
// other codes here:
}
The id to the QuickNoteFragment is 0, and to PendViewPager is 1. You can turn to PendViewPager in QuickNoteFragment:
Navigation_Drawer.getInstance().selectItem(1);
-
update1: how to pass data to fragment:
QuickNoteFragment and HistoryFragement have the same parent Class: FragmentBase, we add a method named onDataIn to receive data:
public class FragmentBase extends Fragment {
public void function onDataIn(Object data) {
}
}
We should change selectItem, add a paraments to receive data:
public void selectItem(int position, Object data) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
// call onDataIn() method.
fragment.onDataIn(data);
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
// fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
fragmentTransaction.add(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
In order to make selectItem compatible, we should add a overloaded selectItem method.
public void selectItem(int postion) {
selectItem(position, null);
}
In this way, we do not need to change the old code where called selectItem and did not need pass a data to fragement.

Fragment Hide do not work

I have created just sample application for fragment hiding and showing.At the first fragment is added into the view properly.But on menu press to hide fragment it don't get hide.I posted my code as follows..
public class SwapfragActivity extends Activity
{
FrameLayout fr;
FragmentManager fm = getFragmentManager();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
fr = (FrameLayout) findViewById(R.id.fm1);
frag f = new frag();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("SHOW");
menu.add("HIDE");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
frag f = new frag();
if (item.getTitle() == "SHOW")
{
if (!f.isAdded())
{
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fm1, f);
ft.commit();
}
else if (f.isHidden())
{
FragmentTransaction ft = fm.beginTransaction();
ft.show(f);
ft.commit();
}
}
else
{
if (f.isAdded())
{
FragmentTransaction ft = fm.beginTransaction();
ft.hide(f);
ft.commit();
}
}
return true;
}
}
class frag extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
return inflater.inflate(R.layout.a, container, false);
}
}

Categories

Resources