how to set image width height based on screen size in gridview
Asked Answered
S

3

13

I want to show 3x3 sized gridview. I want to set the height and width based on device size. I am taking reference from this link.

MainActivity-

public class MainActivity extends Activity {

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

      GridView gridview = (GridView) findViewById(R.id.gridview);
      gridview.setAdapter(new ImageAdapter(this));
   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
   }

}

activity_main-

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
   android:id="@+id/gridview"
   android:layout_width="fill_parent" 
   android:layout_height="fill_parent"
   android:columnWidth="90dp"
   android:numColumns="auto_fit"
   android:verticalSpacing="10dp"
   android:horizontalSpacing="10dp"
   android:stretchMode="columnWidth"
   android:gravity="center"
/>

Edit-

Like first getting screen height and width then each item height and width 1/3 of the value of screen height and width I am getting.

Shiism answered 8/3, 2014 at 10:0 Comment(7)
Here your columns are fixed 3Runnels
I know but images in grid view on some screens take only above half screen.Shiism
because you set android:columnWidth="90dp", you need handle that on your code, as i said on before questionRosaliarosalie
Yes but I want to make changes in my code. I check my code on tablet. Gridview take only half screen.Shiism
set width on your code side, get screen width and set width/3 to your gridViewRosaliarosalie
How to get screen width and where to set?Shiism
Do you want display fixed 3x3 grid (9 items constant) or a grid with 3x3 format (scrollable) with undetermined items?Ollie
O
9

Do not use screen size, in a multi-windows context this method is invalid. If your grid is a 3x3 items size fixed, so use custom layout ViewGroup like this: (and set RelativeLayout items content)

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle state) {
        setContentView(new ViewGroup(this) {
            private RelativeLayout[] items = new RelativeLayout[9];
            private int width, height, itemWidth, itemHeight;
            {
                Random r = new Random();
                for (int i = 0; i < 9; i++) {
                    items[i] = new RelativeLayout(getContext());
                    float[] hsv = new float[] {360 * r.nextFloat(), .50f, .75f};
                    items[i].setBackgroundColor(Color.HSVToColor(hsv));
                    addView(items[i]);

                    // UPDATE ////////////////////////////////////
                    ImageView image = new ImageView(getContext());
                    switch (i) {
                    case 0: // top left
                    case 1: // top center
                    case 2: // top right
                    case 3: // center left
                    case 4: // center center
                    case 5: // center right
                    case 6: // bottom left
                    case 7: // bottom center
                    case 8: // bottom right
                        image.setImageResource(R.drawable.ic_launcher);
                        break;
                    }
                    image.setScaleType(ScaleType.FIT_XY);
                    image.setLayoutParams(new RelativeLayout.LayoutParams(
                            RelativeLayout.LayoutParams.MATCH_PARENT,
                            RelativeLayout.LayoutParams.MATCH_PARENT
                    ));
                    items[i].addView(image);
                    //////////////////////////////////////////////
                }
            }
            @Override
            protected void onMeasure(int wMS, int hMS) {
                width = MeasureSpec.getSize(wMS);
                height = MeasureSpec.getSize(hMS);
                itemWidth = width / 3;
                itemHeight = height / 3;
                wMS = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
                hMS = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
                measureChildren(wMS, hMS);
                setMeasuredDimension(width, height);
            }
            @Override
            protected void onLayout(boolean changed, int l, int t, int r, int b) {
                for (int i = 0; i < 9; i++) {
                    l = itemWidth * (i % 3);
                    t = itemHeight * (i / 3);
                    r = l + itemWidth;
                    b = t + itemHeight;
                    items[i].layout(l, t, r, b);
                }
            }
        });
        super.onCreate(state);
    }

}

EDIT : see my update in code, you have simply to add your images to the items containers. With this method, no XML layout file needed because you manage content and size yourself.

Result : result


