How to add backstack to viewpager with fragmentManager and FragmentPagerAdapter - android

How to add backstack to viewpager
How do we manage to go to previous fragment from the current fragment
I have got the fragment part working , now I am trying to learn to manage the naviation of fragments by the back button
Here is the main activity which contains three fragments
public class MainActivity extends FragmentActivity {
ViewPager viewpager = null;
LinearLayout lay;
#Override
protected void onCreate(Bundle savedInstancestate) {
// TODO Auto-generated method stub
super.onCreate(savedInstancestate);
setContentView(R.layout.activity_main);
viewpager = (ViewPager) findViewById(R.id.pager);
viewpager.setPageTransformer(true, new DepthPageTransformer());
FragmentManager fragmentManager = getSupportFragmentManager();
viewpager.setAdapter(new myAdaper(fragmentManager));
PagerTitleStrip pagerTitleStrip = (PagerTitleStrip)findViewById(R.id.pager_title_strip);
pagerTitleStrip.setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
// pagerTitleStrip.setTextColor(Color.BLUE);
}
class myAdaper extends FragmentPagerAdapter {
public myAdaper(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public Fragment getItem(int i) {
// TODO Auto-generated method stub
Fragment fragment = null;
if (i == 0) {
fragment = new fragmentA();
}
if (i == 1) {
fragment = new fragmentB();
}
if (i == 2) {
fragment = new fragmentC();
}
return fragment;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
String title = new String();
SpannableStringBuilder sb = new SpannableStringBuilder(""+ position);
if (position == 0) {
return "Tab1";
}
if (position == 1) {
return "Tab2";
}
if (position == 2) {
return "Tab3";
}
return null;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
}
And the fragments are
public class fragmentA extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment_a,container, false);
}
}
these are repeated with same code just diff color for the other two fragments fragment B and fragment C
now if
I am on fragment C i want ot go back to fragment B and
if I am on Fragment B i want to go to Fragment A

Store in a variable wich is your current page (you can get it with the ViewPager.OnPageChangeListener). Then override the onBackPressed()method of your activity and change to the previous of your viewpager with setCurrentItem(int item)
If you are in the first fragment just call super.onBackPressed()

Related

how to stop swabbing one fragment in FragmentManager

hi every one I'm working on android application that will contain a set for fragments, an the problem I need to make the fragment 1 working only by the menu and not working by finger swab.
and this is my code.
public class MainActivity extends FragmentActivity {
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
FragmentManager fm = getSupportFragmentManager();
viewPager.setAdapter(new MyAdapter(fm));
}
}
class MyAdapter extends FragmentPagerAdapter
{
public MyAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public Fragment getItem(int i) {
// TODO Auto-generated method stub
Log.d("MASAFA", "get item is called " + i);
Fragment fragment = null;
if (i == 0)
{
fragment = new FragmentA();
}
if (i == 1)
{
fragment = new FragmentB();
}
if (i == 2)
{
fragment = new FragmentC();
}
return fragment;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
Log.d("MASAFA", "get count is called");
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
// TODO Auto-generated method stub
if (position == 0)
{
return "Tab 0";
}
if (position == 1)
{
return "Tab 1";
}
if (position == 2)
{
return "Tab 2";
}
return null;
}
}

How to get the selected page index of ViewPager in fragment

