0

For my app, I'm using a library which implements it's own ScrollView throughout the entire layout.

My issue is that I need to have a GridView in a fragment but doing so causes most of it to be chopped off like so: Why You No Work?! (Ignore the slider on top)

I ended up creating my own GridView that expands according to the number of rows but that disables view recycling. Since we use a lot of images, we end up getting all sorts of OutOfMemoryExceptions if we load more than 10. We also can't use animations you see while scrolling and stuff.

Here is the code for my custom GridView:

public class PkGridView extends GridView implements OnTouchListener, OnScrollListener
{

private int listViewTouchAction;
private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 50;

public PkGridView(Context context, AttributeSet attrs)
{
    super(context, attrs);
    listViewTouchAction = -1;
    setOnScrollListener(this);
    setOnTouchListener(this);
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
    if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE)
    {
        if (listViewTouchAction == MotionEvent.ACTION_MOVE)
        {
            scrollBy(0, -1);
        }
    }
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int newHeight = 0;
    final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    if (heightMode != MeasureSpec.EXACTLY)
    {
        ListAdapter listAdapter = getAdapter();
        if (listAdapter != null && !listAdapter.isEmpty())
        {
            int listPosition = 0;
            for (listPosition = 0; listPosition < listAdapter.getCount() && listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++)
            {
                View listItem = listAdapter.getView(listPosition, null, this);
                // now it will not throw a NPE if listItem is a ViewGroup instance
                if (listItem instanceof ViewGroup)
                {
                    listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                }
                listItem.measure(widthMeasureSpec, heightMeasureSpec);
                newHeight += listItem.getMeasuredHeight();
            }
            //newHeight += 5 * listPosition;
        }
        if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize))
        {
            if (newHeight > heightSize)
            {
                newHeight = heightSize;
            }
        }
    }
    else
    {
        newHeight = getMeasuredHeight();
    }
    setMeasuredDimension(getMeasuredWidth(), newHeight);
}

@Override
public boolean onTouch(View v, MotionEvent event)
{
    if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE)
    {
        if (listViewTouchAction == MotionEvent.ACTION_MOVE)
        {
            scrollBy(0, 1);
        }
    }
    return false;
}
}

Is there any way I can have my items recycle again while still being able to see the whole GridView without expanding?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Pkmmte
  • 2,822
  • 1
  • 31
  • 41

1 Answers1

1

You should definitely use your own adapter implementation. There's a nice training on Android developers that offers a full solution for showing bitmaps in a ListView/GridView and does all the asynchronous image loading and view recycling:

http://developer.android.com/training/displaying-bitmaps/process-bitmap.html

In your custom adapter in getView(...) you only need to use the ViewHolder pattern accordingly and then call loadBitmap(...) and you're done. See this tutorial for creating a custom adapter:

http://www.vogella.com/articles/AndroidListView/article.html#adapterown_custom

For custom views maybe this one is interesting too:

http://developer.android.com/training/custom-views/index.html

ramdroid
  • 6,738
  • 1
  • 16
  • 14
  • Actually, I already am using my own adapter and the Picasso library I'm using for loading images is as efficient as can be. Oh and I'm also already using the ViewHolder pattern. The problem here is that the FadingActionBar library I'm using requires the GridView/ListView to have a Header. I'm currently trying out this [HeaderGridView](https://github.com/maurycyw/HeaderGridView) library to solve the problem but still no luck. – Pkmmte Jul 10 '13 at 00:19