EDIT : the minimalist way:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle state) {
        setContentView(new ViewGroup(this) {
            private static final int SIZE_X = 3;
            private static final int SIZE_Y = 3;
            private ImageView[] items = new ImageView[SIZE_X * SIZE_Y];
            private int itemWidth, itemHeight;
            {
                setBackgroundColor(Color.DKGRAY);
                for (int i = 0; i < items.length; i++) {
                    items[i] = new ImageView(getContext());
                    items[i].setScaleType(ScaleType.CENTER);
                    items[i].setImageResource(R.drawable.ic_launcher);
                    addView(items[i]);
                }
            }
            @Override
            protected void onMeasure(int wMS, int hMS) {
                int width = MeasureSpec.getSize(wMS);
                int height = MeasureSpec.getSize(hMS);
                itemWidth = width / SIZE_X;
                itemHeight = height / SIZE_Y;
                wMS = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
                hMS = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
                measureChildren(wMS, hMS);
                setMeasuredDimension(width, height);
            }
            @Override
            protected void onLayout(boolean changed, int l, int t, int r, int b) {
                for (int i = 0; i < items.length; i++) {
                    l = itemWidth * (i % SIZE_X);
                    t = itemHeight * (i / SIZE_X);
                    r = l + itemWidth;
                    b = t + itemHeight;
                    items[i].layout(l, t, r, b);
                }
            }
        });
        super.onCreate(state);
    }

}

Result :

enter image description here


@ Kanwaljit Singh:

In MainActivity items creation loop:

final int id = i;
items[i].setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        startActivity(new Intent(getContext(), NextActivity.class).putExtra("id", id));
    }
});

In NextActivity:

int id = getIntent().getIntExtra("id", -1);
Ollie answered 14/3, 2014 at 19:23 Comment(10)
Just copy/paste this code in your project and adapt it with your needsOllie
You completely changed my code. Please help me with one thing if I have to send value of image to next activity where I can do this. For example on first image click send 0 to next activity.Tjaden
@Ollie its working. One last question how to set vertical and horizontal padding in rows and columns?Shiism
@JohnR if it's working...you can approve alex's answer right? :-)Aloysius
@Aloysius ofcourse. But after getting my last problem's answer.Shiism
items[i].setPadding(30, 30, 30, 30); will set a 30px padding around your imagesOllie
Can you tell me parameters in setPadding for what side i.e first parameter for top or right?Shiism
Please read documentation developer.android.com/reference/android/view/…Ollie
@Ollie Can you explain why you disagree using screen size ?Guajardo
@serj: Screen is not the direct parent container of the GridView. So if you calculate his size from the Screen size, if one of intermediate parent ViewGroup has not the same size (ex: Window can be smaller than Screen), you will obtain bad results. Always use the direct parent container to compute a View formatting.Ollie
P
4

You can get the screen dimensions like:

final DisplayMetrics displayMetrics=getResources().getDisplayMetrics();
final float screenWidthInDp=displayMetrics.widthPixels;
Log.WTF("ScreenWidth", "width: "+screenWidthInDp+", menuWidth: "+screenWidthInDp/3);

And for the gridview, I would suggest you to take a look at this awesome library called Staggered Grid View. And their sample here.

Polo answered 8/3, 2014 at 10:7 Comment(2)
I dont want to use staggered grid view. If I use above coding suggested by you what changes I have to made in above code?Shiism
No this is not the case. I tried this code on emulator.Shiism
P
2

I use the following approach when I have to resize my Activitys, I assume the same is valid for your case:

// I'm storing the size of the window in the display var, so I can then play around
final Display display = getWindowManager().getDefaultDisplay();
final Point size = new Point();
display.getSize(size);

// In your case, you'll probably need something like this:
GridView gv = (GridView) findViewById(R.id.gridview);
gv.setWidth((int) size.x * 0.75);    // Whis would resize the grid width to the 75%
gv.setHeight((int) size.y * 0.5);    // Same with the height, but to the 50%
Prytaneum answered 14/3, 2014 at 15:25 Comment(1)
I removed the useless line for you. In your case, just put these 6 lines in your code prior to populating your GridView, but where you can find it by their id (I mean, once the layout has been rendered), just changing the % to what you need to resize. It should do the trick as it is right now.Prytaneum

© 2022 - 2024 — McMap. All rights reserved.