Nouvel Travay Nouvel Travay - 4 months ago 39
Android Question

ViewPager getChildCount returns zero

Does anyone know what might cause

viewPager.getChildCount()
to return zero? I do
findViewById
inside onCreate and there I also do
viewPager.setAdapter
and
tabLayout.setupWithViewPager(viewPager)
. Then inside
onResume
I log the child count and it is zero! Why is that?

Oh, btw, the layout of the ViewPager displays no problem although getChildCount returns 0.

I was under the impression that after I call
viewPager.setAdapter(pagerAdapter)
then the ViewPager and the PagerAdapter would have the same count. But clearly that is not true. So why might this be happening?

UPDATE

You guys raise some very good points. Thank you. The objective is that I want to iterate through all the Fragments in my ViewPager/PagerAdapter. When I use
getChildCount
it is often 0 at unexpected times, but when it is non-zero everything works fine.

for(int i=0; i<viewPager.getChildCount(); i++){
MyFragmentInterface frag = pagerAdapter.getRegisteredFragment(i);
. . .
}


However when I use
viewPager.getAdapter().getCount()
, the value is always the same as
pagerAdapter.getCount()
. But I tend to get NullPointerException because apparently there are no fragments yet.

for(int i=0; i<viewPager.getAdapter().getCount(); i++){
MyFragmentInterface frag = pagerAdapter.getRegisteredFragment(i);
. . .
}


ANSWER

I seem to have fixed it with

for(int i=0; i<pagerAdapter.getCount(); i++){
Fragment frag = pagerAdapter.getItem(i);
. . .
}


No more NullPointerException or size 0

Answer

as far i know ViewPager doesn't implement this method

ViewPager.getChildCount() == ViewGroup.getChildCount()

but as you see:

public abstract class ViewGroup extends View implements ViewParent, ViewManager {


// Number of valid children in the mChildren array, the rest should be null or not
// considered as children
private int mChildrenCount

/**
 * Returns the number of children in the group.
 *
 * @return a positive integer representing the number of children in
 *         the group
 */
public int getChildCount() {
    return mChildrenCount;
}

it returns a mChildren count - count of view group child views**

so in short:

** this mean any child view (that is not the same as object/item of pager)

further see method:

ViewPager.populate(int newCurrentItem)

ViewPager rely on TabLayout - so term item is an "tablayout" tab mapped to view pager adapter item ( could be fragment or view)

as you can add child views to any view - this is not the same as add view pager item to it - you can have something like

        [   T1   ][   T2   ][   T3   ]   <- tab layout 
< -- >  |----------------------------|
pager   |[      pager item         ] |  < - fragment  as view pager item 
(view)  |----------------------------|
< -- >  |[   child view of pager    ]|  < - child view of pager 

Thanks for the education, friend. +1. Do you know how I might solve the problem of iterating through my fragments? – Nouvel Travay

to iterate: ?? mhh let me think ....

maybe get array and iterate ???

1) via loop :)

List<Fragment> fragments = getAdapter().getArrayOfFragments();

for(Fragment fragment : fragments) {

   String title = fragment.getTitle();

}

2) or via iterator :))

List<Fragment> fragments = some implementation of List interface;

Iterator<Fragment> iterator = fragments.iterator();
while(iterator.hasNext()) {

    Fragment fragment = iterator.next();
}

hint for simplest method to get array ?:

 // its only a hint how  - not solution - class need override methods from base class 
class MyAdapter extends BaseAdapter {

   private List<Items> _items;
   public List<Items> getItems() { return _items; }

   MyAdapter(List<Items> items)
     _items = items;
   }

}

// set 
ViewPager.setAdapter(new MyAdapter(listOfItems);
// retrieve 
Adapter  adapter = ViewPager.getAdapter();
if(adapter != null && MyAdapter.class.isAssignableFrom(adapter.getClass())  {
   // magic 
    MyAdapter myadapter = (MyAdapter) adapter; 
    List<Items>  myList = myAdapter.getItems()
}

ps. sorry for typos i dont' know english and i'm bot in real time :D

TODO FOR YOU (FOR TODAY)

  • general read about java language
  • datatypes, classes, interfaces
  • inheritance
  • ps. i forgot about generics

then try write simple class which inherits from other class and implements a mhhh this interface :

/**
* Created by ceph3us on 03.09.2015.
*/
public interface IListAdapter<T> extends ListAdapter{
   void add(T listElement);
   void addAll(List<T> listOfElements);
   void clear();
   void remove(T listElement);
   void notifyDataSetChanged();
   T  getItem(int position);
   List<T> getList();
}

as for your case :)

you have a holder [ in java term definition ] for array of fragments

private Fragment registeredFragments[] = new Fragment[FRAGMENT_TITLES.length];

when u fill this array ??

@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            return DogsFragment.newInstance();   <-   ?? **here** ?? 

i guess no ?? :)

maybe try adjust something like ??

        case 0:
             // if my array contains this type of fragment return it 
             // else  make new one ??? and pack to this array ??? 
            return DogsFragment.newInstance();  

second matter is instantiation of this holder ???

[FRAGMENT_TITLES.length] ?? make array of ?? what size ???

don't use primitive array for this ( think forward when u will add new fragment - as newbie try use list - at this level It will save you time for looking to solutions for many problems ....

i say it one more time READ ABOUT INTERFACES ESPECIAL ABOUT ONE named

 List
Comments