I'm making use of ViewPagerIndicator, and I have my adapter defined like this:
public class MyPagerAdapter extends FragmentPagerAdapter implements
IconPagerAdapter {
private final static String TAB_ITEMS[] = { "Tab 1", "Tab 2", "Tab 3", "Tab 4"};
private int count = TAB_ITEMS.length;
public MyPagerAdapter (FragmentManager fm) {
super(fm);
}
#Override
public int getIconResId(int index) {
// TODO Auto-generated method stub
return 0;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new BaseFragment();
return fragment;
}
#Override
public int getCount() {
return count;
}
And this is my activity that will contain my fragments:
public class MyActivity extends FragmentActivity implements
OnPageChangeListener {
private int tabPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
MyPagerAdapter adapter = new MyPagerAdapter (
getSupportFragmentManager());
pager.setAdapter(adapter);
UnderlinePageIndicator indicator = (UnderlinePageIndicator) findViewById(R.id.indicator);
indicator.setFades(false);
indicator.setViewPager(pager);
indicator.setOnPageChangeListener(this);
}
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
// TODO Auto-generated method stub
}
#Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
setTabPosition(position);
Toast.makeText(MyActivity.this,
"Changed to page: " + position, Toast.LENGTH_SHORT).show();
}
public void setTabPosition(int position) {
this.tabPosition = position;
}
public int getTabPosition() {
return this.tabPosition;
}
}
Finally the definition of BaseFragment:
public class BaseFragment extends Fragment implements OnItemClickListener {
private final static String TAG = "BaseFragment";
private int tabPosition;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_base, container,
false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
tabPosition = ((MyActivity) getActivity()).getTabPosition();
Toast.makeText(getActivity(), "page " + tabPosition, Toast.LENGTH_SHORT)
.show();
}
Now , this is my problem:
The toast in onPageSelected of the activity always shows the correct page when a new page is selected or swiped to.
However, the toast in my fragment only shows the correct page when you swipe to either page 1 or page 2. The only time it toasts page 0 is anytime the app is launched. After that, when the user swipes to page 0 or page 4, no toast is shown at all, not even an empty toast.
I wrote the getTabPosition() and setTabPosition() methods with the intention of getting the current selected tab position in the fragment, but it obviously doesn't work correctly hence I dont get toasts on pages 0 and 4.
My question is: how do I get the selected page position in my BaseFragment, since I need that position to load the appropriate data?
Hope I was clear enough?
Each Fragment will display a different set of data, then maybe it is a good idea to have one fragment for each. Here is what I did to display different Fragments for different data in the FragmentPagerAdapter:
#Override
public Fragment getItem(int index) {
Fragment fragment = null;
// Define the page for each index
switch(index){
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
case 2:
fragment = new Fragment3();
break;
}
This may not be the best approach but in your activity that holds reference to ViewPager try this:
public class TabbedViewActivity extends FragmentActivity {
ViewPager viewPager;
public static int tabIndex = 0;
#Override
protected void onCreate(Bundle bundle) {
......
viewPager = (ViewPager)findViewById(R.id.pager);
TabbedViewActivity.tabIndex = 0; // in the start index is always 0 unless coded otherwise
viewPager.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
TabbedViewActivity.tabIndex = position;
}
});
}
Then you can always access this variable statically like this in your Fragment TabbedViewActivity.tabIndex
pager.getCurrentItem();
it return current fragment index

How to access method in fragment from different class?

