I have Navigation drawer.and in First fragmant of Navigation drawer there is viewpager and there is information coming from network.Viewpager has 2 fragments also.When I switch fragment to Settings fragment of navigation drawer and coming back to this fragment everything is gone..There is no any information..How can i save state of this fragment?Or in which method can i send request to take information from network again
MainActivity
public class MainActivity extends AppCompatActivity implements
NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.motherFragments, FragmentMainPage.newInstance("MainPage"))
.commit();
}
#Override
public void onBackPressed() {
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: {
drawer.openDrawer(GravityCompat.START);
break;
}
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment = null;
if (item.isChecked()) {
drawer.closeDrawer(GravityCompat.START);
return false;
}
switch (item.getItemId()) {
case R.id.home: {
fragment = new FragmentMainPage().newInstance("Sample");
break;
}
case R.id.settings:{
Intent intent = new Intent(this,SettingsActivity.class);
startActivity(intent);
break;
}
case R.id.incoming:{
fragment = new FragmentIncomingPage().newInstance("Sample");
break;
}
}
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction().replace(R.id.motherFragments, fragment)
.commit();
item.setChecked(true);
}
drawer.closeDrawer(GravityCompat.START);
return true;
} }
Fragment1 of Navigation drawer
public class FragmentMainPage extends Fragment implements
ViewPager.OnPageChangeListener {
private Toolbar toolbar;
private MainActivity activity;
private TabLayout tabLayout;
private ViewPager viewPager;
String[] names = {
"Sample 1",
"Sample 2"
};
private static FragmentMainPage myInstance;
public static FragmentMainPage newInstance(String testString){
Bundle bundle = new Bundle();
bundle.putString("test",testString);
if(myInstance == null){
myInstance = new FragmentMainPage();
}
myInstance.setArguments(bundle);
return myInstance;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
activity = ((MainActivity) context);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_fragment_main,container,false);
toolbar = (Toolbar) view.findViewById(R.id.toolbar);
activity.setSupportActionBar(toolbar);
activity.setTitle(getResources().getText(R.string.bosh_sahifa));
activity.getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp);
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
setupViewpager(viewPager);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(this);
setupTabName();
return view;
}
private void setupViewpager(ViewPager viewPager) {
MyAdapter adapter = new MyAdapter(getActivity().getSupportFragmentManager());
adapter.addFragement(new Fragment_home1());
adapter.addFragement(new Fragment_home2());
viewPager.setAdapter(adapter);
}
private void setupTabName() {
tabLayout.getTabAt(0).setText(names[0]);
tabLayout.getTabAt(1).setText(names[1]);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
private class MyAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragement(Fragment fragment){
mFragmentList.add(fragment);
}
}
}
Fragment 2 of Navigation drawer
public class FragmentIncomingPage extends Fragment {
private Toolbar toolbar;
private MainActivity activity;
private static FragmentIncomingPage myInstance;
public static FragmentIncomingPage newInstance(String testString){
Bundle bundle = new Bundle();
bundle.putString("test",testString);
if(myInstance == null){
myInstance = new FragmentIncomingPage();
}
myInstance.setArguments(bundle);
return myInstance;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
activity = ((MainActivity) context);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_fragment_incoming,container,false);
toolbar = (Toolbar) view.findViewById(R.id.toolbar);
activity.setSupportActionBar(toolbar);
activity.setTitle(getResources().getText(R.string.Incoming));
activity.getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp);
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
return view;
}
}
Have 3 fragments and swipe to 3rd fragment then back to 1st fragment, the 1st fragment's data is gone?
You can use fragment.addToBackStack(null) method.
like,
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, A);
ft.addToBackStack(null);
ft.commit();
There is few ways to achieve it.
You can use SharedPreferences to save current Fragment by mViewPager.getCurrentItem() and set it again once you come to the ViewPager activity by navigation drawer button.
Use BaseFragment and implement your fragments from the Base Fragment, keep current visible fragment of the view pager in side the Base Fragment as protected variable.
As Base Fragment which is describe above, You can use Bas Activity class.
Related
I have an activity that has two fragments. The activity has a custom toolbar and the remaining space on the screen is used by the fragments (one at a time). In this toolbar there is a SearchView.OnQueryTextListener but this search should always be available in the fragment 1 and for the fragment 2 if should be available only if it meets a criteria. So what I need is a way to check, everytime I switch from fragments which one if occupying the screen at the moment and if it's the fragment one I set the searchView as available and for the fragment 2 the searchView will be available only if it meets the criteria.
This is my Activity:
public class ActivityTeams extends BaseActivity implements SearchView.OnQueryTextListener {
public ActivityTeams(){
super(R.layout.activity_teams);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
token = SharedPrefsHelper.getString(getApplicationContext(), Constants.TOKEN);
listview = (ListView) findViewById(R.id.listview);
listview.setVisibility(View.INVISIBLE);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new InternsFragment(), getResources().getString(R.string.team_internal));
adapter.addFragment(new ExternsFragment(), getResources().getString(R.string.team_external));
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
#Override
protected void initToolbar() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
if(toolbar!=null) {
if (user_type == 1) {
toolbar.setTitle(R.string.collaborators_title);
} else if (user_type == 2) {
toolbar.setTitle(R.string.admin_title);
}
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationIcon(R.drawable.ic_action_back_black);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search_team, menu);
SearchManager searchManager = (SearchManager)
getSystemService(Context.SEARCH_SERVICE);
searchMenuItem = menu.findItem(R.id.search);
searchView = (SearchView) searchMenuItem.getActionView();
ImageView searchSubmit = (ImageView) searchView.findViewById (android.support.v7.appcompat.R.id.search_go_btn);
searchSubmit.setImageResource(R.drawable.ic_dots_w);
searchSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Clear query
searchView.setQuery("", false);
//Collapse the action view
searchView.onActionViewCollapsed();
//Collapse the search widget
searchMenuItem.collapseActionView();
listview.setVisibility(View.GONE);
viewPager.bringToFront();
appBarLayout.setVisibility(View.VISIBLE);
}
});
for (TextView textView : findChildrenByClass(searchView, TextView.class)) {
textView.setTextColor(Color.BLACK);
textView.setHintTextColor(Color.BLACK);
}
searchView.setSearchableInfo(searchManager.
getSearchableInfo(getComponentName()));
searchView.setSubmitButtonEnabled(true);
searchView.setOnQueryTextListener(this);
return true;
}
This is fragment 1:
public class InternsFragment extends Fragment{
public InternsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_interns, container, false);
return rootView;
}
And this is fragment 2:
public class ExternsFragment extends Fragment {
public ExternsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_externs, container, false);
return rootView;
}
searchMenuItem in my activity is the thing I want to make change the visibility depending on the fragment that it's visible.
Use a ViewPager.OnPageChangeListener and use InvalidateOptionsMenu() inside that like so:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentFragment = position // use a field to store position
invalidateOptionsMenu();
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
});
Then depending on position, setup your menu in onPrepareOptionsMenu
I read some articles and make a nav drawer and fragments.i want to when I click on items in nav drawer, open fragments layout. but when I click on my fragments, my app crashed and unfortunately has stopped.
Can any one tell me what do I wrong? or what should I do to resolve my problem?
This is my MainActivty.java:
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawer;
private Toolbar toolbar;
private NavigationView nvDrawer;
private ActionBarDrawerToggle drawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
nvDrawer = (NavigationView) findViewById(R.id.nvView);
setupDrawerContent(nvDrawer);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = setupDrawerToggle();
mDrawer.addDrawerListener(drawerToggle);
}
private ActionBarDrawerToggle setupDrawerToggle() {
return new ActionBarDrawerToggle(this, mDrawer, toolbar, R.string.drawer_open, R.string.drawer_close);
}
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) {
Fragment fragment = null;
Class fragmentClass;
switch (menuItem.getItemId()) {
case R.id.nav_first_fragment:
fragmentClass = FirstFragment.class;
case R.id.nav_second_fragment:
fragmentClass = SecondFragment.class;
case R.id.nav_third_fragment:
fragmentClass = ThirdFragment.class;
default:
fragmentClass = FirstFragment.class;
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
menuItem.setChecked(true);
setTitle(menuItem.getTitle());
mDrawer.closeDrawers();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawer.openDrawer(GravityCompat.START);
return true;
}
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
}
This is my firstfragment:
public class FirstFragment extends android.support.v4.app.Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public FirstFragment() {
}
public static FirstFragment newInstance(String param1, String param2) {
FirstFragment fragment = new FirstFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_first, container, false);
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}
Call fragment by using below code;
Fragment fragment = new TaskDiscussionFragment();
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.flContent, fragment);
ft.commit();
Add the Listener which you are expecting in in FirstFragment in MainActvity and override the interface method like below,
FirstFragment is expecting OnFragmentInteractionListener in your onAttach method.
public class MainActivity extends AppCompatActivity implements OnFragmentInteractionListener{
#Override
public void onFragmentInteraction(Uri uri) {
}
}
I've a FrameLayout and Navigation Drawer in Main Activity. I'm transacting a fragment in Main Activity using this FrameLayout. In this fragment, I've TabLayout and ViewPager. Now what I want is to open a new fragment on Button click in the ViewPager fragment. But app crashes on Button click. Is it becuz FrameLayout is in Main Activity and the Button is in child fragment's child fragment? I've tried using FrameLayout in Tabs but that would mean I would have to use FrameLayouts for each Tab and I don't want that. So any help in this regard will be much appreciated. Also, how to handle back arrow click in toolbar to go back to previous fragment?
public class HomeFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 2;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.homefragment, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
}
class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
/**
* Return fragment with respect to Position .
*/
#Override
public Fragment getItem(int position)
{
switch (position){
case 0 : return new TabOne();
case 1 : return new TabTwo();
}
return null;
}
#Override
public int getCount() {
return int_items;
}
/**
* This method returns the title of the tab according to the position.
*/
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "ONE";
case 1 :
return "TWO";
}
return null;
}
}
}
public class TabOne extends Fragment {
private Button newFrag;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.tabone, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
newFrag = (Button)view.findViewById(R.id.button);
newFrag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction xfragmentTransaction = getChildFragmentManager().beginTransaction();
xfragmentTransaction.replace(R.id.containerView, new NewFrag()).addToBackStack(null).commit();
}
});
}
}
public class MainActivity extends AppCompatActivity {
DrawerLayout myDrawerLayout;
NavigationView myNavigationView;
Toolbar toolbar;
ActionBarDrawerToggle mDrawerToggle;
FragmentManager myFragmentManager;
FragmentTransaction myFragmentTransaction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
myNavigationView = (NavigationView) findViewById(R.id.nav_drawer) ;
myFragmentManager = getSupportFragmentManager();
myFragmentTransaction = myFragmentManager.beginTransaction();
myFragmentTransaction.replace(R.id.containerView, new HomeFragment()).commit();
myNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem selectedMenuItem) {
myDrawerLayout.closeDrawers();
if (selectedMenuItem.getItemId() == R.id.nav_profile) {
FragmentTransaction fragmentTransaction = myFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.containerView, new ProfileFragment()).addToBackStack(null).commit();
}
if (selectedMenuItem.getItemId() == R.id.nav_history) {
FragmentTransaction xfragmentTransaction = myFragmentManager.beginTransaction();
xfragmentTransaction.replace(R.id.containerView, new HistoryFragment()).addToBackStack(null).commit();
}
return false;
}
});
toolbar = (Toolbar)findViewById(R.id.toolbar);
mDrawerToggle = new ActionBarDrawerToggle(this, myDrawerLayout, toolbar, R.string.app_name, R.string.app_name);
myDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
}
FATAL EXCEPTION: main
Process: com.sam.demonavigation, PID: 8523
java.lang.IllegalArgumentException: No view found for id 0x7f0c006b (com.sam.demonavigation:id/containerView) for fragment HistoryFragment{42016928 #0 id=0x7f0c006b}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1059)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5388)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:655)
at dalvik.system.NativeStart.main(Native Method)
This link proved to be very useful. Using the method mentioned in my link I was able to use the FrameLayout in my Main Activity to open any fragment
// This is the button click event in one of the TabLayout fragment
newFrag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment var1 = new NewFrag();
((MainActivity)getActivity()).replaceFragment(var1);
}
});
// Add this method in MainActivity
public void replaceFragment(Fragment fragment){
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.containerView, fragment).addToBackStack(null);
t.commit();
}
.
1-Create ViewPager object
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setOffscreenPageLimit(3);
setupViewPager(viewPager);
2-then add Custom FragmentPagerAdapter
ViewPagerAdapter adapter = new ViewPagerAdapter(this);
adapter.addFrag(new Fragment1(), "Item1");
adapter.addFrag(new Fragment2(), "Item2");
adapter.addFrag(new Fragment3(), "Item3");
viewPager.setAdapter(adapter);
3-After that write custom adapter definition
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
I have a drawer navigationview on the left connects to different fragments with different viewpagers. The structure is as followed.
MainActivity
Drawer NavigationView
| Fragment A -- ViewPagerA ----Tab1 - Fragment1
Tab2 - Fragment2
| Tab3 - Fragment3
| Fragment B -- ViewPagerB ----Tab1 - Fragment4
Tab2 - Fragment5
| Tab3 - Fragment6
Fragment1-6 are list view fragments.
The problem is when I switch from Fragment A to Fragment B, viewpager will cache the content of list view from Fragment1 and try to show the cached content to the adapter of Fragment4. So that it always shows wrong information when the first time I switch fragments from navigation drawer.
My Code:
MainActivity:
public class MainActivity extends Activity {
#InjectView(R.id.navigation_view) public NavigationView mNavigationView;
#InjectView(R.id.drawerLayout) public DrawerLayout mDrawerLayout;
//......Layout injections..............///
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout, mToolbar,R.string.app_name,
R.string.app_name){
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
}
public void setUpToggle()
{
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
if (menuItem.isChecked()) menuItem.setChecked(false);
else menuItem.setChecked(true);
//Closing drawer on item click
mDrawerLayout.closeDrawers();
switch (menuItem.getItemId()) {
case R.id.a_drawer:
startFragment(FragmentA.newInstance());
return true;
case R.id.b_drawer:
startFragment(FragmentB.newInstance());
return true;
default:
Toast.makeText(getApplicationContext(),"More things need to be added",Toast.LENGTH_SHORT).show();
return true;
}
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
}
}
Fragment A/B (Exactly the same structures and layouts)
public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = n; //n is any positive integer
private Context mContext;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/**
*Inflate tab_layout and setup Views.
*/
View tabView = inflater.inflate(R.layout.fragment_tab,null);
tabLayout = (TabLayout) tabView.findViewById(R.id.tabs);
viewPager = (ViewPager) tabView.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return tabView;
}
class MyAdapter extends FragmentStatePagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position)
{
switch (position){
case 0 : return new Fragment1();//or Fragment4 5 6 here
case 1 : return new Fragment2();
case 2 : return new Fragment3();
default:return new Fragment1();
}
}
#Override
public int getCount() {
return int_items;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "F1";
case 1 :
return "F2";
case 2 :
return "F3";
}
return null;
}
}
Fragment 1 - 6 :
public class TabFocusFragmentextends extends Fragment
implements LoaderManager.LoaderCallbacks<Cursor>
{
private TabFocusAdapter mAdapter;
private List<E> mList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadData();// never been executed,:(
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab_focus, container, false);
loadData();
setupRecyclerView();
return view;
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onLoadMore() {
if(NeedLoad)
loadData();
}
private void loadData() {
//RequestData
……
}
private void setupRecyclerView() {
…...
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(mActivity, ContentProvider.createUri(E.class, null),
null, null, null, null);
}
#Override //fragment starts here, why??
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (loadedList.size() > 0) {
//crashes here …...
if (!fullPacketLoaded) {
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
If new fragment list adapter doesn't have an appropriate to show previous content, it will crash.
Based on this question, if you have a better solution for the question down below as well? Why is Tablayout and Viewpager crashing with NullpointerException when I start a fragment with LoaderManager from TabFragment?
Finally fixed.
In my onCreate() method of which fragment implemented LoaderManager, I did this
getLoaderManager().initLoader(0, null, this);
if(!getLoaderManager().getLoader(0).isReset()) {
getLoaderManager().restartLoader(0, null, this);
}
It works when new loader was not actived properly.
As mentioned in my previous question I had some problem with showing Fragments inside a ViewPager after opening another Fragment from one of the Fragments inside the ViewPager.
I somehow managed to resolve the problem by using add() in the FragmentTransaction. Unfortunately this creates another problem:
I am using the ActionBar in my app. When I am selecting the same menu item twice I encounter the same problem as before, it doesn't show any Fragments inside the ViewPager.
Home Activity Code(where action bar on click events are call)
public class HomePageActivity extends SherlockFragmentActivity implements ICallback {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private SherlockActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mChampionsMenuItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.Theme_Sherlock);
setContentView(R.layout.activity_home_page);
mTitle = mDrawerTitle = getTitle();
mChampionsMenuItems = getResources().getStringArray(R.array.champions_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mChampionsMenuItems));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.color.navy_blue));
getSupportActionBar().setDisplayShowTitleEnabled(false);
mDrawerToggle = new SherlockActionBarDrawerToggle(this, mDrawerLayout, R.drawable.menu_icon, R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(mTitle);
supportInvalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle(mDrawerTitle);
supportInvalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
onFragmentChange(new HomeActivityFragment(), true);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
default: return super.onOptionsItemSelected(item);
}
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
switch (position) {
case 0:
onFragmentChange(new Fragment1(), false);
break;
case 1:
onFragmentChange(new Fragment2(), false);
break;
case 2:
onFragmentChange(new MyPointFragment3(), false);
break;
case 3:
// onFragmentChange(new HomeActivityFragment(), true);
break;
case 4:
onFragmentChange(new QueriesFragment(), false);
break;
case 5:
onFragmentChange(new GalleryFragment(), false);
break;
default:
break;
}
mDrawerList.setItemChecked(position, true);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getSupportActionBar().setTitle(mTitle);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onFragmentChange(Fragment fragment, boolean flag) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.content_frame, fragment, fragment.getClass().getName());
transaction.commit();
}
}
This is the Fragment which contains the ViewPager:
public class Fragment1 extends Fragment implements OnClickListener {
ICallback callback;
private LinearLayout headerContainer;
private ImageView headerLogo;
private TextView headerName;
private Button menuBarButton;
MyAdapter adapter;
ViewPager pager;
ActionBar actionBar;
private Button progOverview, progStr, bonusPoint;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof ICallback) {
this.callback = (ICallback) activity;
}
actionBar = activity.getActionBar();
actionBar.show();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = setUpView(inflater, container);
return rootView;
}
private View setUpView(LayoutInflater inflater, ViewGroup container) {
View rootView = inflater.inflate(R.layout.fragment_about_champions_club, container, false);
headerContainer = (LinearLayout) rootView.findViewById(R.id.second_top_header);
headerContainer.setBackgroundColor(getResources().getColor(R.color.prog_str_blue));
headerLogo = (ImageView) rootView.findViewById(R.id.header_logo);
headerLogo.setBackgroundResource(R.drawable.about_champions_ticon);
headerName = (TextView) rootView.findViewById(R.id.header_name);
headerName.setText(R.string.about_champ_title);
adapter = new MyAdapter(getFragmentManager());
pager = (ViewPager) rootView.findViewById(R.id.pager);
pager.setAdapter(adapter);
return rootView;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
// Restore last state for checked position.
}
}
}
}
This is one of the Fragments inside the ViewPager:
public class ProgramOverViewFragment extends Fragment {
ICallback callback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof ICallback) {
this.callback = (ICallback) activity;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_program_overview, container, false);
TextView termsAndCond = (TextView) rootView.findViewById(R.id.terms_and_condition_button);
termsAndCond.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content_frame, fragment);
fragment.setRetainInstance(true);
transaction.addToBackStack(null);
transaction.commit();
}
});
return rootView;
}
}
My FragmentStatePagerAdapter:
public class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int index) {
switch (index) {
case 0: return new ProgramOverViewFragment();
case 1: return new ProgramStructureFragment();
case 2: return new BonusPointFragment();
}
return null;
}
#Override
public int getCount() {
return 3;
}
}
Thanks for your help!
What do you want to do exactly? Are you trying to replace a Fragment inside the ViewPager? Or are you trying to replace a Fragment inside a Fragment inside the ViewPager? Or are you trying to do something different altogether? I can only give you an accurate solution if you explain what you are trying to do in detail. Anyway here is what I am guessing might be wrong:
I think your problem is that you use the wrong FragmentManager. There are multiple different FragmentManagers, but essentially there are two cases:
You want to add/replace/remove a Fragment from an Activity
You want to add/replace/remove a Fragment from another Fragment
As long as I don't see your layout files I can't be sure which of those two options fits your situation.
Solution if you want to replace a Fragment inside of another Fragment
If you want to perform a FragmentTransaction on a Fragment inside of another Fragment, then you need to use the child FragmentManager! You can use the child FragmentManager inside a Fragment like this:
FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content_frame, fragment);
fragment.setRetainInstance(true);
transaction.addToBackStack(null);
transaction.commit();
As you can see you just need to use getChildFragmentManager() instead of getSupportFragmentManager()
As I already said, without any further information about your situation I cannot give you a more accurate answer. So please try to explain what you want to do as best as you can to me and I'm confident we can solve this.
Finally i found what i did wrong in my code :
i'm using this below code for setting adapter for view Pager inside a fragment :
adapter = new MyAdapter(getFragmentManager());
pager = (ViewPager) rootView.findViewById(R.id.pager);
pager.setAdapter(adapter);
and by replacing getFragmentManager() to getChildFragmentManager() we resolve this problem. As per my understanding i'm using view pager inside a fragment that's why i have to use getChildFragment manager to store transitions of my viewPager.
Might this help someone and this question is still open for better solutions.