1

I'm simulating a tile-based map in Android using android-support-v7-gridlayout.

I implement it smoothly and fast during the debugging times until I test it on a huge data scale. The actual data would be about ~700x400 (row-column) and I just tested it in 400x100 but the application has just crashed and throws an OutOfMemoryException. I then reduced the data until it actually runs on 300x100. It's not lagging or I don't have any CPU performance issue, the only issue is inadequate memory.

This is how I add ImageViews in the grid layout:

public boolean genMap(GridLayout gl) {

    gl.removeAllViews();
    gl.setRowCount( mapFile.getRowCount() );
    gl.setColumnCount( mapFile.getColCount() );

    try {

    for (int row = 0; row < mapFile.getRowCount(); ++row) {
        for (int col = 0; col < mapFile.getColCount(); ++col) {

            com.gridlayout.GridLayout.Spec rowspan = GridLayout.spec(row, 1); 
            com.gridlayout.GridLayout.Spec colspan = GridLayout.spec(col, 1);
            GridLayout.LayoutParams lp = new GridLayout.LayoutParams(rowspan, colspan);
            lp.width = Cell.SIZE;
            lp.height = Cell.SIZE;

            Cell cell = genNewCell( ctx.getApplicationContext(), row, col );

            gl.addView( cell, lp );
        }
    }

        return true;

    } catch (Exception e) {
        return false;
    }

}

Where Cell is a subclass of ImageView

Perhaps, I also think of lazyload pattern where the only visible view will be loaded out but, I'd like to know if GridLayout already implements it.

Update 1

GridView seems is not what I'm looking for. It cannot scroll diagonally plus it can't have a scrollbar both horizontal and vertical at the same time. What I want to achieve is something like GoogleMaps' ViewGroup layout wherein you can scroll in a 2 dimensional way and each cells memory allocation/deallocation are managed automatically. I think GridLayout is my last hope as I cannot see any ViewGroup w/c implements what I wanted to.

So my question is, how can I able to recycle those cells that aren't visible yet in the screen while keeping layout as they are present?

Community
  • 1
  • 1
mr5
  • 3,438
  • 3
  • 40
  • 57
  • 1
    How many "cells" are visible on the screen at one time? If very few of them, then you probably should implement a custom Adapter which only loads the images needed at any given time. – Code-Apprentice Aug 09 '14 at 01:22
  • @Code-Apprentice Depends of the zoom factor. Maybe about **16x8**. Ah, I though it's only applicable to listview? – mr5 Aug 09 '14 at 01:27
  • @Code-Apprentice Is there a way to pretend that I added some children in GridLayout just to properly align the cells inside the grid. because most of the cells are not used? – mr5 Aug 09 '14 at 01:31
  • [GridLayout doesn't have any adapters](http://stackoverflow.com/questions/11309597/how-gridlayout-items-come-from-the-adapterlist-image-in-android-app) – mr5 Aug 09 '14 at 01:53
  • You need to change your title then because it says you are using `GridView`. – Code-Apprentice Aug 09 '14 at 01:54
  • @Code-Apprentice Ooops sorry. My bad – mr5 Aug 09 '14 at 01:55

2 Answers2

2

GridLayout does not do any dynamic memory management and simply creates everything regardless if it is actually on the screen or not. You need to use something like the GridView. With a GridView, you could theoretically support an infinite amount of items. Now because you want to do horizontal scrolling you will need a custom GridView implementation. Something like https://github.com/jess-anders/two-way-gridview.

If you take away nothing from my post, DO NOT DO THIS WITH A GRID LAYOUT. You could test all day but every phones different and some have more or less memory.

EDIT 1:

This also might be easier with the release of the new RecyclerView in android L, but I haven’t look into it that much.

David Stocking
  • 1,200
  • 15
  • 26
  • But it does not allow me to put this `app:scrollDirectionPortrait="vertical|horizontal"` and `app:scrollDirectionLandscape="horizontal|vertical"` . I have tested it but I only got one working scrollbar at a time. – mr5 Aug 20 '14 at 08:53
  • Hmmm How large would this be horizontally? You could just eat the extra columns off the screen and wrap a grid view with a horizontal scroller like http://stackoverflow.com/questions/16299633/android-gridview-with-both-horizontal-and-vertical-scrolbars-at-the-same-time. You would have to be able to specify the width I think. Otherwise, it will just be unbounded. I'm very confused how this control doesn't seem to exist (in a library). – David Stocking Aug 20 '14 at 13:56
  • Even if I set the `colCount` of that `two-way-gridview` it does not allow to expand beyond the screen boundaries, instead, it compresses each cells until it fits. Each cell size will be ~32x32 – mr5 Aug 20 '14 at 15:09
  • What I wanted to achieve is something like a `GoogleMap`'s `ViewGroup` layout. – mr5 Aug 20 '14 at 15:14
  • I was saying that you would have a horizontal scroll the size that you want itemSize * numberOfItemsDesired. that way it wouldnt bunch them all up on the screen. However, I hate to say it, but OWADVL's idea of using a webview might actually be way easier. You should be able to pull this off in a highly modified gridview but frankly that would be a lot of work. Although, if you did you could open source it for the next guy. – David Stocking Aug 20 '14 at 15:25
  • OWADVL's suggestion don't provide a strong example. I made a sample of what I wanted to achieve [here](http://editor.mr5proj.hostoi.com/mtl_map_view.php). I have tried to load it through Android's default browser in an emulator and it just hang up and does not continue to load. If you're using Firefox, don't open that page as it is very very slow there. – mr5 Aug 22 '14 at 07:31
1

In my opinion you should use Webview for this. Has scroll, zoom, memory issues already addressed.

OWADVL
  • 10,704
  • 7
  • 55
  • 67