Android: ViewPager - adding Fragments - android

I am trying to add a ViewPager, but I am am having problems adding new fragments. I followed a tutorial to create it where the on each swipe the SAME fragment was used with only a TextView in the fragment changing changing.
The fragment that works is called MyFragment. ( I don't know why this works and the others don't.
I don't want to use this fragment as I have different fragments that I have already made (that work fine). I want to add for example a fragment called ReminderFragment
I tried adding a switch and case to the getItem() method, but I get an error saying: "Type mismatch: cannot convert from name of fragment to Fragment".
This is the code of my FragmentActivity - it holds the FragmentPagerAdapter inside it (I don't know if this is a good way or not):
// Removed imports, package name
public class PageViewActivity extends FragmentActivity {
MyPageAdapter pageAdapter;
private ViewPager pager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_pager_activity); // Sets the layout to an xml which includes a viewpager
List<Fragment> fragments = getFragments();
pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
pager = (ViewPager)findViewById(R.id.viewpager);
pager.setAdapter(pageAdapter);
pager.setCurrentItem(1);
pager.setPageTransformer(true, new ZoomOutPageTransformer());
}
#Override
public void onBackPressed() {
if (pager.getCurrentItem() == 1) {
super.onBackPressed();
} else if (pager.getCurrentItem() == 0){
pager.setCurrentItem(pager.getCurrentItem() + 1);
}
else if (pager.getCurrentItem() == 2){
pager.setCurrentItem(pager.getCurrentItem() - 1);
}
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
// I don't know how to change this to work with my fragments
fList.add(MyFragment.newInstance("Page 0")); // MyFragment is the fragment I don't need, but it is the only fragment that works!
fList.add(MyFragment.newInstance("Page 1"));
fList.add(MyFragment.newInstance("Page 2"));
return fList;
}
private class MyPageAdapter extends FragmentPagerAdapter { // Sets what MyPagerAdapter is
private List<Fragment> fragments; // Defines a list of fragments called fragments
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) { // Sets what is inside the MyPagerAdapter
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int index) {
// return this.fragments.get(index);
switch (index){
case 0: return new ReminderFragment(); // This is where I get errors
case 1: return new QuickNoteFragment();
}
}
#Override
public int getCount() {
return this.fragments.size();
}
}
}
This is the code of the ReminderFragment. This does not work as I get the error above
// Removed stuff
public class ReminderFragment extends Fragment implements OnClickListener{
public static final String ARG_nOTERACTIVITY_NUMBER = "noter_activity";
// Removed stuff
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View remView = inflater.inflate(R.layout.reminder, container, false);
int i = getArguments().getInt(ARG_nOTERACTIVITY_NUMBER);
String noter_activity = getResources().getStringArray(
R.array.noter_array)[i];
// Removed stuff
getActivity().setTitle(noter_activity); // For navigation drawer(?)
return remView;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()) {
case R.id.***: // Does stuff
case R.id.***:
break;
}
}
}
public static Fragment newInstance() { // Is this necessary
// TODO Auto-generated method stub
ReminderFragment remFrag = new ReminderFragment();
return remFrag;
}
}
I know there are two methods of adding the fragments here - I just trying to show what I have tried :-). I am very confused!
Thank you

Looks that you imported Fragments from the support package in all the class. The import should be android.support.v4.app.Fragment or android.app.Fragment (if you are targeting API level 11) in all the class

Related

How to return multiple fragments from FragmentPagerAdapter