I have navigational drawer and fragment for each drawer item. Now Under each fragment we have created multiple fragments using FragmentPagerAdapter.
I've 3 drawer items as Home, Group and Feedback. Under Home, there are 2 fragments i.e My Profile and Logged
so i've created a swipeable tabs for My Profile and Logged and these two fragments are under home item. Now i've to do some network calls in both the fragments(My Profile, Logged) but how to identify which fragment is active on FragmentPagerAdapter? Is it possible to stop adapter to create fragments in advance.
HomeFragment
DrawerModel model = new DrawerModel();
LoggedFragment loggedFrag = new LoggedFragment();
loggedFrag.setTargetFragment(loggedFrag, 0);
model.setFragment(loggedFrag);
dFragments.add(model);
model = new DrawerModel();
model.setDrawerTitle(getString(R.string.profile_tab_title));
model.setFragment(new ProfileFragment());
dFragments.add(model);
Bundle bundle = new Bundle();
bundle.putSerializable("fragments", dFragments);
fragment = new DrawerFragment();
fragment.setArguments(bundle);
navigateFragment(fragment);
DrawerFragment
public class DrawerFragment extends Fragment {
private FragmentAdapter pagerAdapter;
private ViewPager mViewPager;
private ArrayList<DrawerModel> fList;
#SuppressWarnings("unchecked")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
fList = (ArrayList<DrawerModel>) getArguments().getSerializable(
"fragments");
View v = inflater.inflate(R.layout.swipe_tabs, container, false);
pagerAdapter = new FragmentAdapter(getChildFragmentManager(), fList);
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mViewPager.setAdapter(pagerAdapter);
return v;
}
}
FragmentAdapter
public class FragmentAdapter extends FragmentStatePagerAdapter {
private int TOTAL_TABS = 0;
private ArrayList<DrawerModel> fragmentList;
private SparseArray<Fragment> mPageReference = new SparseArray<Fragment>();
public FragmentAdapter(FragmentManager fm, ArrayList<DrawerModel> fList) {
super(fm);
// TODO Auto-generated constructor stub
TOTAL_TABS = fList.size();
fragmentList = fList;
}
#Override
public Fragment getItem(int position) {
// TODO Auto-generated method stub
return fragmentList.get(position).getDrawerFragment();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return TOTAL_TABS;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
// TODO Auto-generated method stub
Fragment fragment = (Fragment) super.instantiateItem(container,
position);
mPageReference.put(position, fragment);
Log.d("FragmentAdapter - OnCreate", mPageReference.size() + "");
return fragment;
}
#Override
public CharSequence getPageTitle(int position) {
// TODO Auto-generated method stub
return fragmentList.get(position).getDrawerTitle();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
mPageReference.remove(position);
Log.d("FragmentAdapter - onDestroy", mPageReference.size() + "");
super.destroyItem(container, position, object);
}
public Fragment getFragment(int key) {
return mPageReference.get(key);
}
}
Logged Fragment
public class LoggedFragment extends Fragment implements OnClickListener {
TextView tHeader, tEmail, tvPhone;
SharedPreferences sp;
ImageView ivAds;
String bannerUrl = null;
private Handler handler = new Handler();
private static final String TAG = "LoggedFragment";
private void addListeners() {
// TODO Auto-generated method stub
ivAds.setOnClickListener(this);
}
Runnable updateImage = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if (Utility.checkConnectivity(getActivity()))
new ImageTask((Home_Activity) getActivity(), "Logged")
.execute();
handler.postDelayed(this, Utility.AD_DURATION);
}
};
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
if (handler != null)
handler.post(updateImage);
}
#Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
if (handler != null)
handler.removeCallbacks(updateImage);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View v = inflater.inflate(R.layout.logged_in, container, false);
bindComponents(v);
addListeners();
return v;
}
private void bindComponents(View v) {
// TODO Auto-generated method stub
ivAds = (ImageView) v.findViewById(R.id.ivLoggedAds);
}
public void updateBanner(Bitmap bitmap, String url) {
ivAds.setImageBitmap(bitmap);
bannerUrl = url;
}
}
Call to update fragment method
Fragment fragment = activity.getSupportFragmentManager()
.findFragmentById(R.id.content_frame)
.getTargetFragment();
if (fragment instanceof LoggedFragment) {
LoggedFragment logged = (LoggedFragment) fragment;
logged.updateBanner(result, parameter[1]);
} else
Log.d(TAG, "No Logged Fragment Found");
Now under logged and my profile fragment i need to fetch some data dynamically as soon fragment is visible to user but unable to do so?
Any ideas/suggestions is highly appreciated.
use below code to find your fragment,
FragmentAdapter pa = (FragmentAdapter)viewPager.getAdapter();
pa.getFragment(viewPager.getCurrentItem()).updateBanner();
the code select current visible fragment you can change it to other one by
pa.getFragment(index of other fragment).updateBanner();
you must cast pa.getFragment(viewPager.getCurrentItem()) to what fragment you want for example if at that position it is logged change it to below:
((LoggedFragment)pa.getFragment(viewPager.getCurrentItem()) )
I would say you have two differnt options.
Option one: Use setTargetFragment() and getTargetFragment() so you get a reference to that fragment you need.
Option two: Use the FragmentManager simply get that Fragment you need from the FragmentManager and call that methods you defined on your Fragment.

How to put swipe tab views inside one of navigation drawer option

