2

My question is similar to How to know GridView numColumns before setting up adapter in case of auto_fit? but it's not answered yet so trying out my luck and I have researched little bit.

Brief background.....I am using gridview layout in a fragment, below is the xml :

 <GridView
        android:id="@android:id/someID"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:columnWidth="@dimen/grid_width"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:visibility="visible" >
    </GridView>

Now the goal is simple to get number of columns, i.e. a call getNumColumns() of gridview object(http://developer.android.com/reference/android/widget/GridView.html#attr_android:numColumns), but as per doc it can return me -1(AUTO_FIT) if view has not been laid out which I don't want.

So to avoid -1 condition and ensure gridview is actually laid I did something like this How can you tell when a layout has been drawn? in fragment's onActivtyCreated() callback.

But here it gets interesting , I added few logs and observed that sometime I get proper value but sometime I get -1. I did little bit of more digging and checked gridview's actual code where is sets up number of columns.

   //declaration of vars
    public static final int AUTO_FIT = -1;
    private int mNumColumns = AUTO_FIT;

    private boolean determineColumns(int availableSpace) {
        final int requestedHorizontalSpacing = mRequestedHorizontalSpacing;
        final int stretchMode = mStretchMode;
        final int requestedColumnWidth = mRequestedColumnWidth;
        boolean didNotInitiallyFit = false;

        if (mRequestedNumColumns == AUTO_FIT) {
            if (requestedColumnWidth > 0) {
                // Client told us to pick the number of columns
                mNumColumns = (availableSpace + requestedHorizontalSpacing) /(requestedColumnWidth + requestedHorizontalSpacing);
                } else {
                    // Just make up a number if we don't have enough info
                    mNumColumns = 2;
                }
            } else {
                // We picked the columns
                mNumColumns = mRequestedNumColumns;
            }

            if (mNumColumns <= 0) {
                mNumColumns = 1;
            }

This snippet only shows where mNumColumns value is set, for entire code you can see http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.2_r1/android/widget/GridView.java , now theoretically mNumColumns can never get -1 except when view is not laid out.

So what should I do for this scenario , any suggestions ? I can either add delay (worse case design) or I can add a check for -1 and return 1 (using idea of above code snippet) which may cause race condition. Probably I am missing something or my assumptions are wrong.

Community
  • 1
  • 1
avenger
  • 156
  • 1
  • 10
  • I am also experiencing the same problem. Have you came up with a solution? – box Sep 30 '15 at 06:29
  • I used same way android is doing (check for -1 and return 1) when I am sure views are laid out. Till now I have faced no issues with this hack – avenger Oct 03 '15 at 06:34
  • Ok I found another solution. I went with my own dynamic scaling algorithm. – box Oct 05 '15 at 08:58

1 Answers1

2
gridview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            gridview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
           int num = gridview.getNumColumns();
           // do what u need here

        }
    });
elham shahidi
  • 771
  • 6
  • 11