If I use a TabLayout with FragmentPagerAdapter, the overridden function getItem(int position) just return one fragment. In case of lager screen I would like to have 2 fragments to be returned.
How can I do it? should wrap these 2 fragments into one fragment and use that instead or is there any better solution?
FragmentPagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: //Ingredients
return IngredientsFragment.newInstance(mRecipe);
case 1: // Details
{
// TODO Here instead of DetailFragment I want to return
// two fragments called DetailFragment and StepFragment.
return DetailFragment.newInstance(mRecipe);
}
default:
throw new RuntimeException(this.toString() + " Wrong fragment!");
}
}
And then in my Activity onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
// Initializing, etc.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
}
I do not see you have much of a wiggle room here.
These two options are exlusive:
You are returning one Fragment with two nested fragments (Wrapped fragment)
You are returning two fragments each anchored to his own tab.
If you would like two fragments to appear on singular page of ViewPager, you have no choice but to wrap them.
Otherwise swiping would go between these two fragments, which is the same as if they are completely different, that is non-correlated.
OK I managed to solve the problem using a Fragment consist of two other fragments as children.
Just do not forget in this case the FragmentManager object should be populated with getChildFragmentManager() to work properly.
For more info look at my BakingApp project DetailStepWideScreenFragment.java
GitHub Repos
Fragment Wrapper:
public class DetailStepWideScreenFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_detail_step_wide_screen, container, false);
// I added the fragments here. StepFragment can be replaced using
// replaceStepFragment function.
DetailFragment detailFragment = DetailFragment.newInstance(mRecipe);
StepFragment stepFragment = StepFragment.newInstance(mRecipe, mStepId);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.fl_detail_fragment_wide_screen, detailFragment);
transaction.add(R.id.fl_step_fragment_wide_screen, stepFragment);
transaction.commit();
return view;
}
public void replaceStepFragment(String stepId) {
mStepId = stepId;
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
StepFragment stepFragment = StepFragment.newInstance(mRecipe, mStepId);
transaction.replace(R.id.fl_step_fragment_wide_screen, stepFragment);
transaction.commit();
}
}
PagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private DetailStepWideScreenFragment currentFragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
currentFragment = null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0: //Ingredients
return IngredientsFragment.newInstance(mRecipe);
case 1: // Details
{
// Show base on screen size.
if (mIsLargeScreen) {
DetailStepWideScreenFragment detailStepWideScreenFragment = DetailStepWideScreenFragment.newInstance(mRecipe, "0");
currentFragment = detailStepWideScreenFragment;
return detailStepWideScreenFragment;
} else {
return DetailFragment.newInstance(mRecipe);
}
}
default:
throw new RuntimeException(this.toString() + " Wrong fragment!");
}
}
#Override
public int getCount() { return 2; }
public DetailStepWideScreenFragment getCurrentFragment() {
return currentFragment;
}
}

android-viewpager with multiple sub-fragments in each tab

This is giving me headache. Lets say my app has a ViewPager which contains 4 tabs. I want to have multiple sub-fragments within each tab. that means each tab would have more than just one view. I totally have no clue how to achieve this....
I have a FragmentActivity which gets load first and set my ViewPager
public class FragActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frag_main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
PagerAdapter adapter = new FFNPagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
pager.setOffscreenPageLimit(3);
tabs.setViewPager(pager);
}
}
I then have my FragmentPagerAdapter
public class PagerAdapter extends FragmentPagerAdapter implements TextAndIconTabProvider {
private final String[] TITLES = { "FIRST", "SECOND", "THIRD", "FORTH" };
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment frag = new Fragment();
switch (position) {
case 1:
frag = new FirstFrag();
break;
case 2:
frag = new SecondFrag();
break;
case 3:
frag = new ThirdFrag();
break;
case 4:
frag = new ForthFrag();
break;
}
return frag;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return TITLES.length;
}
}
the above would give me a working ViewPager with 4 active tabs. Then I need to do all 4 individual Fragments. I'm giving out one example below.
public class FirstFrag extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.firstfrag, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Button btn1 = (Button) getActivity().findViewById(R.id.btn1);
btn1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// what should I put in this block??????
Fragment fragment = new FirstFragSub1();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.pager, fragment); //<<------what should i replace???????
transaction.commitAllowingStateLoss();
}
});
}
}
The OnCreateView in FirstFragSub1 gets called but I don't see anything displayed on the screen. Basically just a blank. I know by replacing R.id.pager should not be the correct way, I'm just giving out an example of what I initial thought was.
Here is my FirstFragSub1
public class FirstFragSub1 extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
Log.i("FirstFragSub1","onCreateView is called");
return inflater.inflate(R.layout.subone, container, false);
}
}
Can someone please help me? I really out of idea...Thanks
there is a great tutorial and github here that covers this in detail.
http://tausiq.wordpress.com/2014/06/06/android-multiple-fragments-stack-in-each-viewpager-tab/
https://github.com/tausiq/ViewPagerMultipleFragmentDemo
this covers handling the backstack and multiple tabs with multiple views per tab. hope this help I was searching for a similar solution when i read your question.
Have FrameLayouts in the view that is being inflated by the Fragment. And onCreateView, replace the FrameLayout by the sub fragments that you want.
Also, be careful not to use the Activity's FragmentManager. getFragmentManager returns the Activity's FragmentManager and that will lead to an undesirable result (Only one fragment inside your ViewPager would have the sub fragments loaded). Use the getChildFragmentManager function instead.

