I have a FragmentPagerAdapter
that works as it should but what I am wondering is that if the FragmentPagerAdapter
is on the last view how can I have it loop back to the first view and continue on like normal
this is my example code that I am using
public class FragmentPager extends FragmentActivity {
MyAdapter mAdapter;
ViewPager mPager;
static final int NUM_ITEMS = 5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
}
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return MyFragment.newInstance(position);
}
}
public static class MyFragment extends ListFragment{
int mNum;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
static MyFragment newInstance(int num) {
MyFragment f = new MyFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, new String[] {"test1","test2","test3","test4","Test5"}));
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
}
basically when it gets to the end how can I have it show the first fragment as it would go to any other fragment?
ie. A->B
,
B->C
, C->A
and backwards A->C
, C->B
, B->A
Here is my solution I have "n" number of screens (5 in this case) and since I want to go back to the first one at the end of the list I "add another screen" which is just an exact copy of the last screen and do this for the reverse direction too. Basically I now have "n" screens +2 (or 7 now in this case). Screens are set up like this copy of C
,A
,B
,C
,copy of A
then I set a gesture listener to watch for swipes on certain pages.
If at the end of the list ("copy of A") and I detect a swipe to the left > a certain number of pixels
I move to page A
and continue to swipe back in the normal page rotation.
the same goes for swiping in the opposite direction.
Issues
It does get a little slow when moving from one of the end pages to simulate the looping because the ViewPager
loads the pages before and after the page you are currently on but since you are at the end or beginning of the page list it does not load the next page like it normally would because there technically is no next page. This really only happens if you have complex custom views for each list row
You cannot use this with animations for page scrolling because it wont look seamless and will animate when you are moving from a copied page to the actual page i.e. copy of A to A.
Also it does seem to get stuck at the end of the pages sometimes and I dont know why
this is my full demo application based off the viewpager example on the android developer site
public class FragmentPager extends FragmentActivity{
MyAdapter mAdapter;
public static ViewPager mPager;
static int currentPage = 1;
static final int NUM_ITEMS = 7;
public static View vContainer;
float dxInitial=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(1,false);
mPager.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
dxInitial=event.getX();
Log.d("INITIAL X", String.valueOf(dxInitial));
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
if(event.getX() - dxInitial > 100 && currentPage==1){
mPager.setCurrentItem(6,false);
}else if(dxInitial - event.getX() > 100 && currentPage==5){
mPager.setCurrentItem(0,false);
}else if(dxInitial - event.getX() > 50 && currentPage==6){
mPager.setCurrentItem(1,false);
}else if(event.getX() - dxInitial > 50 && currentPage==0){
mPager.setCurrentItem(5,false);
}
}
/*if(Math.abs(dx) > Math.abs(dy)) {
if(dx>75){ directiion = "right";
}else if{
direction = "left";
}
} else {
if(dy>0) direction = "down";
else direction = "up";
}*/
return false;
}
});
mPager.setOnPageChangeListener(new OnPageChangeListener(){
@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
if(state == ViewPager.SCROLL_STATE_IDLE){
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int arg0) {
currentPage=arg0;
}
});
}
public static class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return MyFragment.newInstance(position);
}
@Override
public Object instantiateItem(View container, int position) {
vContainer=container;
return super.instantiateItem(container, position);
}
}
public static class MyFragment extends ListFragment{
int mNum;
/**
* Create a new instance of CountingFragment, providing "num"
* as an argument.
*/
static MyFragment newInstance(int num) {
MyFragment f = new MyFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
if(mNum == 6){
mNum=1;
}else if(mNum==7){
mNum=5;
}else if(mNum==0){
mNum=5;
}
((TextView)tv).setText("Fragment #" + mNum);
return v;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, new String[] {"test1","test2","test3","test4","Test5"}));
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
}
}
}