Updated code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
viewPager = (ViewPager)view.findViewById(R.id.base_pager);
FragmentManager manager = getChildFragmentManager();
viewPager.setAdapter(new MyFragmentPagerAdapter(manager));
return rootView;
}
class HomeFragment extends FragmentPagerAdapter {
public HomeFragment(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public android.support.v4.app.Fragment getItem(int item) {
// TODO Auto-generated method stub
android.support.v4.app.Fragment fragment = null;
if (item == 0) {
//MapFragment.message("Map");
fragment = new MapFragment();
} else if (item == 1) {
//SavedLocationsFragment.message("locations");
fragment = new MapFragment();
} /*else if (item == 2) {
fragment = new FragmentC();
}*/
return fragment;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
// TODO Auto-generated method stub
String title = new String();
if (position == 0) {
title = "Map";
} else if (position == 1) {
title = "savedLocations";
}
return title;
}
}
I am getting error on this onCreateView method;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
viewPager = (ViewPager)view.findViewById(R.id.base_pager);
FragmentManager manager = getChildFragmentManager();
viewPager.setAdapter(new MyFragmentPagerAdapter(manager));
return rootView;
}
The error are;
The annotation #Override is disallowed for this location
Syntax error on token "View", # expected
Syntax error on token "LayoutInflater", = expected after this token
Syntax error on token "ViewGroup", = expected after this token
Syntax error on token "Bundle", = expected after this token
in your home fragment do this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_activity, container, false);
viewPager = (ViewPager)view.findViewById(R.id.base_pager);
FragmentManager manager = getChildFragmentManager();
viewPager.setAdapter(new MyFragmentPagerAdapter(manager));
return view;
}
class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public android.support.v4.app.Fragment getItem(int item) {
// TODO Auto-generated method stub
android.support.v4.app.Fragment fragment = null;
if (item == 0) {
fragment = new PhotoCommnFragment();
} else if (item == 1) {
fragment = new ShowRestaurant();
} /*else if (item == 2) {
fragment = new FragmentC();
}*/
return fragment;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
// TODO Auto-generated method stub
String title = new String();
if (position == 0) {
title = "Map";
} else if (position == 1) {
title = "Restaurant";
} else if (position == 2) {
title = "Table 2";
}
return title;
}
}
now from this you would be able to call your child fragment of home, it like this
your mainActivity is mother then you home fragment is child of your mainActivity.
and in your home fragment is hosting Reasturant and Map Fragment.
kindly check how to you dex2jar, if you can't i will mail you relevant code

Fragment to Fragment communication with FragmentStatePagerAdapter

I'm trying to update the text of my TextView in my FragmentB through the Button in my FragmentA. But whenever I click the Button, nothing happens in my TextView. What could be the problem? Here's my code:
Communicator.java:
public interface Communicator {
public void respond(String data);
}
MainActivity.java:
public class MainActivity extends FragmentActivity implements Communicator{
ViewPager viewPager = null;
FragmentManager fragmentManager = getSupportFragmentManager();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(new MyAdapter(fragmentManager));
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentB fragB = new FragmentB();
fragmentTransaction.add(R.id.pager, fragB, "frag_tag");
fragmentTransaction.commit();
}
public class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter (FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
if (i == 0)
{
fragment = new FragmentA();
}
if (i == 1)
{
fragment = new FragmentB();
}
if (i == 2)
{
fragment = new FragmentC();
}
if (i == 3)
{
fragment = new FragmentD();
}
if (i == 4)
{
fragment = new FragmentE();
}
if (i == 5)
{
fragment = new FragmentF();
}
return fragment;
}
#Override
public int getCount() {
return 6;
}
}
#Override
public void respond(String data) {
// TODO Auto-generated method stub
FragmentB f2 = (FragmentB) fragmentManager.findFragmentByTag("frag_tag");
f2.changeText(data);
}
}
FragmentA:
public class FragmentA extends Fragment implements OnClickListener {
int counter = 0;
Button button1;
Communicator comm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmenta, container, false);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
comm = (Communicator) getActivity();
button1 = (Button) getActivity().findViewById(R.id.button1);
button1.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
counter++;
comm.respond("The button was clicked" + counter + "times");
}
}
FragmentB:
public class FragmentB extends Fragment {
TextView text1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmentb, container, false);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
text1 = (TextView) getActivity().findViewById(R.id.textView1);
}
public void changeText(String data) {
// TODO Auto-generated method stub
text1.setText(data);
}
}
The host activity can deliver messages to a fragment by capturing the Fragment instance with findFragmentById(), then directly call the fragment's public methods.
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
// The user selected the headline of an article from the HeadlinesFragment
// Do something here to display that article
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
// If article frag is available, we're in two-pane layout...
// Call a method in the ArticleFragment to update its content
articleFrag.updateArticleView(position);
} else {
// Otherwise, we're in the one-pane layout and must swap frags...
// Create fragment and give it an argument for the selected article
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
For more detail please follow this link http://developer.android.com/training/basics/fragments/communicating.html#Deliver

Categories

Resources