Change Fragment with ViewPager

I am using PagerSlidingTab Library for ViewPager. And I want to change Fragment while scrolling of tabs. It is working fine. Check out my code.
I am using AsynTask() on each Fragment.
When the App opens with the MainActivity, First Fragment is attached to the activity, But It shows two AsynTask() dialog message, one from First and another from Second Fragment. And When I scroll to second tab, It shows dialog message of Third Fragment.
So, If I scroll from left to right in tabs, the Fragment right to the current fragment is displayed and if i scroll from right to left, the Fragment left to the current Fragment is displayed.
Please help me to solve the problem.
My Code:
public class PageSlidingTabStripFragment extends Fragment {
public static final String TAG = PageSlidingTabStripFragment.class
.getSimpleName();
public static PageSlidingTabStripFragment newInstance() {
return new PageSlidingTabStripFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.pager, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) view
.findViewById(R.id.tabs);
ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
MyPagerAdapter adapter = new MyPagerAdapter(getChildFragmentManager());
pager.setAdapter(adapter);
tabs.setViewPager(pager);
}
public class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
private final String[] TITLES = { "Instant Opportunity", "Events",
"Experts" };
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new InstantOpportunity();
case 1:
return new Events();
case 2:
return new Experts();
default:
break;
}
return null;
}
}
}
Explanation:
It turns out there is an easier implementation for scrollable tabs which doesn't involve another library. You can easily implement tabs into your app using normal Android code straight from the default SDK.
The Code
Main Class:
public class PageSlidingTabStripFragment extends Fragment {
//Variables
private ViewPager viewPager;
private PagerTitleStrip pagerTitleStrip;
public PageSlidingTabStripFragment() {
// Required empty public constructor
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//Find your pager declared in XML
viewPager = (ViewPager) getView().findViewById(R.id.pager);
//Set the viewPager to a new adapter (see below)
viewPager.setAdapter(new MyAdapter(getFragmentManager()));
//If your doing scrollable tabs as opposed to fix tabs,
//you need to find a pagerTitleStrip that is declared in XML
//just like the pager
pagerTitleStrip = (PagerTitleStrip)
getView().findViewById(R.id.pager_title_strip);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.[your layout name here], container, false);
}
}
Adapter:
//Note: this can go below all of the previous code. Just make sure it's
//below the last curly bracket in your file!
class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
Fragment fragment = null;
if (arg0 == 0) {
fragment = new InstantOpportunity();
}
if (arg0 == 1) {
fragment = new Events();
}
if (arg0 == 2) {
fragment = new Experts();
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
if (position == 0) {
return "Instant Opportunity";
}
if (position == 1) {
return "Events";
}
if (position == 2) {
return "Experts";
}
return null;
}
}
Conclusion:
I hope this helps you understand another way to make scrollable tabs! I have examples on my Github Page about how to make each type (That being Fixed or Scrollable).
Links:
Fixed Tabs Example - Click Here
Scrollable Tabs Example - Click Here
Hope this helps!
Edit:
When asked what to import, make sure you select the V4 support fragments.
please use this example..its very easy.i already implement that.
reference link
hope its useful to you.its best example of pager-sliding-tabstrip.
Use
framelayout compulsory:
FrameLayout fl = new FrameLayout(getActivity());
fl.addView(urFragementView);
and then set your fragement view in this framelayout.

Access TextView in ViewPager from Activity

