I want to get the hidden value which is set in Fragment Page in order to work on it. I am setting the hidden value in Fragment Page and want to get that hidden value in the activity page's Viewpager onPageSelected value in oreder to update the fragment with detail information. Is this possible?
My Fragment page
public class CountryFragment extends Fragment {
public static final String STARTUP_ID = "startupID";
private String st_id;
public CountryFragment() {
// emtpy
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String st_id = getArguments().getString(STARTUP_ID);
this.st_id = st_id;
View v = inflater.inflate(R.layout.country_fragment, container, false);
TextView hiddenstatupid= (TextView) v.findViewById(R.id.hiddenstatuptextview);
hiddenstatupid.setText(st_id);
return v;
}
}
Activity Page
public class IndividualPage extends ActionBarActivity{
ViewPager pager;
#Override
public void onCreate (Bundle savedInstanceState)
{
pager = (ViewPager)findViewById(R.id.viewpager);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
//here is where i need to get the hidden id of startup which is in the countryfragment
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
My CountryPageAdapter
public class CountryPageAdapter extends FragmentPagerAdapter {
public CountryPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
mFragmentTags = new HashMap<Integer, String>();
}
#Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
}
Iy your CountryFragment part of the viewpager? If so, then you can have a local store of your fragments in your pager adapter and then get the fragment from the viewpager adapter using the position.
If your adapter extends FragmentStatePagerAdapter you have to implement the getItem() method.
You will have something like this:
#Override
public void onPageSelected(int position) {
CountryFragment frag = pager.getAdapter().getItem(position);
}
Hope this helps.
Related
I'm using a Fragment on my Activity that will have a picture "swiper". I've created a FragmentStatePagerAdapter which I'm trying to call from this Fragment and for some reason my getItem() method is never being called.
I've searched and found that I need to use getChildFragmentManager() when instantiating my FragmentStatePagerAdapter because I'm calling it from a Fragment. I've tried this as well as getSupportFragmentManager() with no luck from either.
Any ideas?
here's my Fragment that I'm using on my MainActivity with the method that shoudl setup the FragmentStatePagerAdapter:
public class PhotoFlipper extends Fragment {
// properties and fields
// primitive types
String currentImage;
int friendShareType = 0;
ImageView share;
ViewPager pager;
PhotoFlipperItemAdapter pagerAdapter;
LatLng itemPosition;
Activity activity;
FragmentActivity fragActivity;
public ArrayList<MarkerModel> picsAndVids;
// end properties and fields
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View photoFlipperFragmentView = inflater.inflate(R.layout.photo_flipper_layout, container, false);
InitializeFragment(photoFlipperFragmentView);
return photoFlipperFragmentView;
}
private void InitializeFragment(View photoFlipperFragmentView) {
activity = getActivity();
fragActivity = (FragmentActivity)activity;
pager = (ViewPager)photoFlipperFragmentView.findViewById(R.id.photoflipper_pager);
share = (ImageView)photoFlipperFragmentView.findViewById(R.id.photoflipper_share);
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
IPictureFlipper iPictureFlipper = (IPictureFlipper)activity;
iPictureFlipper.ShareVideoOrImage(friendShareType, itemPosition, currentImage);
}
});
}
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) {
pager.setVisibility(View.GONE);
}
}
public void SetTappedPicture(int index) {
pagerAdapter = new PhotoFlipperItemAdapter(getChildFragmentManager(), picsAndVids, picsAndVids.size());
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(index);
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
}
});
}
}
And here's my FragmentStatePagerAdapter:
public class PhotoFlipperItemAdapter extends FragmentStatePagerAdapter {
ArrayList<MarkerModel> _markers;
int NUM_PAGES;
String TAG = "home";
public PhotoFlipperItemAdapter(FragmentManager fm, ArrayList<MarkerModel> markers, int numpages){
super(fm);
Log.d(TAG,"in adapter in constructor");
_markers = markers;
NUM_PAGES = numpages;
}
#Override
public Fragment getItem(int position) {
Log.d(TAG,"in adapter in get item");
Fragment fragment = PhotoFlipperItemFragment.create(position, _markers);
return fragment;
}
#Override
public int getCount() {
Log.d(TAG,"in adapter in get count: "+NUM_PAGES);
return NUM_PAGES;
}
}
logcat is showing me that NUM_PAGES is > 0 so that's not my issue. I see my log in the constructor and in getCount() but nothing in getItem().
TIA
I got this sorted out. I was hiding my fragment in my InitializeActivity() right after I added it to my FragmentManager so it was never fully building the Fragment with the ViewPager etc.
I'm going to have to come up with a different solution for hiding/showing the fragment but that was my problem.
I came across a strange issue in my project.
I have implemented infinite viewpager adapter using FragmentStatePagerAdapter
Code for same is:
public class DashBoardAdapter extends FragmentStatePagerAdapter {
ArrayList<AbstractFragment> fragments;
private int MAXFRAGMENTS=0;
public DashBoardAdapter(FragmentManager fm, ArrayList<AbstractFragment> fragments) {
super(fm);
this.fragments = fragments;
MAXFRAGMENTS=fragments.size();
}
#Override
public AbstractFragment getItem(int position) {
return fragments.get(position%MAXFRAGMENTS);
}
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
#Override
public CharSequence getPageTitle(int position) {
return fragments.get(position%MAXFRAGMENTS).getTitle();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
int virtualPosition = position % MAXFRAGMENTS;
return super.instantiateItem(container, virtualPosition);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
int virtualPosition = position % MAXFRAGMENTS;
super.destroyItem(container, virtualPosition, object);
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
MAXFRAGMENTS = fragments.size();
}
}
And the Main Activitycode(Function only) is something like this:
public void initializeViewPager()
{
verticalViewPager = (VerticalViewPager) findViewById(R.id.verticalviewpager);
enabledPages=new ArrayList<>();
enabledPages.addAll(getEnabledPages(false));
adapter=new DashBoardAdapter(getSupportFragmentManager(),enabledPages);
verticalViewPager.setAdapter(adapter);
verticalViewPager.setPageTransformer(true, new PageTransformer());
verticalViewPager.setCurrentItem(999+position);
verticalViewPager.setOffscreenPageLimit(1);
verticalViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(adapter!=null)
title.setText(adapter.getPageTitle(position));
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private ArrayList<AbstractFragment> getEnabledPages(boolean a)
{
ArrayList<AbstractFragment> fragments=new ArrayList<>();
fragments.add(FragmentAttendance.newInstance(fragments.size()));
fragments.add(FragmentCompensation.newInstance(fragments.size()));
if(a)
fragments.add(FragmentTimeOff.newInstance(fragments.size()));
if(a)
fragments.add(FragmentCalendar.newInstance(fragments.size()));
if(a)
fragments.add(FragmentPeople.newInstance(fragments.size()));
if(a)
fragments.add(FragmentProvisions.newInstance(fragments.size()));
position = fragments.size()-(999+position)%fragments.size();
return fragments;
}
Layout of activity contains just a Viewpager.
And the Fragments, I have used is just copy of below fragment with different names
public class FragmentAttendance extends AbstractFragment {
public static final String ARG_SECTION_NUMBER = "section_number";
String title ="Testing";
public static FragmentAttendance newInstance(int sectionNumber) {
FragmentAttendance fragment = new FragmentAttendance();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public FragmentAttendance() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.card_attendance, container, false);
return rootView;
}
#Override
public String getTitle() {
return title;
}
}
Layout of fragment has just LinearLayout with a TextView.
The code is running superb if I am adding fragments more than three fragments. Howsoever as soon as the number of added fragments gets below four. My code Works in strange behavior.
Some of errors are Fragment already initialised
Other are Forward scrolling shows fragement View Howsoever when I scroll backward No view appears.
The working code can be tested by passing true to getEnabledPages(true);
And the non working code can be tested by passing false to getEnabledPages(false);
Please someone help me in this strange behaviour.
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");
}
}
// ...
}
I have problem with FragmentPagerAdapter ,I have set fragments in viewpager through FragmentPagerAdapter,
I have to show viewpager dynamically,I have listview data , which I need to show in viewpager,
when I click on the listview , I have to load exact position in the viewpager
so i just set the total size of the item to show in FragmentPagerAdapter, But the problem is that when I select the viewpager position through mPager.setCurrentItem(listposition) it show correct position of the viewpager,
but the data load at wrong place, it load in next fragement in viewpager position,after some tracking in FragmentPagerAdapter, I show that instantiateItem method initailize one fragment in advance, like i set the currentitem (from listview)of viewpager 2
then instantiateItem method initalize 0 to 3 fragment, I think that the reason the data load in 3rd fragment,I tried a lot with FragmentStatePagerAdapter also but no any success , please help me , thanks in advance.
Mainactivity class(Fragmnetactivity) :
public class NewsDetail extends FragmentActivity implements OnClickListener {
public static ViewPager mPager;
private static int NUM_PAGES;
private PagerAdapter mPagerAdapter;
public static ArrayList<Integer> exist_detail = new ArrayList<Integer>();
public static ArrayList<PageFragment> detailfragment = new ArrayList<PageFragment>();
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
NUM_PAGES = topList.size();
PageFragment fragment = new PageFragment();
Bundle args = new Bundle();
args.putInt("page", i);
fragment.setArguments(args);
detailfragment.add(fragment);
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
if (PageFragment.getInstance() != null) {
Log.d("LOG","PageFragment || "+ PageFragment.getInstance());
PageFragment.getInstance().startLoadingNews(
MusicList.topMusicList.get(arg0)._id);
}
return;
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
#Override
public void onPageScrollStateChanged(int arg0) {}
});
mPagerAdapter.notifyDataSetChanged();
mPager.setCurrentItem(listposition);// setcurrent item from here , it is selected from list. "listposition" indicate list position click
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {
private FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private Fragment mCurrentPrimaryItem = null;
private static final boolean DEBUG = false;
public ScreenSlidePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
this.mFragmentManager = fragmentManager;
}
#Override
public Fragment getItem(int position) {
return detailfragment.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return super.getItemId(position);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Log.v("LOG", "On InstantiateItem " + position);// it indicate that this method initialize one fragment in advance.
return super.instantiateItem(container, position);
}
public String makeFragmentName(int viewId, long index) {
return "android:switcher:" + viewId + ":" + index;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG)
Log.e("LOG", "Detaching item #" + position + ": f=" + object
+ " v=" + ((Fragment) object).getView());
mCurTransaction.detach((Fragment) object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
PageFragment
public class PageFragment extends Fragment implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
mDetailPageFragment = this;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout containing a title and body text.
rootView = (ViewGroup) inflater.inflate(R.layout.newsdetail, container,
false);
//init();
return rootView;
}
public void startLoadingNews(String _id) {
if (NetworkUtil.cheackNetwork(mActivity)) {
executeTask(_id);
} else {
showRetryCancelDialog();
}
}
}
I can see two issues in the code you've posted:
Only instantiate your fragments in FragmentPagerAdapter.getItem. Don't instantiate them and save them to some list or array, let the FragmentPagerAdapter do that for you. In FragmentPagerAdapter.instantiateItem it checks if the Fragment was already created and if so it returns it, if not, it'll call your getItem to create the fragment.
Don't use the Singleton scheme for your fragment, create a new fragment using a constructor or a .newInstance() static helper.
I have an application that Implements ActionBarSherlock, it's mainly composed of
ViewPager with different content of fragments (for each page), with ViewPager indicator.
Here is my onCreate Method of the Activity that extends SherlockFragmentActivity
// Assume that tabs,sources,types are string arrays e.g. tabs = ["tab1","tab2","tab3"]
// types = ["listview","listview","webview"]
// according to the type of each tab, the type of content of the fragment associated to that tab is determined (e.g. WebView or ListView)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
srcContext = getBaseContext();
srcActivity = SaudiActivity.this;
int selectPos = 0;
Intent sender = getIntent();
FragmentPagerAdapter mAdapter = new NewsListAdapter(
getSupportFragmentManager());
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(mAdapter);
TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator);
indicator.setViewPager(pager);
pager.setOffscreenPageLimit(tabs.length);
pager.setCurrentItem((tabs.length - 1));
currentPosition = (tabs.length - 1);
indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
currentPosition = position;
if ((type[position] == "listview" || type[position]
.equals("listview")) && loaded[position] == false) {
loaded[position] = true;
getNews(listViews[position], position);
}
}
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
getSupportActionBar().setCustomView(R.layout.logo);
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
Context ctx = getSupportActionBar().getThemedContext();
SourcesAdapter adapter = new SourcesAdapter(ctx,
R.layout.navigation_list_item, src_name, icons, src_value);
}
Here are my News List Adapter (that creates the fragments),
public static class MyViewHolder {
public TextView title;
public ImageView icon;
}
class NewsListAdapter extends FragmentPagerAdapter {
public NewsListAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return new NewsFragment(MyActivity.this, position);
}
// This is the number of pages -- 5
#Override
public int getCount() {
return tabs.length;
}
// This is the title of the page that will apppear on the "tab"
public CharSequence getPageTitle(int position) {
return tabs[position];
}
}
public List<NewsItem> NewsItems;
Finally here's my NewsFragment:
public static class NewsFragment extends Fragment {
private int position;
public NewsFragment() {
}
public NewsFragment(Context ctx, int pos) {
this.position = pos;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = null;
if (type[position].equals("listview")) {
// Put a ListView in the Fragment
} else {
// Put a WebView in the Fragment
}
return view;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
}
Let the fragment handle it's state by overriding onSaveInstanceState and placing the necessary values into outState. Recover that state in onCreateView using savedInstanceState. Also I'm pretty sure that if you're using Actionbarsherlock fragments need to extend SherlockFragment rather than Fragment.