MainActivity(extends fragmentActivity) has listview which calls listviewadapter within which have a ViewPager with ViewpagerAdapter now if i need to generate 5 fragments within ViewPager how to pass getFragmentManager() to adapter.
MainActivity [fragmentActivity] ----> Listview ----> ListviewAdapter[Custom BaseAdapterAdapter with getview of layout ViewPager] ---> ViewPager ---> ViewPageAdapter[i need to create 5 fragments based on position?]
It will be too long if i paste the whole code so i have attached only
public class ViewPagerAdapter extends PagerAdapter {
ArrayList<ModelClass> arrayModelClasses = new ArrayList<ModelClass>();
Context mcontext ;
LinearLayout layouttest;
final int PAGE_COUNT = 5;
private String titles[] = new String[] { "Villa ","", "" ,"","",""};
private int[] imageResId = { R.drawable.transparant,R.drawable.ic_action_place, R.drawable.icon_3d1,
R.drawable.icon_flooplan,R.drawable.icon_gallery,R.drawable.icon_location };
#SuppressLint("NewApi")
#Override
public void finishUpdate(ViewGroup container) {
// TODO Auto-generated method stub
super.finishUpdate(container);
}
public ViewPagerAdapter(ArrayList<ModelClass> arrayModelClasses , Context context) {
super();
this.arrayModelClasses = arrayModelClasses;
this.mcontext= context;
}
#Override
public boolean isViewFromObject(View collection, Object object) {
return collection == ((View) object);
}
View view;
#Override
public Object instantiateItem(View collection, int position) {
if (position == 0) {
//need to call fragment 1
}if (position == 1) {
//need to call fragment 2
}if (position == 2) {
//need to call fragment 3
}if (position == 3) {
//need to call fragment 4
}if (position == 4) {
//need to call fragment 5
}
return view;
}
#Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
#Override
public CharSequence getPageTitle(int position) {
Drawable image = mcontext.getResources().getDrawable(imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" " + titles[position] );
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
link but it uses FragmentPagerAdapter for viewPager and passed the getSupportFragmentManager from FragmentActivity but its not possible with 2 adapters so help.
Question: How to create fragment within viewPager which is inside listview. sorry if its confusing.
Thanks,
Considering you did not post your ListView Adapter I'll assume you extend BaseAdapter (either way it'll be similar). On the getView(...) method instantiate a new ViewPagerAdapter and set it to the PagerAdapter defined in the list item xml.
Note: having a ViewPager inside the ListView (and specially while loading the items that way) could cause low performance.
I've attached fragments inside ViewPager with the code as follows
public class IntroslideActivity extends FragmentActivity {
private static int NUM_PAGES = 5;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_introslide);
mPager = (ViewPager) findViewById(R.id.pager);
/**
* A simple pager adapter that represents 5 {#link ScreenSlidePageFragment} objects, in
* sequence.
*/
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter{
protected final int[] ICONS = new int[] {
R.drawable.ic_message,
R.drawable.ic_phone,
R.drawable.ic_message,
R.drawable.ic_message,
R.drawable.ic_message
};
public ScreenSlidePagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
android.support.v4.app.Fragment frm = null;
System.out.println("scrolling position"+position);
if(position==0){
frm=ScreenSlidePageFragment.create(position);
}
else if(position==1){
frm=Screenslidetwo.create(position);
}
else if(position==2){
frm=Screenslidethree.create(position);
}
else if(position==3){
frm=Screenslidefour.create(position);
}
else if(position==4){
frm=Screenslidefive.create(position);
}
return frm;
}
#Override
public int getCount() {
return NUM_PAGES;
}
public void setCount(int count) {
if (count > 0 && count < 5) {
NUM_PAGES = count;
notifyDataSetChanged();
}
}
}
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
}
}
Related
I am trying to set infinite view Pager(circular Scroll-able tab) using Infinite ViewPager but when I tried to set the adapter
1.It work only from the end side (last Position).
2.It is not working on the start(position 0) side.
3.It repeat the last fragment when scrolled further.
My adapter
private InfiniteViewPager pager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pager = (InfiniteViewPager) findViewById(R.id.pager);
FragmentManager fragmentManager = getSupportFragmentManager();
pager.setAdapter(new MyAdapter(fragmentManager));
pager.setPageTransformer(true, new CubeOutTransformer());
pager.setCurrentItem(2);
}
My adapter class
class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
public int getActualPosition(int i){
return i < 5? i : 0;
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
i = getActualPosition(i);
if (i == 0) {
fragment = new Albums();
}
if (i == 1) {
fragment = new Artists();
}
if (i == 2) {
fragment = new Songs();
}
if (i == 3) {
fragment = new Genres();
}
if (i == 4) {
fragment = new Playlists();
}
return fragment;
}
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
#Override
public CharSequence getPageTitle(int position) {
String title = new String();
if (position == 0) {
return "ALBUMS";
}
if (position == 1) {
return "ARTISTS";
}
if (position == 4) {
return "PLAYLIST";
}
if (position == 3) {
return "GENRES";
}
if (position == 2) {
return "SONGS";
}
return title;
}
}
I have gone through Infinite Pager Adapter and Mine pager adapter
but when I try to set the adapter inside another adapter I am getting an error in my adapter class.
where I am doing wrong and how I can fix the scrolling from both starting and ending.
You should set adapter like this
MyAdapter adapter=new MyAdapter(fragmentManager);
InfinitePagerAdapter myAdapter= new InfinitePagerAdapter(adapter);
pager.setAdapter(myAdapter);
Also in your adapter change this code
from this
#Override
public int getCount() {
return Integer.MAX_VALUE;
}
to
#Override
public int getCount() {
return 5;
}
I have a ViewPager and I'm using FragmentStatePagerAdapter to hold my fragments. Now the problem is that when I slide the OnCreateView and OnCreate of the Fragments are called everytime and I make network calls in the Fragments which will be called again and again causing lag.
I have copied from here
How to Avoid calling the OnCreateView and OnCreate of the Fragments.
Here's my code:
FragmentHolder.class
public class ViewPagerAdapter extends SmartFragmentStatePagerAdapter {
final int PAGE_COUNT = 3;
private final ArrayList<Fragment> mFragments = new ArrayList<>();
private long baseId = 0;
private String tabTitles[] = new String[] { "HOME", "DISCOVER", "MESSAGES" };
private Context context;
private TabLayout tabLayout;
public int[] imageResId = {
R.drawable.ic_ac_unit_black_24dp,
R.drawable.ic_airport_shuttle_black_24dp,
R.drawable.ic_all_inclusive_black_24dp
};
public ViewPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public Fragment getItem(int position) {
if(position == 0)
{
Log.d("Fragment","1");
return FragmentOne.newInstance(position + 1);
}
else if(position == 1)
{
Log.d("Fragment","2");
return FragmentTwo.newInstance(position + 2);
}
else if(position == 2)
{
Log.d("Fragment","3");
return FragmentThree.newInstance(position + 3);
}
return new Fragment();
}
#Override
public CharSequence getPageTitle(int position)
{
Drawable image = ContextCompat.getDrawable(context, imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
}
MainActivity:
lockableViewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager(),
Dashboard.this));
lockableViewPager.setSwipeable(false);
lockableViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position == 0) {
fragmentOne.message();
} else if (position == 1) {
fragmentTwo.message();
} else if (position == 2) {
fragmentThree.message();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Yes, using the setOffscreenPageLimit to 3 (depending on the no of fragments you have), allows you to retain the Fragments (not calling on CreateView)
lockableViewPager.setOffscreenPageLimit(3);
With the help of Vivek Pratap Singh and astuetz codes from following questions(Remove Fragment Page from ViewPager in Android and Android saving dynamically added viewpager's fragment while coming back from another activity and reopening app),
In my previous question in stack overflow I used inbuild method onDestroy, as it looks like it will save all the dynamically added fragments in viewpager.
But it's not happening, I am able to see only one intial static page(i.e. fragment) when I restart my app or navigate to another activity and come back to my activity containing the viewpager with fragments.Could any one please help me on this question.
Here is my source code for your reference:
public class MainActivity extends FragmentActivity implements TextProvider {
private Button mAdd;
private Button mRemove;
private ViewPager mPager;
int position;
private MyPagerAdapter mAdapter;
private ArrayList<String> mEntries = new ArrayList<String>();
#Override
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putInt("currenItem", mPager.getCurrentItem());
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPager = (ViewPager) findViewById(R.id.pager);
if (savedInstanceState != null) {
mPager.setCurrentItem(savedInstanceState.getInt("currentItem", 0));
}
mEntries.add("page 1");
mAdd = (Button) findViewById(R.id.add);
mRemove = (Button) findViewById(R.id.remove);
mAdd.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
addNewItem();
}
});
mRemove.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
removeCurrentItem();
}
});
mAdapter = new MyPagerAdapter(this.getSupportFragmentManager(), this);
mPager.setAdapter(mAdapter);
mPager.setOffscreenPageLimit(3);
}
private void addNewItem() {
// int position = mPager.getCurrentItem();
mEntries.add("page ");
mAdapter.notifyDataSetChanged();
}
private void removeCurrentItem() {
int position = mPager.getCurrentItem();
if(position != 0){
mEntries.remove(position);
}else{
Toast.makeText(getApplicationContext(), "Sorry", Toast.LENGTH_LONG).show();
}
mAdapter.notifyDataSetChanged();
}
#Override
public String getTextForPosition(int position) {
return mEntries.get(position);
}
#Override
public int getCount() {
return mEntries.size();
}
private class MyPagerAdapter extends FragmentPagerAdapter {
private TextProvider mProvider;
private long baseId = 0;
public MyPagerAdapter(FragmentManager fm, TextProvider provider) {
super(fm);
this.mProvider = provider;
}
#Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return FragmentOne.newInstance(mProvider.getTextForPosition(position));
case 1:
return FragmentTwo.newInstance(mProvider.getTextForPosition(position));
case 2:
return FragmentThree.newInstance(mProvider.getTextForPosition(position));
default: return FragmentOne.newInstance(mProvider.getTextForPosition(position));
}
}
#Override
public int getCount() {
return mProvider.getCount();
}
//this is called when notifyDataSetChanged() is called
#Override
public int getItemPosition(Object object) {
// refresh all fragments when data set changed
return PagerAdapter.POSITION_NONE;
}
#Override
public long getItemId(int position) {
// give an ID different from position when position has been changed
return baseId + position;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
/**
* Notify that the position of a fragment has been changed.
* Create a new ID for each position to force recreation of the fragment
* #param n number of items which have been changed
*/
public void notifyChangeInPosition(int n) {
// shift the ID returned by getItemId outside the range of all previous fragments
baseId += getCount() + n;
}
}
}
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
ViewPager as a circular queue / wrapping
I have three fragment classes in my code.
FirstActivity,SecondActivity,ThirdActivity i want to swipe these three activities.. these three are extend from Fragment class
public class ViewPagerFragmentActivity extends FragmentActivity {
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
super.setContentView(R.layout.viewpager_layout);
initialisePaging();
}
/**
* Initialize the fragments to be paged
*/
List<Fragment> fragments = new Vector<Fragment>();
ViewPager pager;
private void initialisePaging() {
fragments.add(Fragment.instantiate(this, FirstActivity.class.getName()));
fragments.add(Fragment.instantiate(this, SecondActivity.class.getName()));
fragments.add(Fragment.instantiate(this, ThirdActivity.class.getName()));
this.mPagerAdapter = new MyPagerAdapter(super.getSupportFragmentManager(), fragments);
pager = (ViewPager) super.findViewById(R.id.viewpager);
pager.setAdapter(this.mPagerAdapter);
}
}
and here is my FragmentPageAdapter class
public class MyPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments;
public MyPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
System.out.println("position"+position);
return this.fragments.get(position);
}
#Override
public int getCount() {
return this.fragments.size();
}
}
my code is working in this way A<->B<->c
but my requirement is to run like this wayC<->A<->B<->C<-A->
that is in circular fragments are swipable...
Circular ViewPager is possible.
With the help of ViewPager as a circular queue / wrapping this link have coded like this. Hope it helps what you needed.
The CircluarPagerAdapter class:
>
public class CircularPagerAdapter extends PagerAdapter{
private int[] pageIDsArray;
private int count;
public CircularPagerAdapter(final ViewPager pager, int... pageIDs) {
super();
int actualNoOfIDs = pageIDs.length;
count = actualNoOfIDs + 2;
pageIDsArray = new int[count];
for (int i = 0; i < actualNoOfIDs; i++) {
pageIDsArray[i + 1] = pageIDs[i];
}
pageIDsArray[0] = pageIDs[actualNoOfIDs - 1];
pageIDsArray[count - 1] = pageIDs[0];
pager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int position) {
int pageCount = getCount();
if (position == 0){
pager.setCurrentItem(pageCount-2,false);
} else if (position == pageCount-1){
pager.setCurrentItem(1,false);
}
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
});
}
public int getCount() {
return count;
}
public Object instantiateItem(View container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int pageId = pageIDsArray[position];
View view = inflater.inflate(pageId, null);
((ViewPager) container).addView(view, 0);
return view;
}
#Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
#Override
public void finishUpdate(View container) {
// TODO Auto-generated method stub
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
// TODO Auto-generated method stub
}
#Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
#Override
public void startUpdate(View container) {
// TODO Auto-generated method stub
}
}
and this is your main class:
>
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager myPager = (ViewPager) findViewById(R.id.conpageslider);
PagerAdapter adapter = new CircularPagerAdapter(myPager, new int[]{R.layout.first_activity, R.layout.second_activity, R.layout.third_activity});
myPager.setAdapter(adapter);
myPager.setCurrentItem(3);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
You can try something like this :
1) Make getCount() return a huge value ( a number of swipe way higher than what your user might use )
2) Make getItem return something like this.fragments.get(position % fragments.size())
3) Make your pager start somewhere in the middle of the range defined by getCount() ( To allow swiping from A to C at the beginning ), make sure to choose a value which will give you the first fragment % 3
I'm aware this solution seems a bit dirty but I cant find a better one at the moment