Attempting to use a ViewPager with FragmentPagerAdapter with all dynamic GUI elements (i.e. no XML). Yes I have a good reason and not just because I feel like it 🙂 Cannot find anything in the docs that suggests this should not work.
The only difference between working and not working is having the ViewGroup (LinearLayout) and ViewPager defined in XML as opposed to created in the onCreate(). Gives the following error:
java.lang.IllegalArgumentException: No view found for id 0xffffffff for fragment PageFragment{41936480 #0 id=0xffffffff android:switcher:-1:0}
Code:
public class DynoPagerActivity extends FragmentActivity {
private static class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
return PageFragment.newInstance("My Message " + index);
}
@Override
public int getCount() {
return 4;
}
}
private ViewPager mViewPager;
private MyFragmentPagerAdapter mMyFragmentPagerAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
setContentView(ll);
mViewPager = new ViewPager(this);
mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mMyFragmentPagerAdapter);
ll.addView(mViewPager);
//setContentView(ll); tried here as well...
}
}
and:
public class PageFragment extends Fragment {
public static PageFragment newInstance(String title) {
PageFragment pageFragment = new PageFragment();
Bundle bundle = new Bundle();
bundle.putString("title", title);
pageFragment.setArguments(bundle);
return pageFragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// https://android-review.googlesource.com/#/c/31261/ - bug in Support lib
setUserVisibleHint(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
TextView textView = new TextView(container.getContext());
textView.setText(getArguments().getString("title"));
return textView;
}
}
Seems to be an issue with how/when fragments are created, but failing to find the connection…
The ViewPager results in a call to findViewById() for each “page” which tries to get the parent (the ViewPager ID), which always fails for Views that do not have their ID set. When you programmatically create Views, they get an ID of -1, which after browsing the Android platform source code, always returns null/fail for findViewByID().
Adding an ID makes it work, but then you need to manage IDs yourself safely to avoid issues. Add this to code above to make it work in the onCreate() method: