I have an activity and pager adapter in it which displays 3 fragments. The fragments are shuffled. I need to know the number of each page when I am swiping through them and that number needs to be displayed in a textView. For example, when I am in the first page number 1 is displayed, second page - number 2 and so on.
PagerAdapter.java
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int arg0) {
return this.fragments.get(arg0);
}
#Override
public int getCount() {
return this.fragments.size();
}
public void setFragments(List<Fragment> fragments) {
this.fragments = fragments;
}
}
mainActivity.java
public class testActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager_adapter);
initialisePaging();
}
private void initialisePaging() {
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this,fragment1.class.getName()));
fragments.add(Fragment.instantiate(this,fragment2.class.getName()));
fragments.add(Fragment.instantiate(this,fragment3.class.getName()));
PagerAdapter mPagerAdapter = new PagerAdapter(this.getSupportFragmentManager(), fragments);
Collections.shuffle(fragments, new Random(System.nanoTime()));
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
pager.setAdapter(mPagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_test, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
If you want to be displaying the number in your fragment, use this
In your Activity
#Override
public Fragment getItem(int position) {
// Here you can add an argument that will be passed to the fragment
// In your case you need to pass the page number
Fragment fragment = this.fragments.get(arg0);
Bundle b = new Bundle();
b.putInt("page_number", position);
fragment.setArguments(b);
return fragment;
}
In you fragment do this
int number;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read the data that Activity passed to us
if (savedInstanceState == null) {
Bundle args = getArguments();
if (args != null) {
number = args.getInt("page_number") + 1;
}
}
else {
number = savedInstanceState.getInt("page_number");
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// Here you need to find your TextView and show the number
View v = inflater.inflate(R.layout.some_layout, container, false);
((TextView) v.findViewById(R.id.someTextView)).setText(String.format("%d", number));
return v;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("page_number", number);
}
If you want to be displaying the number in your Activity, use this
private void initialisePaging() {
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this,fragment1.class.getName()));
fragments.add(Fragment.instantiate(this,fragment2.class.getName()));
fragments.add(Fragment.instantiate(this,fragment3.class.getName()));
PagerAdapter mPagerAdapter = new PagerAdapter(this.getSupportFragmentManager(), fragments);
Collections.shuffle(fragments, new Random(System.nanoTime()));
// !!! Change ME!!!!!
textView = (TextView) findViewById(R.id.someTextView);
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
}
#Override
public void onPageSelected(int i) {
textView.setText("Position: " + i);
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
pager.setAdapter(mPagerAdapter);
}
Use PageChangeListener as:
yourPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position)
{
yourTextView.setText("Page: " + position);
}
... ...
});
Related
I've created Activity to handle ViewPager. At the beginning it was working fine, but then I had to add some more code, to make it refresh my pages while selecting them. I've handled it by calling onResume() method with every page change.
I've optimized my Fragments, cleared unnecessary code (inside onResume()) in each of them, but this give no result. That's how my Activity looks like:
public class MainTabsActivity extends AppCompatActivity implements FullList.OnListFragmentInteractionListener, AcceptedList.OnListFragmentInteractionListener, StartedList.OnFragmentInteractionListener {
private static final int NUM_TABS = 3;
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_tabs);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(2);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
Fragment fragment = ((SectionsPagerAdapter)mViewPager.getAdapter()).getFragment(i);
if (fragment != null) {
Log.e("PAGE SELECTED", " " + i);
tabLayout.getTabAt(i).select();
fragment.onResume();
}
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
Intent i = getIntent();
int pageNum = i.getIntExtra("pagenumber", 0);
mViewPager.setCurrentItem(pageNum);
tabLayout.getTabAt(pageNum).select();
mViewPager.invalidate();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main_tabs, 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 onListFragmentInteraction(DummyContent.DummyItem item) {
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
mFragmentTags = new HashMap<>();
mFragmentManager = fm;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch(position) {
case 0:
return getString(R.string.tab_text_1);
case 1:
return getString(R.string.tab_text_2);
case 2:
return getString(R.string.tab_text_3);
}
return null;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
FullList tab1 = new FullList();
return tab1;
case 1:
AcceptedList tab2 = new AcceptedList();
return tab2;
case 2:
StartedList tab3 = new StartedList();
return tab3;
default:
return null;
}
}
#Override
public int getCount() {
return NUM_TABS;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
Object obj = super.instantiateItem(container, position);
if (obj instanceof Fragment) {
Fragment f = (Fragment) obj;
String tag = f.getTag();
mFragmentTags.put(position, tag);
}
return obj;
}
public Fragment getFragment(int position) {
String tag = mFragmentTags.get(position);
if (tag == null) return null;
return mFragmentManager.findFragmentByTag(tag);
}
}
}
I've added code, to call onResume() method, but funny thing is that the Fragments are loading so long only while I open this Activity from another, but not while scrolling between pages (everything works smoothly then), before changes everything was fine.
Is there any way to make this work faster?
You don't need to write onPageSelected code to change your tab selection.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOffscreenPageLimit(2);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager); // this will synchronize our tablayout with your viewpager
You should not call onResume directly, this is a system event and a call to this void
is not recommended.
Also, in your case, no need to call mViewPager.invalidate()
I am trying to fill Tablayout from 2 different fragments depending on the value (0 or 1) of the argument Radios.newInstance(int type)
The first fragment contains all radio stations and the second contains the favorite stations
But it shows me always the fragment containing the favorite stations
public class HomeFragment extends Fragment {
public static final String TAG = "HomeFragment";
private SectionsPagerAdapter mSectionsPagerAdapter;
private ProgressBar mProgressView;
private ViewGroup mContainer;
private BaseActivity activity;
public HomeFragment() {
}
public static HomeFragment newInstance() {
return new HomeFragment();
}
public void showProgress(final boolean show) {
mContainer.setVisibility(show ? View.GONE : View.VISIBLE);
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
activity = (BaseActivity) getActivity();
activity.findViewById(R.id.tabs).setVisibility(View.VISIBLE);
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
activity.getSupportActionBar().show();
mProgressView = (ProgressBar) activity.findViewById(R.id.progress);
mContainer = container;
showProgress(true);
ViewPager mViewPager = (ViewPager) view.findViewById(R.id.container);
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(RadiosFragment.newInstance(0));
fragments.add(RadiosFragment.newInstance(1));
mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager(), fragments);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) activity.findViewById(R.id.tabs);
tabLayout.setVisibility(View.VISIBLE);
tabLayout.setTabMode(TabLayout.GRAVITY_CENTER);
tabLayout.setupWithViewPager(mViewPager);
showProgress(false);
return view;
}
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragments;
public SectionsPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
mFragments = fragments;
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "RADIOS";
case 1:
return "FAVORITES";
default:
return null;
}
}
}
}
This is the fragment that i want to show, if type == 0 it shows the all radio stations, and if type == 1 it shows the favorite stations
public class RadiosFragment extends Fragment {
private static String TYPE = "NONE";
private FirebaseRecyclerAdapter<FireBaseManager.Radio, ViewHolder> mAdapter = null;
private FirebaseRecyclerAdapter<FireBaseManager.Favorites, ViewHolder> mAdapter_fav = null;
private RecyclerView recyclerView;
public ArrayList<FireBaseManager.Favorites> listOrder;
public RadiosFragment() { }
public static RadiosFragment newInstance(int type) {
if (type == 1 )
TYPE = "favorite";
else
TYPE = "radios";
RadiosFragment fragment = new RadiosFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_item_list, container, false);
final Context context = view.getContext();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
recyclerView = (RecyclerView) view.findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
Query query = FireBaseManager.Radio.Ref.orderByChild(FireBaseManager.Radio.Table.Name.text);
ProgressDialog progressDialog = new ProgressDialog(getContext());
if (TYPE == "favorite"){
....
#Override
protected void populateViewHolder(ViewHolder viewHolder, FireBaseManager.Favorites model, int position) {
...
viewHolder.Initialize(Data);
...
}
};
recyclerView.setAdapter(mAdapter_fav);
}
});
}
else if(TYPE == "radios") {
....
#Override
protected void populateViewHolder(ViewHolder viewHolder, FireBaseManager.Radio model, int position) {
...
viewHolder.Initialize(Data);
...
});
}
};
recyclerView.setAdapter(mAdapter);
});
}
return view;
}
}
I think the problem has to do with onCreateView / onCreate but i am no sure, can you help me please.
This might help you.
mViewPager.setCurrentItem(0);
Add this line after you setup tabLayout with viewpager
thank you very much for your answers, i have found a solution for my problem.
the solution is to add Listener on the Tablayout and intercept the events.
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == 0)
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.flContent, RadiosFragment.newInstance(0), FavoriteActivity.TAG).addToBackStack(null).commit();
if (tab.getPosition() == 1)
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.flContent, RadiosFragment.newInstance(1), FavoriteActivity.TAG).addToBackStack(null).commit();
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
I am implementing nested fragments in a ViewPager. When I perform the transaction by replacing the child fragment in the parent fragment after executing addToBackStack(), I am able to see the view shown below. But when I press back button and the code reaches the MainActivity's onBackPressed() method, I notice the stack size is 1, and I successfully popout the Fragment. The problem starts now
My app closes and for a brief amount of time, I see my child fragment closing and then the app closing.
MainActivity
public class MainActivity extends FragmentActivity implements FragmentCommunicationListener {
ViewPager viewPager;
PagerAdapter pagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//createTabs();
viewPager = (ViewPager) findViewById(R.id.pager);
Fragment[] fragments = new Fragment[]{
new ViewStudentsFragment(),
new AddStudentFragment()
};
pagerAdapter = new PagerAdapter(getSupportFragmentManager(), this, fragments);
viewPager.setAdapter(pagerAdapter);
}
#Override
public void passMsg(Fragment fragment, Bundle msg) {
int currentItem = viewPager.getCurrentItem();
Fragment targetFragment;
if (currentItem == 0) {
targetFragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 1);
((AddStudentFragment) targetFragment).renderData(msg);
viewPager.setCurrentItem(1);
} else {
targetFragment = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 0);
((ViewStudentsFragment) targetFragment).updateList(msg,viewPager);
viewPager.setCurrentItem(0);
}
}
#Override
public void onBackPressed() {
ViewStudentsFragment fragment = (ViewStudentsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 0);
super.onBackPressed();
if (fragment.getChildFragmentManager().getBackStackEntryCount() != 0) {
fragment.getChildFragmentManager().popBackStack();
}
}
}
Parent Fragment
public class ViewStudentsFragment extends Fragment {
ArrayList<Student> studentList = new ArrayList<Student>();
ListView list;
ListViewAdapter listAdapter;
GridView grid;
FragmentCommunicationListener fragComm = null;
int resIdView, resIdSort;
GridViewAdapter gridAdapter;
static ImageButton toggleView, toggleSort;
View view;
ViewPager viewPager=null;
public ViewStudentsFragment() {
}
private static ViewStudentsFragment viewStudentsFragment;
FragmentTransaction transaction;
Fragment details ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_view_students, container, false);
toggleView = (ImageButton) view.findViewById(R.id.viewImageButton);
toggleSort = (ImageButton) view.findViewById(R.id.sortImageButton);
transaction= getChildFragmentManager().beginTransaction();
view.findViewById(R.id.container).setVisibility(View.GONE);
...
toggleView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
...
}
});
toggleSort.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
...
}
});
registerForContextMenu(list);
registerForContextMenu(grid);
return view;
}
public void updateList(Bundle bundle,ViewPager vp) {
viewPager=vp;
...
}
listAdapter.notifyDataSetChanged();
gridAdapter.notifyDataSetChanged();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof FragmentCommunicationListener) {
fragComm = (FragmentCommunicationListener) activity;
} else {
throw new ClassCastException();
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
...
}
#Override
public boolean onContextItemSelected(MenuItem item) {
...
switch (menuItemIndex) {
case Constant.VIEW_STUDENT_DETAIL:
bundle.putSerializable("viewField", student); view.findViewById(R.id.container).setVisibility(View.VISIBLE);
transaction.addToBackStack(null);
details = new Details();
transaction.replace(R.id.container, details, "task");
transaction.commit();
details.setArguments(bundle);
break;
...
default:
}
listAdapter.setStudentList(studentList);
gridAdapter.setStudentList(studentList);
listAdapter.notifyDataSetChanged();
gridAdapter.notifyDataSetChanged();
return true;
}
}
ChildFragment
public class Details extends Fragment {
View view;
static Details details;
Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
context=container.getContext();
Bundle bundle = getArguments();
view=inflater.inflate(R.layout.display_details, container, false);
...
return view;
}
#Override
public void onDetach() {
super.onDetach();
view.findViewById(R.id.displayDetails).setVisibility(View.GONE);
}
#Override
public void onDestroyView() {
super.onDestroyView();
view.findViewById(R.id.displayDetails).setVisibility(View.GONE);
}
#Override
public void setArguments(Bundle bundle) {
super.setArguments(bundle);
}
}
PagerAdapter
public class PagerAdapter extends FragmentPagerAdapter {
private String[] tabMenu;
private int pageCount;
private Context context;
private Fragment[] fragments;
public PagerAdapter(FragmentManager fm, Context context, Fragment[] fragments) {
super(fm);
this.context = context;
tabMenu = context.getResources().getStringArray(R.array.tab_menu);
pageCount = tabMenu.length;
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return fragments[position];
}
#Override
public int getCount() {
return fragments.length;
}
#Override
public CharSequence getPageTitle(int position) {
return tabMenu[position];
}
}
If you use FragmentTransaction.addToBackStack(), the back button is handled automatically for you.
When you do this:
#Override
public void onBackPressed() {
ViewStudentsFragment fragment = (ViewStudentsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 0);
super.onBackPressed();
if (fragment.getChildFragmentManager().getBackStackEntryCount() != 0) {
fragment.getChildFragmentManager().popBackStack();
}
}
you are basically popping the backstack twice, which is why your application quit.
Replace the onBackPressed() method in your Activity with this:
#Override
public void onBackPressed() {
ViewStudentsFragment fragment = (ViewStudentsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + 0);
if (fragment.getChildFragmentManager().getBackStackEntryCount() != 0) {
fragment.getChildFragmentManager().popBackStack();
}
else {
super.onBackPressed();
}
}
Need help to fix a code I saw in a https://stackoverflow.com/a/9275732/1938357. The solution I need is get the current view onany page in my viewpager based application
Below is the code for reference
public View getCurrentView(ViewPager pager) {
for (int i = 0; i < pager.getChildCount(); i++) {
View child = pager.getChildAt(i);
if (child.getX() <= pager.getScrollX() + pager.getWidth()
&& child.getX() + child.getWidth() >= pager.getScrollX() + pager.getWidth()) {
return child;
}
}
return getChildAt(0);
I am trying to access the current view in the view pager and used the code above. It works fine when I scroll forwards. But when I scroll backwards then after 2 backward scrolls this stops working.
Public class myActivity extends FragmentActivity
//Variable declarations
protected void onCreate(Bundle savedInstanceState) {
ViewPager mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
View CurrView;
OnPageChangeListener pageChangelistener = new OnPageChangeListener() {
#Override
public void onPageSelected(int pageSelected) {
doTextViewChnges();//access the text view and update it based on pageSelected
---THIS IS WHERE I AM STUCK IN TRYING TO GET THE TEXTVIEW IN MY CURRENT FRAGMWNT/VIEW-------
}
mPager.setOnPageChangeListener(pageChangelistener);
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
return ScreenSlidePageFragment.create(position, <other parameters I want to pass>);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
And below is my ScreenSlidePageFragment class
public class ScreenSlidePageFragment extends android.support.v4.app.Fragment {
public static final String ARG_PAGE = "pagenumber";
public static final String ARG_PAGEARRAY = "pages";
private int mPageNumber;
//Declare other variables
#SuppressLint("NewApi")
public static ScreenSlidePageFragment create(int pageNumber, String[] pages, int bookmarkPageNumber, String storyName, int linesInOnePage) {
ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
args.putStringArray(ARG_PAGEARRAY, pages);
fragment.setArguments(args);
return fragment;
}
#SuppressLint("NewApi")
public ScreenSlidePageFragment() {
}
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
pages = getArguments().getStringArray(ARG_PAGEARRAY);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = (ViewGroup) inflater
.inflate(R.layout.activity_story, container, false);
//load layout with all components filled up for that page
loadView(rootView);
return rootView;
}
public int getPageNumber() {
return mPageNumber;
}
It is very hard to discuss in comments with example of code.
As I see in grepcode FragmentStatePagerAdapter.setPrimaryItem(), receive object as android.support.v4.app.Fragment. But you are receive ClassCastException when trying to cast object as Fragment. Can you check your casting: do you really cast object in android.support.v4.app.Fragment not in android.app.Fragment? If all right, add your exception message to your question, please.
UPDATE:
If your ScreenSlidePagerAdapter has method getCurrentView(), then your method 'getCurrentView()' can work like this:
public View getCurrentView(ViewPager pager) {
return ((ScreenSlidePagerAdapter) pager.getAdapter()).getCurrentView();
}
And method getCurrentView() of your ScreenSlidePagerAdapter:
public View getCurrentView() {
return currView;
}
UPDATE 2:
I've made some modification with your code:
Your Activity with private Adapter:
public class myActivity extends FragmentActivity implements ISelectItemListener {
// Your variable declarations and methods
#Override
protected void onCreate(Bundle savedInstanceState) {
final ViewPager pager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
pager.setAdapter(mPagerAdapter);
pager.setOnPageChangeListener(
new OnPageChangeListener() {
#Override
public void onPageSelected(int pageSelected) {
final ScreenSlidePageFragment fragment = mPagerAdapter.getFragment(pageSelected);
if (fragment != null) {
fragment.doTextViewChnges();
}
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
});
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
//Your variable declarations
private final ScreenSlidePageFragment[] mFragments;
public ScreenSlidePagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
mFragments = new ScreenSlidePageFragment[NUM_PAGES];
}
#Override
public int getCount() {
return NUM_PAGES;
}
// It will create new ScreenSlidePageFragment by position if it's not exsist
#Override
public android.support.v4.app.Fragment getItem(int position) {
if (getFragment(position) == null) {
mFragments[position] = ScreenSlidePageFragment.create(position, <other parameters I want to pass>);
}
return getFragment(position);
}
// It will give you ScreenSlidePageFragment if it's exists, or null
public ScreenSlidePageFragment getFragment(int position) {
return mFragments[position];
}
}
}
Your Fragment:
public class ScreenSlidePageFragment extends Fragment {
//Your variables and methods
public static ScreenSlidePageFragment create(int pageNumber, String[] pages, int bookmarkPageNumber, String storyName, int linesInOnePage) {
final Bundle args = new Bundle();
args.putInt(ARG_PAGE, pageNumber);
args.putStringArray(ARG_PAGEARRAY, pages);
final ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
pages = getArguments().getStringArray(ARG_PAGEARRAY);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = (ViewGroup) inflater.inflate(R.layout.activity_story, container, false);
loadView(rootView);
return rootView;
}
public int getPageNumber() {
return mPageNumber;
}
// Let's keep logic of modifications in fragment
public void doTextViewChnges() {
final View view = getView();
// do what you want with your View and his children
}
}
I have a parent SherlockFragmentActivity class that contains ViewPager with 4 Fragments inside.
One of them extends from SherlockListFragment and I want to scroll it to top by click on it's tab.
MainActivity class:
public class MainActivity extends SherlockFragmentActivity {
ViewPager viewPager;
TabAdapter tabAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
setTheme(Constants.THEME);
viewPager = new ViewPager(this);
viewPager.setId(R.id.pager);
viewPager.setBackgroundResource(R.color.background_color);
tabAdapter = new TabAdapter(this,viewPager);
super.onCreate(savedInstanceState);
setContentView(viewPager);
// Action bar setup
setupTabs(savedInstanceState);
}
private void setupTabs(Bundle savedInstanceState) {
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (int i = 1; i <= 4; i++) {
ActionBar.Tab tab = getSupportActionBar().newTab();
switch (i) {
case 1:
tab.setText(R.string.feed).setTabListener(tabAdapter);
tabAdapter.addTab(EventListFragment.class);
break;
case 2:
tab.setText(R.string.downloads).setTabListener(tabAdapter);
tabAdapter.addTab(LocalEventListFragment.class);
break;
case 3:
tab.setText(R.string.tags).setTabListener(tabAdapter);
tabAdapter.addTab(TagsFragment.class);
break;
case 4:
tab.setText(R.string.settings).setTabListener(tabAdapter);
tabAdapter.addTab(SettingsFragment.class);
break;
}
getSupportActionBar().addTab(tab);
}
}
TabAdapter class:
public static class TabAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, ActionBar.TabListener {
private final Context mContext;
private final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
private final ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
private final ActionBar mActionBar;
private final ViewPager mViewPager;
public TabAdapter(SherlockFragmentActivity activity, ViewPager pager){
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(Class<?> clss){
classes.add(clss);
mFragments.add(Fragment.instantiate(mContext, clss.getName(),
null));
}
#Override
public Fragment getItem(int i) {
return mFragments.get(i);
}
public int getId(int index){
return mFragments.get(index).getId();
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// fixed double call onTabReselected
if (mActionBar.getSelectedNavigationIndex() != position)
mActionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int i) {
}
#Override
public int getCount() {
return 4;
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
final int position = tab.getPosition();
final Fragment fragment = mFragments.get(position);
if (fragment != null) {
switch (position) {
case 0:
// call tab's ListFragment scroll to top item
((EventListFragment) fragment).scrollToTop();
break;
case 1:
// do something
break;
}
}
}
onTabReselected called, then user press current tab, so I try to do EventListFragment scrolling:
EventListFragment class:
public class EventListFragment extends SherlockListFragment {
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
mAdapter = new EventListAdapter(getSherlockActivity());
setListAdapter(mAdapter);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
}
#Override
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View eventListLayout = inflater.inflate(R.layout.eventlist_fragment,null);
ListView lv = (ListView) eventListLayout.findViewById(android.R.id.list);
ViewGroup parent = (ViewGroup) lv.getParent();
//Remove ListView and add PullToRefreshListView in its place
int lvIndex = parent.indexOfChild(lv);
parent.removeViewAt(lvIndex);
mPullToRefreshListView = onCreatePullToRefreshListView(inflater, savedInstanceState);
parent.addView(mPullToRefreshListView, lvIndex, lv.getLayoutParams());
return eventListLayout;
}
public void scrollToTop() {
if (getSherlockActivity() != null) { // null after screen rotation
final ListView listView = getListView();
listView.post(new Runnable(){
public void run() {
listView.smoothScrollToPosition(0);
}});
}
}
It works on application start, but after screen rotation scrollToTop - getSherlockActivity() returns null.
If remove this condition check, have an exception:
java.lang.IllegalStateException: Content view not yet created
at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328)
at android.support.v4.app.ListFragment.getListView(ListFragment.java:222)
at com.project.fragment.EventListFragment.scrollToTop(EventListFragment.java:337)
at com.project.MainActivity$TabAdapter.onTabReselected(MainActivity.java:411)
at com.actionbarsherlock.internal.app.ActionBarWrapper$TabWrapper.onTabReselected(ActionBarWrapper.java:327)
I haven't totally understatinding how to ViewPager and its FragmentPagerAdapter works. So can't find a problem, that occurs.
Use this FragmentPageAdapter:
public class TestFragmentAdapter extends FragmentPagerAdapter implements IconPagerAdapter {
protected static final String[] CONTENT = new String[] { "CATEGORIAS", "PRINCIPAL", "AS MELHORES", };
protected static final int[] ICONS = new int[] {
R.drawable.perm_group_calendar,
R.drawable.perm_group_camera,
R.drawable.perm_group_device_alarms,
};
private int mCount = CONTENT.length;
public TestFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {Fragment f = null;
switch(position){
case 0:
{
f = new ArrayListFragment();//YourFragment
// set arguments here, if required
Bundle args = new Bundle();
f.setArguments(args);
break;
}
case 1:
{
f = new HomeFragment();//YourFragment
// set arguments here, if required
Bundle args = new Bundle();
f.setArguments(args);
break;
}
case 2:
{
f = new EndlessCustomView();//YourFragment
// set arguments here, if required
Bundle args = new Bundle();
f.setArguments(args);
break;
}
default:
throw new IllegalArgumentException("not this many fragments: " + position);
}
return f;
}
#Override
public int getCount() {
return mCount;
}
#Override
public CharSequence getPageTitle(int position) {
return TestFragmentAdapter.CONTENT[position % CONTENT.length];
}
#Override
public int getIconResId(int index) {
return ICONS[index % ICONS.length];
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
This Activity:
public class BaseSampleActivity extends SlidingFragmentActivity {
private static final Random RANDOM = new Random();
TestFragmentAdapter mAdapter;
ViewPager mPager;
PageIndicator mIndicator;
protected ListFragment mFrag;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.themed_titles);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mAdapter = new TestFragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(1);
mIndicator = (TitlePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}
Applied solution according to this post:
MainActivity class:
//...
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
FragmentManager manager = getSupportFragmentManager();
for (int i = 0; i < tabAdapter.getClasses().size(); i++) {
String className = tabAdapter.getClasses().get(i).getName();
if (manager.findFragmentByTag(className) != null) {
manager.putFragment(outState, className, manager.findFragmentByTag(className));
}
}
}
//...
TabAdapter class:
//...
public void addTab(Class<?> clss, FragmentManager manager, Bundle savedInstanceState) {
classes.add(clss);
String className = clss.getName();
tags.add(className);
Fragment fragment;
if (savedInstanceState != null) {
fragment = manager.getFragment(savedInstanceState, className);
if (fragment == null) {
fragment = createFragment(className);
manager.beginTransaction().add(fragment, className);
}
} else {
fragment = createFragment(className);
manager.beginTransaction().add(fragment, className);
}
mFragments.add(fragment);
}
//...
where createFragment is a simple method, that creates needed fragment by passed class name.