My question is similtar to this:
Android ViewPager Inside Fragment Loaded Only Once
The difference is that its answer doesn't work for me.
I have 4 fragments. Inside one of these fragments there is a Fragment X with ViewPager that switch betwen two other fragments. The first time I load the FragmentX the ViewPager works fine. The problem is if I switch to one of the other 4 fragments, when I go back to the FragmentX the ViewPager has nothing inside.
Fragment X
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_campus, container, false);
TabLayout tabLayout = (TabLayout)view.findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Mapa"));
tabLayout.addTab(tabLayout.newTab().setText("Eventos"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
vpPager = (ViewPager)view.findViewById(R.id.vpPager);
adapterViewPager = new PagerAdapter(getChildFragmentManager());
vpPager.setAdapter(adapterViewPager);
vpPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
vpPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
return view;
}
PageAdapter
public class PagerAdapter extends FragmentPagerAdapter {
private int NUM_ITEMS = 2;
public PagerAdapter(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:
return MapFragment.newInstance(0);
case 1:
return EventosFragment.newInstance(1);
default:
return null;
}
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
MainActivity
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
...
if (...) {
if (campusFragment == null) // the problem is not solved by commenting this condition
campusFragment = new CampusFragment(); // Fragment X
fragmentManager.beginTransaction().replace(R.id.content_frame, campusFragment).commit();
}
}
Related
I am working with TabLayout which shows tab icon red according to fragment selected in ViewPager. But I have been facing this problem for 2 weeks and I have been searching a lot to resolve this issue.
The problem is if I am at fragment user account and when I close the application, my user tab icon is selected. Now when I reopen the application fragment, my tab restaurant is loaded, but the user account tab icon is still selected, although restaurant tab icon should be selected.
I have attached screenshots for reference:
user account image
restaurant image after re open
public class PagerMainActivity extends Fragment {
//This is our tablayout
public TabLayout tabLayout;
public static CustomViewPager viewPager;
AdapterPager adapter;
public int tabIconColor_Selected;
public int tabIconColor_DeSelected;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// tabSelection();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_pager, container, false);
tabLayout = (TabLayout) v.findViewById(R.id.tab_layout);
viewPager = v.findViewById(R.id.pager);
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.restaurent).setText("Restaurant"));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.order).setText("Order"));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.deals).setText("Deals"));
tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.account).setText("Account"));
viewPager = v.findViewById(R.id.pager);
adapter = new AdapterPager(getActivity().getSupportFragmentManager(), tabLayout.getTabCount());
adapter.getRegisteredFragment(viewPager.getCurrentItem());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
viewPager.setAllowedSwipeDirection(SwipeDirection.none);
// setupTabIcons();
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
{
#Override
public void onTabSelected(TabLayout.Tab tabSelected)
{
viewPager.setCurrentItem(tabSelected.getPosition());
if(UserAccountFragment.LOG_OUT_FLAG || UserAccountFragment.LOG_IN_FLAG){
tabIconColor_Selected = ContextCompat.getColor(getContext(), R.color.colorDeal);
tabSelected.getIcon().setColorFilter(tabIconColor_Selected, PorterDuff.Mode.SRC_IN);
UserAccountFragment.LOG_OUT_FLAG=false;
UserAccountFragment.LOG_IN_FLAG=false;
}
tabIconColor_Selected = ContextCompat.getColor(getContext(), R.color.colorRed);
tabSelected.getIcon().setColorFilter(tabIconColor_Selected, PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabUnselected(TabLayout.Tab tabSelected){
viewPager.setCurrentItem(tabSelected.getPosition());
tabIconColor_DeSelected = ContextCompat.getColor(getContext(), R.color.colorDeal);
tabSelected.getIcon().setColorFilter(tabIconColor_DeSelected, PorterDuff.Mode.SRC_IN);
}
#Override
public void onTabReselected(TabLayout.Tab tabSelected){
}
});
return v;
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
Adapter
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
int mNumOfTabs;
public AdapterPager(FragmentManager fragmentManager, int tabCount) {
super(fragmentManager);
this.mNumOfTabs=tabCount;
}
#Override
public Fragment getItem(int position) {
Fragment fm=null;
switch (position) {
case 0:
fm = new RestaurantsFragment();
break;
case 1:
fm = new OrdersFragment();
break;
case 2:
fm = new DealsFragment();
break;
case 3:
fm = new UserAccountFragment();
break;
}
return fm;
}
#Override
public int getCount() {
return mNumOfTabs;
}
/* #Override
public Parcelable saveState() {
// Do Nothing
return saveState();
}*/
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
Your views and solution will be appreciated. Thanks in advance
I've built an Android app which uses fragments and action bar to create a tab layout. The app is made up of:
MainActivity.java
PagerAdapter.java
Tab1Fragment.java
Tab2Fragment.java
activity_main.xml
fragment_tab_1.xml
fragment_tab_2.xml
I have this working and I can switch between tabs. My question is how do I control the content of each tab? Obviously I can add my objects to each xml layout but where should I be identifying these objects in my java code? Should I be controlling the content in MainActivity.java or within each separate Fragment.java?
MainActivity.java:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Questions"));
tabLayout.addTab(tabLayout.newTab().setText("Ask a Question"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Tab1Fragment.java:
public class Tab1Fragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab_1, container, false);
}
}
PagerAdapter.java:
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Tab1Fragment tab1 = new Tab1Fragment();
return tab1;
case 1:
Tab2Fragment tab2 = new Tab2Fragment();
return tab2;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
You should reference all of the views within the Fragment code. The views within are defined in that specific Fragment's xml layout file, so the Activity will not be able to reference them easily.
Example:
public class Tab1Fragment extends Fragment {
Button button;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab_1, container, false);
button = (Button) view.findViewById(R.id.button);
//Get all views here
return view; //Must return a view
}
}
I am not clearly understand what you ask but i think you are asking where to code for the specific tabview the answer is in Tab1Fragment and Tab2Fragment.
Hi I have a TabLayout and ViewPager inside a fragment. But I can not slide beetween tab to come to child fragment (Working normally when in Activity but not work in fragment).
Here is my code for Tablayout inside fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View inflateView = inflater.inflate(R.layout.fragment_assign_beacon_to_event, container, false);
//Viewpager and TabLayout
viewPager = (ViewPager)inflateView.findViewById(R.id.viewPager);
viewPager.setAdapter(new CustomAdapter(getFragmentManager(), getContext()));
tabLayout = (TabLayout)inflateView.findViewById(R.id.tabLayout);
// Inflate the layout for this fragment
return inflateView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
});
Any here is my Custom Adapter class
private class CustomAdapter extends FragmentPagerAdapter {
private String fragments[] = {"Assign Event", "Manage Event"};
public CustomAdapter(FragmentManager supportFragmentManager, Context applicationContext) {
super(supportFragmentManager);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
// return new AssignEventToBeacon();
return new Test1();
case 1:
return new ManageEventAssigned();
default:
return null;
}
}
#Override
public int getCount() {
return fragments.length;
}
#Override
public CharSequence getPageTitle(int position) {
return fragments[position];
}
}
I doubt i have problem with this line:
viewPager.setAdapter(new CustomAdapter(getFragmentManager(), getContext()));
Anyhelp is much appreciate, thanks
I have done a similar project and here is my code for the fragment :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.outer_fragment, container, false);
setHasOptionsMenu(true);
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
if (viewPager != null) {
setupViewPager(viewPager);
}
Log.v("Layout","Tabs");
TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#FFFFFF"));
tabLayout.setTabTextColors(Color.parseColor("#707070"), Color.parseColor("#FFFFFF"));
assert viewPager != null;
tabLayout.setupWithViewPager(viewPager);
return view;
}
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getChildFragmentManager());
adapter.addFragment(new Tab1Fragment(), "PHOTOS");
adapter.addFragment(new Tab2Fragment(), "HI-FIVES");
viewPager.setAdapter(adapter);
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public Adapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
You need to use getChildFragmentManager() in Fragment instead of getFragmentManager().
From getChildFragmentManager() documentation
Return a private FragmentManager for placing and managing Fragments
inside of this Fragment.
From getFragmentManager() documentation
Return the FragmentManager for interacting with fragments associated
with this fragment's activity.
In simple words,
Use getChildFragmentManager() for Child Fragments
Use getFragmentManager() for Fragments inside Activity
One can see #this answer for complete code.
I am using ViewPager with my fragments. All fragments has animation and it does not work when switching back maybe because ViewPager saves somehow state of near Fragments, do you have some idea how to avoid it?
getItemPosition() doesn't make anything in this case
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return GetStartedOneFragment.newInstance();
case 1:
return GetStartedTwoFragment.newInstance();
case 2:
return GetStartedThreeFragment.newInstance();
case 3:
return GetStartedFourFragment.newInstance();
case 4:
return GetStartedFiveFragment.newInstance();
case 5:
return GetStartedSixFragment.newInstance();
default:
return GetStartedOneFragment.newInstance();
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
I used a Fragment as a slider content, see the sample code below. Feel free to ask more details if required.
I have 4 flight modes in the example. The ViewPager is used with the associated adapter (ScreenSlidePagerAdapter).
You can see the app in the Play Store to see the slider (search "Flight Recorder 24").
// In the main fragment java code
private View headerView;
private ViewPager mPager;
public ScreenSlidePagerAdapter mPagerAdapter;
// ...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View mainView = inflater.inflate(R.layout.monitoring_fragment,container, false);
// The header of the list
View view = inflater.inflate(R.layout.header_monitoring_fragment, mListView, false);
headerView = view;
//...
mPager = (ViewPager) view.findViewById(R.id.pager);
FragmentManager fm = getChildFragmentManager();
mPagerAdapter = new ScreenSlidePagerAdapter(fm);
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(UserConfiguration.getUserConf().getPositionFromFlightMode());
// Attach the page change listener inside the activity
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
// This method will be invoked when a new page becomes selected.
#Override
public void onPageSelected(int position)
{
int flight_mode = UserConfiguration.getFlightModeFromPosition(position);
UserConfiguration.getUserConf().setFlightMode(flight_mode);
}
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int state)
{
// Code goes here
}
});
// ...
}
// ...
// Slider adapter
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter
{
public ScreenSlidePagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
// position to flight mode
int flight_mode = UserConfiguration.getFlightModeFromPosition(position);
FlightModeFragment flightModeFragment = FlightModeFragment.newInstance(flight_mode);
return flightModeFragment;
}
public int getItemPosition(Object object)
{
return POSITION_NONE;
}
#Override
public int getCount()
{
return 4;
}
}
Then you have to create a Fragment with your slider content (here the class FlightModeFragment), it will be instanciated with an integer to identify the page embedded into a Bundle savedInstanceState (I have 4 pages).
public class FlightModeFragment extends Fragment
{
LinearLayout mainLayout;
ImageView live15minImageView;
ImageView modeImageView;
ImageView imageViewLeft;
ImageView imageViewRight;
private TextView textViewRecord;
private TextView textViewGps;
int flight_mode = UserConfiguration.AC_LISTENER_TRAVEL_RECORDER_MODE;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// handle fragment arguments
Bundle arguments = getArguments();
if(arguments != null)
{
flight_mode = arguments.getInt("flight_mode");
}
}
// ...
}
Hi Im new in android and I want ask for help. Im creating new project in android studio and I use navigation Action bar tabs with viewpager. Android studio generate this code. I know work with one activity atc but now I want to learn work with swipe layouts with tabs. My question is: Is possible do more layouts with different items inside this? For example, now I have on every fragment one textview and when I swipe I see any text on every page. But I need for example on page(tab1) layout with textview, on tab2 I need layout edittext, on tab3 I need layout with image. Is this possible with this? Because I can change text but now I have the same layout for all tabs.
public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
}
In this case you can define 3 separate fragment classes. Then you can return them appropriately in getItem of your SectionsPagerAdapter:
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new YourFragmentClass1();
case 1:
return new YourFragmentClass2();
case 2:
return new YourFragmentClass3();
}
}
To elaborate on Szymon's answer.
Step 1 Delete the inner class PlaceHolderFragment
Step 2: Create your fragment classes, with corresponding layouts. For example, ImageViewFragment (which extends Fragment of course) and then image_view_fragment_layout.
Step 3 Have ImageViewFragment's onCreateView method inflateimage_view_fragment_layout.
public ImageViewFragment extends Fragment {
...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.image_view_fragment_layout,
container, false);
return rootView;
}
Follow these steps for as many tabs you want to add.
Then in the getItem() method follow Szymon's answer. Remember, the tab you want to appear first will be in position 0 and so on.
One more Important thing, in your getCount method:
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
the number returned should reflect the number of tabs you have added.