I have an Activity with a ViewPager containing multiple fragments. how can i now access a TextView in one of that fragments to change its text from the main activity? I tried multiple ways and they all ended in a NullPointerException.
Activity:
public class SummonerOverview extends SherlockFragmentActivity implements TabListener, OnPageChangeListener {
private ViewPager mPager;
private PagerAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.summoner_overview);
initialize();
}
private void initialize() {
// initialize Pager
mPager = (ViewPager) findViewById(R.id.viewpager);
mAdapter = new PagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(1);
mPager.setOnPageChangeListener(this);
}
}
PagerAdapter:
public class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
frags = new Fragment[3];
frags[0] = new StatisticsFragment(0);
frags[1] = new RatingsFragment(1);
frags[2] = new HistoryFragment(2);
}
private final int NUM_PAGES = 3;
Fragment[] frags;
#Override
public Fragment getItem(int arg0) {
if (arg0 == 0)
return frags[0];
else if (arg0 == 1)
return frags[1];
else
return frags[2];
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
The Fragment:
public class StatisticsFragment extends SherlockFragment {
public StatisticsFragment(int fragNr) {
this.fragNr = fragNr;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_overview_statistics, container, false);
return v;
}
}
The Textview in the StatisticsFragment is labeled with an id in the fragment_overview_statistics.xml, but when i try
TextView tv = (TextView) findViewById(R.id.id_of_the_textview)
tv.setText("text");
from within the onCreate() Method of the Activity after the initialize() Method, i get an Exception.
Okay, after another hour of googling, i think i solves my own question (although i'm sure there is a better method to solve that)
I now hold all the Data that is displayed by the fragments in the MainActivity and make the Fragmets consume this Data in their onCreateView() Method by using public Methods of the Activity.
In the PagerAdapter, i overwrote getItemPosition() to:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Now, everytime i update some of the Data, i also call mAdapter.notifyDataSetChanged() which leads into a recreation of all fragments.
It works, although it looks like a poor hack for me. Im sure there must be a better solution because now i have to recreate all fragments for changing one TextView of one Fragment, what is surely not the way it is intended to be done.

Three fragment within viewpager

I have this problem as you can see in the pictures below:
1) http://imageshack.us/photo/my-images/19/schermata20120512a09444.png/
2) http://imageshack.us/photo/my-images/651/schermata20120512a09444.png/
I have done one viewpager with three fragment , but when scroll, I see one of them, i would see two fragments.
my cose is:
public class FragmentProjetSwipePageActivity extends FragmentActivity {
// derived from http://thepseudocoder.wordpress.com/2011/10/05/android-page-swiping-using-viewpager/
// list contains fragments to instantiate in the viewpager
List<Fragment> fragmentsV1 = new Vector<Fragment>();
// page adapter between fragment list and view pager
private PagerAdapter mPagerAdapter;
// view pager
private ViewPager mPager;
// activity data
public String p2text,p3text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// creating fragments and adding to list
fragmentsV1.add(Fragment.instantiate(this,Page1Fragment.class.getName()));
fragmentsV1.add(Fragment.instantiate(this,Page2Fragment.class.getName()));
fragmentsV1.add(Fragment.instantiate(this,Page3Fragment.class.getName()));
// creating adapter and linking to view pager
mPager = (ViewPager) super.findViewById(R.id.pager1);
this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(),fragmentsV1,this );
mPager.setAdapter(this.mPagerAdapter);
//Set a listener that will be invoked whenever the page changes or is incrementally scrolled.
}
}
PagerAdapter.java
public class PagerAdapter extends FragmentPagerAdapter {
// fragments to instantiate in the viewpager
private List<Fragment> fragments;
FragmentManager fm;
private static int NUM_PAGER_VIEWS = 2;
Context contex;
// constructor
public PagerAdapter(FragmentManager _fm,List<Fragment> fragments) {
super(_fm);
this.fragments = fragments;
fm=_fm;
}
// return access to fragment from position, required override
#Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
// number of fragments in list, required override
#Override
public int getCount() {
return NUM_PAGER_VIEWS;
//return this.fragments.size();
}
}
thanks

Categories

Resources