0

I have a GridView to put some images in it. What I would like to do is to have the measurements of the GridView such as width and height so that I know what should be the optimal size of images when they are being showed in the getView() method. I want to show only 8 image per row. So say if a device has bigger screen the images will have bigger size instead of adding more image in the row by setting a fixed size for images.

So in the onCreate() method I initialize my custom Adapter and pass the getWidth and getHeight values into it. But they are always zero.

In the xml layout file, gridview was the only view, then I added it to a linearlayout so maybe it atleast return the width and height of its parent...but that is still zero.

Here is the onCreate method of the Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    if (savedInstanceState == null) {
    }

    int difficulty = getIntent().getExtras()
            .getInt(AppConstants.EXTRAS_GAME_DIFFICULTY_LEVEL, 1);

    LinearLayout lvg = (LinearLayout) findViewById(R.id.linearForGridGame);
    GridView gv = (GridView) findViewById(R.id.gridview);

    gv.setAdapter(new CellAdapter(this, difficulty, lvg.getWidth(), lvg.getHeight()));

    gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            Toast.makeText(GameActivity.this, "" + position, Toast.LENGTH_SHORT).show();
        }
    });
}

Here is the xml layout file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearForGridGame">

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnWidth="128px"
    android:numColumns="auto_fit"
    android:verticalSpacing="0dp"
    android:horizontalSpacing="0dp"
    android:stretchMode="none"
    android:gravity="center"
    android:choiceMode="none"
    android:listSelector="@null"
    android:clickable="true" />

    </LinearLayout>

And here is the cosntructor of the adapter, where I get width and height always 0:

public CellAdapter(Context context, int difficultyLevel,  int parentWidth, int parentHeight)
{
    _context = context;
    _dificultyLevel = difficultyLevel;
    _parentHight = parentHeight;
    _parentWidth = parentWidth;

    Log.d(TAG, "Received difficulty level " + _dificultyLevel); //OK
    Log.d(TAG, "Received parent width " + _parentWidth); //Always 0
    Log.d(TAG, "Received parent height " + _parentHight); //Always 0

    _cellWidth = (_parentWidth / 6); //Width of image to fill 6 per row
    setupGame(_dificultyLevel);
}
Dumbo
  • 13,555
  • 54
  • 184
  • 288

4 Answers4

3

You must wait until the view hierarchy is inflated and measured to know the dimensions. Add something like that in onCreate()

    final ViewTreeObserver vto = lvg.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            if (lvg.getWidth() > 10){ // because it may be called before the view is measured and you will still get 0
                // here you can get the measured dimensions
                ViewTreeObserver obs = pictureImg.getViewTreeObserver(); 
                obs.removeGlobalOnLayoutListener(this); // otherwise you're gonne keep getting called
            }
        }
    });
znat
  • 13,144
  • 17
  • 71
  • 106
1

Try doing lvg.getWidth() in onWindowFocusChanged(boolean ) of the activity

Abhishek Shukla
  • 1,242
  • 8
  • 11
1

I think you have to use LayoutParams, like this:

...
LinearLayout lvg = (LinearLayout) findViewById(R.id.linearForGridGame);
ViewGroup.LayoutParams layoutParams = lvg.getLayoutParams();
GridView gv = (GridView) findViewById(R.id.gridview);
gv.setAdapter(new CellAdapter(this, difficulty, layoutParams.getWidth(), layoutParams.getHeight()));
...

Be sure to import android.view.ViewGroup.LayoutParams .

JJ86
  • 5,055
  • 2
  • 35
  • 64
0

View layout hasn't occurred at onCreate(), you can see for yourself by subclassing View and observing when onLayout() is called.

Lots of info in this question. A ViewTreeObserver.OnGlobalLayoutListener may be more specific to your desire than onWindowFocusChanged(boolean), as you can target a particular view.

Example from this answer:

yourView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            // Ensure you call it only once :
            yourView.getViewTreeObserver().removeGlobalOnLayoutListener(this);

            // Here you can get the size :)
        }
});
Community
  • 1
  • 1
dbro
  • 1,718
  • 1
  • 20
  • 34