I dont know how to explain this, so i uploaded a video in Youtube. Everything works fine when i am adding pages. Also removing page works if i start at the end of the list and move progressively to the first page, but if i remove somewhere between 0-end and after that i add page, i am getting a blank page. Fragment is created but view is not.
Is there something wrong with my code? Yes, i have seen this question, returning POSITION_NONE
is not an option, because application i am working on downloads content from web and displays it in listview, so recreating fragments everytime when user removes page is not very effective.
Button click: Result:
Add page [Fragment 1]
Add page [Fragment 1][Fragment 2]
Add page [Fragment 1][Fragment 2][Fragment 3]
remove page(position2) [Fragment 1][Fragment 2]
remove page(position1) [Fragment 1]
Add page [Fragment 1][Fragment 2]
remove page(position1) [Fragment 1]
remove page(position0) ---No pages---
Add page [Fragment 0]
Add page [Fragment 0][Fragment 1]
Add page [Fragment 0][Fragment 1][Fragment 2]
add page [Fragment 0][Fragment 1][Fragment 2][fragment 3]
remove page(position2) [Fragment 0][Fragment 1][Fragment 3]
add page [Fragment 0][Fragment 1][Fragment 3][Blank page]
remove page(position0) [Fragment 1][Fragment 3][Fragment 3][Blank page]
MainActivity.class
public class MainActivity extends FragmentActivity {
private static final String TAG = "MainActivity";
private ViewPager mViewpager;
private ArrayList<Fragment> fragmentslist;
private SectionsPagerAdapter mPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentslist = new ArrayList<Fragment>();
mPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewpager = (ViewPager)findViewById(R.id.pager);
mViewpager.setAdapter(mPagerAdapter);
mViewpager.setOffscreenPageLimit(4);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected (MenuItem item){
switch(item.getItemId()){
case R.id.menu_add_page:
Bundle bundle = new Bundle();
bundle.putInt("Position", fragmentslist.size());
fragment frag = new fragment();
frag.setArguments(bundle);
fragmentslist.add(frag);
mPagerAdapter.notifyDataSetChanged();
mViewpager.setCurrentItem(fragmentslist.indexOf(frag));
Log.i(TAG, "Add fragment");
break;
case R.id.menu_remove_page:
if(fragmentslist.size() > 0){
mPagerAdapter.removeItem(mViewpager.getCurrentItem());
}
Log.i(TAG, "Removing page " + mViewpager.getCurrentItem());
break;
}
return true;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragmentslist.get(position);
}
@Override
public int getCount() {
return fragmentslist.size();
}
@Override
public int getItemPosition(Object object){
int index = fragmentslist.indexOf(object);
if(index != -1){
Log.i(TAG, "Position: " + index);
return index;
}
else{
Log.i(TAG, "POSITION_NONE");
return POSITION_NONE;
}
}
public void removeItem(int position){
Fragment fragment = (Fragment)fragmentslist.get(position);
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
fragmentslist.remove(position);
notifyDataSetChanged();
}
}
public static class fragment extends Fragment{
private String colors[] = {"#FF0000", "#00FF00", "#FFFF00", "#FF6600"};
public View onCreateView(LayoutInflater inflater, ViewGroup root, Bundle savedInstanceState){
View mView = inflater.inflate(R.layout.fragment_layout, null);
RelativeLayout layout = (RelativeLayout)mView.findViewById(R.id.relativelayout);
TextView text = (TextView)mView.findViewById(R.id.textView1);
int position = this.getArguments().getInt("Position");
text.setText("Page: " + position);
layout.setBackgroundColor(Color.parseColor(colors[position]));
Log.i("fragment", "Page: " + position + " view created");
return mView;
}
}
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
fragment_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/relativelayout">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Large Text"
android:textSize="40sp" />
Try doing mViewpager.setAdapter(null) before adding or removing items from the list. Afterwards, set the adapter back to mPagerAdapter. It appears that ViewPager was not designed to handle insertions or deletions except from the end of the list.
I have working sample code that might be useful to you. Take a look at ViewPager sample.