Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically load next fragment with ViewPager

Tags:

android

I'm creating a demo app with the new android compatibility library. I want to show two listfragments with ViewPager. The first shows the root categories and the second shows the subcategories. After somebody clicks on root category the viewpager move to the subcategory, but it won't work, because always show the root category elements. I spend few minutes with debug and I'm realised the ViewPager creates the second fragment after the first one.(I think the pager cache the next view or fragment.)

Is it possible to load the second fragment after onListItemClick?

Here is the code:

public class ViewPagerDemoActivity extends FragmentActivity implements OnBookSelectedListener {

private static int mSelectedCategoryId;
private MyAdapter mMyAdapter;
private ViewPager mPager;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    setupPager();
}

private void setupPager() {
    mPager = (ViewPager) findViewById(R.id.pager);
    mMyAdapter = new MyAdapter(getSupportFragmentManager());
    mPager.setAdapter(mMyAdapter);
}

@Override
public void onBookSelected(int categoryId) {
    mSelectedCategoryId = categoryId;
    if (mSelectedCategoryId == 0) {
        mPager.setCurrentItem(1);
    } else {
        mPager.setCurrentItem(0);
    }
}

public static class MyAdapter extends FragmentPagerAdapter {
    private static final int NUMBER_OF_FRAGMENTS = 2;

    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return BookListFragment.newInstance(mSelectedCategoryId);
    }

    @Override
    public int getCount() {
        return NUMBER_OF_FRAGMENTS;
    }
}

}

public class BookListFragment extends ListFragment {
private static final String ARGUMENT_KEY = "categoryId";
private OnBookSelectedListener mOnBookSelectedListener;
private int mCategoryId;

public static BookListFragment newInstance(int categoryId) {
    BookListFragment bookListFragment = new BookListFragment();
    Bundle argument = new Bundle();
    argument.putInt(ARGUMENT_KEY, categoryId);
    bookListFragment.setArguments(argument);
    return bookListFragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mCategoryId = getArguments() != null ? getArguments().getInt(ARGUMENT_KEY) : 0;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Books.getBooks(mCategoryId)));
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.pager_list, container, false);
    View tv = v.findViewById(R.id.text);
    ((TextView) tv).setText("Category :" + mCategoryId);
    return v;
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    if (mCategoryId == 0) {
        mOnBookSelectedListener.onBookSelected(1);
    } else {
        mOnBookSelectedListener.onBookSelected(0);
    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mOnBookSelectedListener = (OnBookSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + "Must Implement OnBookSelectedListener.");
    }
}

public interface OnBookSelectedListener {
    public void onBookSelected(int categoryId);
}

}

public class Books {
private static final String[] fruits = new String[] { "Apple", "Banana", "Orange" };
private static final String[] category = new String[] { "Lorem", "Dolor", "Ipsum" };

public static String[] getBooks(int categoryId) {
    return categoryId == 0 ? category : fruits;
}

}

like image 944
kameny Avatar asked Aug 01 '11 19:08

kameny


1 Answers

I solved the problem, I need to add List to the adapter and after that the getItem don't create new instance, only gets the item from the list.

This is the new code.

public class ViewPagerDemoActivity extends FragmentActivity implements OnBookSelectedListener {

private MyAdapter mMyAdapter;
private ViewPager mPager;
private BookOnPageChangeListener mBookOnPageChangeListener;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    setupPager();
}

private void setupPager() {
    mPager = (ViewPager) findViewById(R.id.pager);
    mMyAdapter = new MyAdapter(getSupportFragmentManager());
    mPager.setAdapter(mMyAdapter);
    mBookOnPageChangeListener = new BookOnPageChangeListener();
    mPager.setOnPageChangeListener(mBookOnPageChangeListener);
}

@Override
public void onBookSelected(int categoryId) {
    mMyAdapter.addPage(categoryId);
    mPager.setCurrentItem(mBookOnPageChangeListener.getCurrentPage() + 1);
}

public static class MyAdapter extends FragmentPagerAdapter {
    private List<Fragment> pages;

    public MyAdapter(FragmentManager fm) {
        super(fm);
        initPages();
    }

    /**
     * Create the list and add the first ListFragment to the ViewPager.
     */
    private void initPages() {
        pages = new ArrayList<Fragment>();
        addPage(0);
    }

    /**
     * Add new BookListFragment to the ViewPager.
     * 
     * @param categoryId
     *            - the category id
     */
    public void addPage(int categoryId) {
        pages.add(BookListFragment.newInstance(categoryId));
    }

    @Override
    public Fragment getItem(int position) {
        return pages.get(position);
    }

    @Override
    public int getCount() {
        return pages.size();
    }
}

/**
 * Get the current view position from the ViewPager.
 */
public static class BookOnPageChangeListener extends ViewPager.SimpleOnPageChangeListener {
    private int currentPage;

    @Override
    public void onPageSelected(int position) {
        // current page from the actual position
        currentPage = position;
    }

    public int getCurrentPage() {
        return currentPage;
    }
}

}

like image 98
kameny Avatar answered Sep 29 '22 10:09

kameny