Search code examples
androidandroid-adapterview

AdapterView onLayout infinite loop


I am trying to make my own list and therefore I am extending the AdapterView class. I have overridden the onLayout method to add children, measure them and call the layout method. my problem is that the onLayout method gets called infinitely and items are duplicated on each call. I have looked on the Internet and verified that my children are not changing (I have made each child returns an empty view with no dynamic content). here is my code:

protected void onLayout(final boolean changed, final int left, final int top, final int right,
            final int bottom)
    {
        super.onLayout(changed, left, top, right, bottom);
        // If we don't have an adapter yet, do nothing and return
        if(mAdapter == null)
        {
            return;
        }
        fillList();
        positionItems();
    }

fillList():

private void fillList()
    {
        int position = 0;
        if(mCurrentList*mNumberItemsPerList > mAdapter.getCount() )
        {
            mCurrentList= 0;
            return ;
        }
        if(mCurrentList < 0)
        {
            double lastList = (double)(mAdapter.getCount()/mNumberItemsPerList);
            mCurrentList= (int) Math.ceil(lastList);
            return ;
        }
        //this.removeAllViewsInLayout();
            while( position+mCurrentList*mNumberItemsPerList < mAdapter.getCount() )
            {


                // Child view
                final View child = mAdapter.getView(position+mCurrentList*mNumberItemsPerList, null, this);
                // Add the child and measure its dimensions to calculate the remaining space
                addAndMeasureChild(child);
                position++;
            }

    }

addAndMeasureChild():

private void addAndMeasureChild(View child)
    {
        LayoutParams params = child.getLayoutParams();
        if(params == null)
        {
            params = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        }
        //child.setLayoutParams(params);
        addViewInLayout(child,-1, params);
        // measure the dimensions
        child.measure(MeasureSpec.EXACTLY | 250,MeasureSpec.EXACTLY | 250);


    }

positionItems():

private void positionItems()
    {
        int left = 0;
        int middleItem = mNumberItemsPerList / 2;
        for(int index =0; index < getChildCount(); index++)
        {
            View child = getChildAt(index);
            int width = child.getMeasuredWidth();
            int height = child.getMeasuredHeight();
            int bottom= (getHeight()-height)/2;
            if(index < middleItem)
            {
                child.layout(left+15, 70+(middleItem-index)*30, left+width, 70+(middleItem-index)*30+height);
            }
            if(index == middleItem)
            {
                child.layout(left+15, 70, left+width, 70+height);
            }
            if(index > middleItem)
            {
                int diff = index -middleItem;
                child.layout(left+15, 70+(middleItem-(index - (middleItem*diff)))*30, left+width, 70+(middleItem-(index - (middleItem*diff)))*30+height);
            }
            left += width;
        }

    }

and this is the getView of my child:

public View getView(final int position, final View convertView, final ViewGroup parent)
    {
        View view = convertView;
        if (view == null) {
            view = LayoutInflater.from(getContext()).inflate(R.layout.cat_item_layout, null);
        }
        return view;
    }

Solution

  • I've figured out what was causing the infinite call to onLayout. on my main layout I have added a clock with this custom view inside a relative layout. I don't know why but the clock (which is updated every second) causes my view to call onLayout again.